[Android] 안드로이드 웹뷰(WebView) 파일 다운로드
안드로이드 하이브리드 앱의 웹뷰(WebView) 안에서 파일 다운로드 URL을 호출했을 때 아무 반응이 없는 경우.
오류가 아니고 원래 안드로이드는 웹뷰에 DownloadListener를 구현해줘야만 파일 다운로드 가능하다.
해당 웹뷰를 사용하는 Activity(정확히 표현하면 Activity 클래스를 상속받은 특정 Activity) 의 onCreate 메서드 안에 다음과 같이 작성한다.
|
public class OOOActivity extends Activity {
public Activity thisActivity = null;
public WebView webView = null;
(중략)
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
thisActivity = this;
(중략)
// 안드로이드 파일 다운로드 구현 (웹메일 첨부 다운로드) webView.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)); DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
contentDisposition = URLDecoder.decode(contentDisposition,”UTF-8″);
// 파일명 잘라내기
String fileName = contentDisposition; if (fileName != null && fileName.length() > 0) { int idxFileName = fileName.indexOf(“filename=”); if (idxFileName > -1) { fileName = fileName.substring(idxFileName + 9).trim(); }
if (fileName.endsWith(“;”)) { fileName = fileName.substring(0, fileName.length() – 1); }
if (fileName.startsWith(“\””) && fileName.startsWith(“\””)) { fileName = fileName.substring(1, fileName.length() – 1); } }
// 세션 유지를 위해 쿠키 세팅하기 String cookie = CookieManager.getInstance().getCookie(url); request.addRequestHeader(“Cookie”, cookie);
request.setMimeType(mimetype); request.addRequestHeader(“User-Agent”, userAgent); request.setDescription(“Downloading File”); request.setAllowedOverMetered(true); request.setAllowedOverRoaming(true); request.setTitle(fileName); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { request.setRequiresCharging(false); }
request.allowScanningByMediaScanner(); request.setAllowedOverMetered(true); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
dm.enqueue(request); Toast.makeText(getApplicationContext(),”파일을 다운로드 합니다.”, Toast.LENGTH_LONG).show(); } catch (Exception e) { if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { Toast.makeText(getBaseContext(), “파일 다운로드 권한을 허용해주십시오.”, Toast.LENGTH_LONG).show(); ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1004); } else { Toast.makeText(getBaseContext(), “파일 다운로드 권한을 허용해주십시오.”, Toast.LENGTH_LONG).show(); ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1004); } } } } });
(후략)
|
이어서 AndroidManifest.xml 에 다음과 같이 권한 코드를 넣는다.
|
<!– 파일 다운로드 권한 –> <uses-permission android:name=”android.permission.WRITE_EXTERNAL_STORAGE” /> <uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE” />
|
파일 다운로드가 수행되지 않는 경우가 발견되어 내용을 추가한다. URL이 파일명으로 끝나지 않는 경우에만 그랬다. 처음엔 https 문제인 것으로 판단했는데, 드랍박스에 파일을 업로드해서 테스트 해본 결과 https 도 잘 동작했다.
확인해보니 파일 다운로드 앞단에서 세션을 체크하는 경우였다. 파일 다운로드가 정상적으로 수행되는 것처럼 보이지만 용량이 3.28kb 로 나오는 등 턱없이 작았다.
아래 코드를 추가하자 해결됐다.
|
// 세션 유지를 위해 쿠키 세팅하기 String cookie = CookieManager.getInstance().getCookie(url); request.addRequestHeader(“Cookie”, cookie);
|
참고사이트 1 : https://onedaycodeing.tistory.com/71
참고사이트 2 : https://stackoverrun.com/ko/q/4885896