일용직 코딩노동자

안드로이드(Android) 하이브리드(Hybrid)앱 첨부파일 다운로드 본문

Android

안드로이드(Android) 하이브리드(Hybrid)앱 첨부파일 다운로드

사용자 일용직 코딩노동자 2020. 2. 26. 14:26

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));
                    DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

                    contentDisposition = URLDecoder.decode(contentDisposition,"UTF-8"); //디코딩
                    String FileName = contentDisposition.replace("attachment; filename=", ""); //attachment; filename*=UTF-8''뒤에 파일명이있는데 파일명만 추출하기위해 앞에 attachment; filename*=UTF-8''제거

                    String fileName = FileName; //위에서 디코딩하고 앞에 내용을 자른 최종 파일명
                    request.setMimeType(mimetype);
                    request.addRequestHeader("User-Agent", userAgent);
                    request.setDescription("Downloading File");
                    request.setAllowedOverMetered(true);
                    request.setAllowedOverRoaming(true);
                    request.setTitle(fileName);
                    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(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                        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}, 1004);
                        }
                        else {
                            Toast.makeText(getBaseContext(), "다운로드를 위해\n권한이 필요합니다.", Toast.LENGTH_LONG).show();
                            ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1004);
                        }
                    }
                }
            }
        });

전체코드입니다.

 

onCreate안에 넣어주시면 되는데요.

 

첨부파일을 누르는 순간 리스너가 호출되고, 오버라이드메소드에서 다운로드 url을 받고

 

userAgent에서는 기기의 정보 및 브라우저 정보들이 담겨있습니다.

 

그리고 중요한 2가지가 있는데, contentDisposition이녀석은 결정적으로 파일이름 입니다.

 

소스코드 보시면

 

contentDisposition = URLDecoder.decode(contentDisposition,"UTF-8");

 

이부분이 있는데요 파일이름이 한글로 되어있는경우 한글이 깨지는 현상이 발생합니다.

 

그래서 디코딩을 통해 한글로 정상출력 가능하게 해준다음,

 

String FileName = contentDisposition.replace("attachment; filename=", "");

 

이코드를 보시면 파일이름.확장자 앞에 attachment; filename= 이런문구가 붙어있습니다.

 

이 문구는 다 달라요 저렇게 안나오실수도있습니다.

 

그럴땐 로그로 contentDisposition값을 찍어서 보신다음 앞에 뭐라고 나오는지 보신 후,

 

위 코드처럼 replace를 통해서 앞에 불필요한 부분을 없애줍니다.

 

replace는 앞에 인자값에 들어간 String형 문자열을 두번째 인자값으로 바꾸겠다는건데 저는 ""로 되어있기때문에

지워 집니다.

 

그럼 순수 파일명.확장자 만 남게되는데요 그게 이제 진짜 파일이름 입니다.

 

이제 그다음에 mimetype가 있는데 이녀석은 확장자를 안드로이드(WebView)에게 알려줍니다.

 

아 지금 이파일 확장자가 뭐 hwp야! pdf야! 라고 알려줍니다.

 

그뒤에 코드들은 이제 다운로드에 필요한녀석들을 셋팅해줍니다.

 

파일이름은 무엇이고 이 브라우저 정보가 어떻게되고 확장자타입은 어떤것이며 저장은 어디에 할것인지 등등 지정해줍니다.

 

request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);

이녀석이 앞에 인자가 저장경로 뒤에 인자가 어떤이름으로 저장할것인지

 

fileName는 아까 저희가 replace로 만들었죠? 그대로 적어주시면됩니다.

 

밑에 이제 catch문이 있습니다.

 

다운로드를 위해서는 권한이 필요한데,

 

WRITE_EXTERNAL_STORAGE 권한이 필요한데요.

 

우선 메니페스트에서

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

저는 그냥 둘다 넣어줬습니다.

 

저장소 권한은 위험권한 이기때문에 퍼미션체크를 해주셔야합니다.

 

박상권님 블로그에 implementation 'gun0912.ted:tedpermission:2.0.0' 라는 라이브러리를 해놓으셨는데

 

매우 유용한 라이브러리 입니다. 퍼미션을 복잡하게 하지않고 바로바로 체크할수있습니다.

 

이렇게 셋팅해주시면 첨부파일 다운로드가 완료됩니다.

 

한글문서나 pdf문서같은 경우 뷰어가 따로 설치되어야 열릴수있습니다.

 

도움이 되셨다면 하트와 궁금하신 사항은 댓글을 남겨주세요.

5 Comments
댓글쓰기 폼