안드로이드에서 웹뷰(WebView) 구현 시 파일 다운로드 기능을 추가하는 작업을 구현해 보았습니다.
작성한 파일 목록 입니다.
1. AndroidManifest.xml
2. WebViewActivity.java
3. file.jsp (웹소스)
4. FileController.java (웹소스)
1. AndroidManifest.xml
저장소 파일 접근 권한 을 추가해야 합니다.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
두개 다 추가해 주세요~
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.eun.myapp">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:usesCleartextTraffic="true" >
<activity android:name=".WebViewActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
2. WebViewActivity.java
현재 소스에서는 파일다운로드 버튼을 클릭해도 아무런 반응이 일어나지 않습니다.
파일다운로드 버튼 클릭 시 파일 다운로드를 실행하기 위해서는 WebViewActivity 클래스 안에 다음과 같은 코드를 추가합니다.
onCreate() 에 웹뷰(webview) 를 설정해주는 부분에서 webView.setDownloadListener 를 추가해줍니다.
그러면 파일 다운로드를 누르는 순간 리스너가 호출됩니다.
WebViewClient 를 상속받고 DownloadListener 를 구현한 MyDownloadListener 클래스의 onDownloadStart() 메소드를 구현하여 파일 다운로드를 실행할 수 있습니다.
@Override
protected void onCreate(Bundle savedInstanceState) {
...
webView.setDownloadListener(new MyWebViewClient());
...
}
/* WebViewClient 를 상속받는 MyDownloadListener 클래스를 만들어 DownloadListener 를 구현해준다 */
private class MyWebViewClient extends WebViewClient implements DownloadListener {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
Log.d(TAG, "***** onDownloadStart()");
Log.d(TAG,"***** onDownloadStart() - url : "+url);
Log.d(TAG,"***** onDownloadStart() - userAgent : "+userAgent);
Log.d(TAG,"***** onDownloadStart() - contentDisposition : "+contentDisposition);
Log.d(TAG,"***** onDownloadStart() - mimeType : "+mimeType);
//권한 체크
// if(권한 여부) {
//권한이 있으면 처리
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
try {
contentDisposition = URLDecoder.decode(contentDisposition, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
contentDisposition = contentDisposition.substring(0, contentDisposition.lastIndexOf(";"));
request.setMimeType(mimeType);
//------------------------COOKIE!!------------------------
String cookies = CookieManager.getInstance().getCookie(url);
request.addRequestHeader("cookie", cookies);
//------------------------COOKIE!!------------------------
request.addRequestHeader("User-Agent", userAgent);
request.setDescription("Downloading file...");
request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimeType));
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimeType));
DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
dm.enqueue(request);
Toast.makeText(getApplicationContext(), "파일을 다운로드합니다.", Toast.LENGTH_LONG).show();
// } else {
//권한이 없으면 처리
// }
}
}
이렇게 해주면 파일다운로드 버튼 클릭 시 /내장메모리/Download/ 폴더 안에 다운로드 받은 파일이 저장됩니다.
3. file.jsp
웹뷰(WebView) 에 표시할 웹페이지에 파일 다운로드 버튼 클릭 시 첨부파일을 다운로드 하는 button 태그를 구현하고
/myweb/downloadFile.do 를 통해 첨부파일을 다운로드 하는 아주 아주 간단하게 테스트용 웹소스를 구현하였습니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<html>
<head>
<title>Home</title>
<script type="text/javascript" src="./resources/js/jquery-3.2.1.min.js"></script>
</head>
<body>
<h1 style="margin: 50px;">
File
</h1>
<div style="margin-bottom: 50px;">
<table style="width: 100%; height: 100px;">
<tr>
<th style="font-size: xx-large; color: #8C8C8C; text-align: left; padding-left: 50px;">첨부파일 업로드/다운로드 </th>
</tr>
</table>
</div>
<div>
<table style="width: 110%;background-color: #E4F7BA;">
<tr>
<td id="" style="padding: 25px 25px 10px 100px;">
<form id="form_file" enctype="multipart/form-data">
<div class="add_file" id="add_file_0">
<input title="첨부파일 업로드" type="file" id="fileData_0" name="fileData_0" value="" style="font-size: xxx-large;">
</div>
</form>
</td>
</tr>
</table>
</div>
<div>
<table style="width: 110%; background-color: #D4F4FA; margin-top: 50px;">
<tr>
<td id="" style="padding: 25px 25px 10px 100px;">
<div class="" id="">
<button id="filePpt_0" name="filePpt_0" value="" style="font-size: xxx-large;"> 파일 다운로드 </button>
</div>
</td>
</tr>
</table>
</div>
<script type="text/javascript">
$(function(){
$('#filePpt_0').click(function() {
var param = "?code=";
location.href="/myweb/downloadFile.do"+param;
});
});
</script>
</body>
</html>
4. FileController.java
location.href="/myweb/downloadFile.do"; 를 호출했을 때 실행되는 controller 를 구현한 FileController 입니다.
ResponseEntity<InputStreamResource> 를 반환값으로 한 downloadFile() 메소드를 통해 첨부파일을 다운로드 하였습니다~
package com.eun.myweb;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FileUtils;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
public class FileController {
@RequestMapping(value="/downloadFile.do")
public ResponseEntity<InputStreamResource> downloadFile(@RequestParam String code, HttpServletResponse response, HttpServletRequest request) throws Exception {
System.out.println("downloadFile");
String filePath = "/Users/~파~일~경~로~/"; //파일 경로
String fileNm = "myPptFile.pptx"; //파일 이름
String fileType = fileNm.substring(fileNm.lastIndexOf(".")).trim(); //파일 형식
String mineType = "";
//.equalsIgnoreCase() 를 사용하여 대소문자 구분 없이 파일 형식을 확인한다
if (fileType.equalsIgnoreCase(".hwp")) {
mineType = "application/x-hwp";
} else if (fileType.equalsIgnoreCase(".pdf")) {
mineType = "application/pdf";
} else if (fileType.equalsIgnoreCase(".doc") || fileType.equalsIgnoreCase(".docx")) {
mineType = "application/msword";
} else if (fileType.equalsIgnoreCase(".xls") || fileType.equalsIgnoreCase(".xlsx")) {
mineType = "application/vnd.ms-excel";
} else if (fileType.equalsIgnoreCase(".ppt") || fileType.equalsIgnoreCase(".pptx")) {
mineType = "application/vnd.ms-powerpoint";
} else if (fileType.equalsIgnoreCase(".zip")) {
mineType = "application/zip";
} else if (fileType.equalsIgnoreCase(".jpeg") || fileType.equalsIgnoreCase(".jpg") || fileType.equalsIgnoreCase(".png")) {
mineType = "image/jpeg";
} else if (fileType.equalsIgnoreCase(".txt")) {
mineType = "textplain";
}
System.out.println("[downloadFile] fileNm : "+fileNm);
File file = new File(filePath, fileNm);
InputStreamResource isr = new InputStreamResource(FileUtils.openInputStream(file));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType(mineType));
headers.add("Access-Control-Allow-Origin", "*");
headers.add("Access-Control-Allow-Methods", "GET, POST, PUT");
headers.add("Access-Control-Allow-Headers", "Content-Type");
headers.add("Content-Disposition", "attachment; filename=" + fileNm + ";");
headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
headers.add("Set-Cookie", "fileDownload=true; path='/");
headers.add("Pragma", "no-cache");
headers.add("Expires", "0");
headers.setContentLength(file.length());
ResponseEntity<InputStreamResource> responseEntity = new ResponseEntity<InputStreamResource>(isr, headers, HttpStatus.OK);
return responseEntity;
}
}
안드로이드 결과화면
파일 다운로드 버튼 클릭 시 "파일을 다운로드합니다." 라는 토스트가 표시되고
상단바에 파일 관리자를 통해 파일 다운로드가 진행됩니다.
다운로드가 완료되면 /내장메모리/Download/ 폴더 안에 다운로드 받은 파일이 저장된 것을 확인할 수 있습니다!
🗳📂🗂
'🤖 안드로이드 Android' 카테고리의 다른 글
[안드로이드/Android] 앱 정보 가져오기 (앱아이디, 앱이름, 패키지명, 버전이름, 버전코드) (1) | 2021.05.03 |
---|---|
[안드로이드/Android] 기기 단말정보 가져오기 (단말ID, 제조사, 브랜드, 모델명, OS버전, SDK 버전) (0) | 2021.04.23 |
[안드로이드/Android] 웹뷰(WebView) 파일 업로드 (3) | 2021.03.26 |
[안드로이드/Android] 웹뷰(WebView) 만들기 (5) | 2021.03.25 |
[안드로이드/Android] 그리드뷰(GridView) 만들기 (0) | 2021.03.25 |