[Android] webview download file async À¥ºä¿¡¼ ÆÄÀÏ ´Ù¿î·Îµå (include sdk23 android 6.0 marshmallow)
±âº» webview¿¡¼´Â ´Ù¿î·Îµå ¸µÅ©¸¦ ´·¯µµ ¾Æ¹« ¹ÝÀÀµµ ¾ø½À´Ï´Ù. µû·Î ±¸ÇöÀ» ÇØÁà¾ß µË´Ï´Ù.
1. permission
ÆÄÀÏ´Ù¿î·Îµå¸¦ À§Çؼ´Â WRITE_EXTERNAL_STORAGE permissionÀÌ ÇÊ¿äÇÕ´Ï´Ù.
targetSdkVersion < 23 Àΰæ¿ì´Â ¾Æ·¡¿Í °°ÀÌ Ã³¸®ÇÏ¸é µË´Ï´Ù.
androidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
android 6 (sdk23)ºÎÅÍ´Â permission Á¤Ã¥ÀÌ º¯°æ µÇ¾î¼ À§ÀÇ ¼³Á¤¸¸ ÇÒ °æ¿ì
java.lang.SecurityException: No permission to write to /storage/emulated/0/Download/foo.jpg: Neither user 10386 nor current process has android.permission.WRITE_EXTERNAL_STORAGE.
¿¡·¯°¡ ¹ß»ýÇÏ°í ¾ÛÀÌ Á×½À´Ï´Ù.
±ÇÇÑ ÁÖ´Â ¹æ¹ýÀº ¾Æ·¡¿¡¼ ¼³¸íÇϵµ·Ï ÇÏ°Ú½À´Ï´Ù.
2. DownloadListener ±¸Çö
public class MainActivity extends Activity {
private WebView mWebView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.activity_trandent_webview);
.
.
.
.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
mWebView.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
try {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setMimeType(mimeType);
request.addRequestHeader("User-Agent", userAgent);
request.setDescription("Downloading file");
String fileName = contentDisposition.replace("inline; filename=", "");
fileName = fileName.replaceAll("\"", "");
request.setTitle(fileName);
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
dm.enqueue(request);
Toast.makeText(getApplicationContext(), "Downloading File", Toast.LENGTH_LONG).show();
} catch (Exception e) {
if (ContextCompat.checkSelfPermission(MainActivity.this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(getBaseContext(), "÷ºÎÆÄÀÏ ´Ù¿î·Îµå¸¦ À§ÇØ\nµ¿ÀÇ°¡ ÇÊ¿äÇÕ´Ï´Ù.", Toast.LENGTH_LONG).show();
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
110);
} else {
Toast.makeText(getBaseContext(), "÷ºÎÆÄÀÏ ´Ù¿î·Îµå¸¦ À§ÇØ\nµ¿ÀÇ°¡ ÇÊ¿äÇÕ´Ï´Ù.", Toast.LENGTH_LONG).show();
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
110);
}
}
}
}
});
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
DownloadListener¿¡ onDownloadStart¸¦ override ÇÕ´Ï´Ù.
content-disposition ÀÌ attachment; filename="" À¸·Î µÇ¾î ÀÖ´Ù¸é
request.setTitle(URLUtil.guessFileName(url,contentDisposition,mimeType));
inline; filename="" À¸·Î µÇ¾î ÀÖ´Ù¸é
String fileName = contentDisposition.replace("inline; filename=", "");
fileName = fileName.replaceAll("\"", "");
request.setTitle(fileName);
À¸·Î ÀÛ¼ºÇÕ´Ï´Ù.
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
ÀÌ ºÎºÐÀÇ fileNameµµ À§¿Í°°ÀÌ URLUtil.guessFileName(url,contentDisposition,mimeType) or fileNameÀ¸·Î ³Ñ°ÜÁÝ´Ï´Ù.
* sdk23 ( android 6 marshmallow)¿¡¼´Â À§ ÄÚµåÀÇ tryºÎºÐÀº ²À try catch·Î °¨½ÎÁà¾ß ÇÕ´Ï´Ù. °¨½ÎÁÖÁö ¾ÊÀ¸¸é SecurityExceptionÀ» ¹ß»ý½ÃÅ°¸ç ¾îÇÃÀÌ Á×½À´Ï´Ù.
Á¤»óµ¿ÀÛÀ» À§Çؼ´Â º°µµÀÇ permissionÀ» ¿äûÇØ¾ß µË´Ï´Ù.
catch¿¡¼ permissionÀ» ¿äûÇÕ´Ï´Ù.
if (ContextCompat.checkSelfPermission(MainActivity.this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) { //1. if no permission
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) { //3. if user click deny, re-requestPermission
Toast.makeText(getBaseContext(), "÷ºÎÆÄÀÏ ´Ù¿î·Îµå¸¦ À§ÇØ\nµ¿ÀÇ°¡ ÇÊ¿äÇÕ´Ï´Ù.", Toast.LENGTH_LONG).show();
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
110);
} else { // 2.first requestPermission : yes or no
Toast.makeText(getBaseContext(), "÷ºÎÆÄÀÏ ´Ù¿î·Îµå¸¦ À§ÇØ\nµ¿ÀÇ°¡ ÇÊ¿äÇÕ´Ï´Ù.", Toast.LENGTH_LONG).show();
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
110);
}
}
1. Æ۹̼ÇÀÌ ¾øÀ¸¸é else¿¡¼ À¯Àú¿¡°Ô WRITE_EXTERNAL_STORAGE ±ÇÇÑÀ» ¿äûÇÕ´Ï´Ù.
2. ¿©±â¼ ±ÇÇÑ Çã¿ëÀ» ÇÏ´À³Ä °ÅºÎ¸¦ ÇÏ´À³Ä¸¦ ¼±ÅÃÇϴµ¥ Çã¿ë Çϴ°æ¿ì ÀÌÁ¦ Á¤»óÀûÀ¸·Î ÆÄÀÏ´Ù¿î·Îµå°¡ °¡´ÉÇØÁö°í °ÅºÎÇÒ °æ¿ì ÆÄÀÏ ´Ù¿î·Îµå¸¦ ½ÃµµÇÒ¶§¸¶´Ù 3¹øÀ¸·Î °¡°Ô µË´Ï´Ù.
3. À̺κпª½Ã ±ÇÇÑÀ» ¿äûÇÏ´Â ºÎºÐÀ¸·Î µ¿ÀǸ¦ Çϸé ÆÄÀÏ´Ù¿î·Îµå°¡ °¡´ÉÇØÁö°í °ÅºÎÇÒ °æ¿ì Àç ½Ãµµ½Ã ±ÇÇÑ ¿äûÀ» ÇÕ´Ï´Ù.
°á°ú -
1. ¸µÅ© Ŭ¸¯
2. permission ¿äû
3. ´Ù¿î·Îµå ¼º°ø