WebView에서 Download를 구현해줄 때 서버에서 MIME이나 Filename을 제대로 주지 않는 경우가 많다.
따라서 다음과 같은 기본 뼈다구 작성..
webview.setDownloadListener(new DownloadListener() {
@SuppressLint("DefaultLocale")
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
MimeTypeMap mtm = MimeTypeMap.getSingleton();
DownloadManager downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadUri = Uri.parse(url);
// 파일 이름을 추출한다. contentDisposition에 filename이 있으면 그걸 쓰고 없으면 URL의 마지막 파일명을 사용한다.
String fileName = downloadUri.getLastPathSegment();
int pos = 0;
if ((pos = contentDisposition.toLowerCase().lastIndexOf("filename=")) >= 0) {
fileName = contentDisposition.substring(pos + 9);
pos = fileName.lastIndexOf(";");
if (pos > 0) {
fileName = fileName.substring(0, pos - 1);
}
}
// MIME Type을 확장자를 통해 예측한다.
String fileExtension = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()).toLowerCase();
String mimeType = mtm.getMimeTypeFromExtension(fileExtension);
// Download 디렉토리에 저장하도록 요청을 작성
Request request = new DownloadManager.Request(downloadUri);
request.setTitle(fileName);
request.setDescription(url);
request.setMimeType(mimeType);
request.setDestinationInExternalPublicDir( Environment.DIRECTORY_DOWNLOADS, fileName);
Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DOWNLOADS).mkdirs();
// 다운로드 매니저에 요청 등록
downloadManager.enqueue(request);
}
});
다운로드가 끝나고 나면 다운로드 완료창을 열어 준다.
// 다운로드 완료 수신자 생성
private BroadcastReceiver completeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Resources res = context.getResources();
// 다운로드 완료 토스트 출력
Toast.makeText(context, res.getString(R.string.download_complete), Toast.LENGTH_SHORT).show();
// 다운로드 완료 창으로 이동
startActivity(new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS));
}
};
@Override
protected void onPause() {
super.onPause();
// 앱이 중단 되면 리시버 등록 해제
unregisterReceiver(completeReceiver);
}
@Override
protected void onResume() {
// 앱이 실행되면 리시버 등록
IntentFilter completeFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(completeReceiver, completeFilter);
super.onResume();
}
아웅.. 귀찮..