Android

[Android] WebView 파일 다운로드 구현

밤토리세상 2022. 7. 21. 16:35

하이브리드 앱을 만드는 과정에서 앱에서 직접 파일 다운로드를 구현해야 되는 상황이 생긴다 

보통은 다른 웹 브라우저를 통해서 다운로드 해도 되지만 직접 받기위해서 추가로 구현해야한다

 

webView.setDownloadListener(new DownloadListener() {});

 웹뷰의 setDownloadListener 를 이용하면 파일 다운로드를 만들수있다.

 

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.replace("attachment; filename=", "");
                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((Activity) mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                        Toast.makeText(getBaseContext(), "파일 다운로드 권한을 허용해주십시오.", Toast.LENGTH_LONG).show();
                        ActivityCompat.requestPermissions((Activity) mContext, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1004);
                    } else {
                        Toast.makeText(getBaseContext(), "파일 다운로드 권한을 허용해주십시오.", Toast.LENGTH_LONG).show();
                        ActivityCompat.requestPermissions((Activity) mContext, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1004);
                    }
                }
            }
        }
    });

 

간단히 설명하자면 request 에 파일 다운로드를 위한 정보를 담고 DonloadManager 를 이용하여 해당 request 실행 

 

위 리스너는 웹뷰에서 파일다운로드를 감지했을때 동작되는 부분이며 

당연히 퍼미션 설정이 되어있어야 파일다운로드가 가능하다