제임스딘딘의
Tech & Life

개발자의 기록 노트/Android

[안드로이드] 웹뷰를 통한 apk 파일 다운로드 및 제어

제임스-딘딘 2010. 12. 3. 17:12

안드로이드에서 웹뷰를 통한 apk 파일 다운로드 및 제어


아래와 같은 순서로 진행하겠다.
  1. apk 파일을 다운 받을 수 있는 WAS 구축(HTML의 a 태그를 이용한다.)
  2. 안드로이드 웹뷰를 통한 웹페이지 접근
  3. 웹뷰 클라이언트를 오버라이딩하여 apk 파일을 sd 카드 내에 다운 받기
  4. 다운 받은 apk를 안드로이드 패키지 매니저를 통해 install 하기


apk 파일을 다운 받을 WAS 구축

WAS(Web Application Server)는 톰캣을 이용했다. 톰캣의 설치는 간단하므로 이 글에서는 제외한다. 참고로 난 우분투에서 만들었다. war을 톰캣 서버에 deploy할 때 다음과 같은 html을 추가했다.

war 파일 내 경로 : test/
경로 내 포함된 파일 : test.html, HelloWorld.apk



test.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>
<a href="http://[IP 주소]:8180/rfidtest/test/HelloWorld.apk">click here to download apk file. </a>
</h2>
</body>
</html>
위의 소스를 보면 알겠지만, <a> 태그를 통해 apk 파일을 다운할 수 있도록 했다.


HelloWorld.apk
다운로드될 apk 파일. TextView를 통해 HelloWorld 텍스트를 뿌리는 기본 app이다.


안드로이드 웹뷰를 통한 웹페이지 접근


아래 예제코드를 보자.

웹뷰를 통해 웹페이지에 접근하도록 하는 코드이다.

webView.loadUrl("http://[IP 주소]/rfidtest/test/test.html");		// 웹뷰를 통해 웹페이지를 접근한다.
webView.getSettings().setJavaScriptEnabled(true); 		// 자바 스크립트를 enable한다. (이번 글 내용과는 상관 없다.)
webView.requestFocus();				// 웹뷰가 포커스를 가진다.(클릭 및 터치를 app 내에서 처리해야하므로 필요하다.
webView.setWebViewClient(new Callback());			// 웹뷰 클라이언트 등록( 3에서 자세히 설명) 


이제 남은것은 아래 2단계이다.

웹뷰 클라이언트를 오버라이딩하여 apk 파일을 sd 카드 내에 다운 받기 -> 다운 받은 apk를 안드로이드 패키지 매니저를 통해 install 하기

웹뷰를 통해 보여지는 페이지에서, <a> 태그로 이루어진 부분을 클릭(혹은 터치)하게 될 때 그 처리를 담당하는 곳이 shouldOverrideUrlLoading() 메서드이다. 
다음과 같은 방법으로 처리 가능하다.



private class Callback extends WebViewClient {
	 private void downloadFile(String fileUrl){
          URL myFileUrl =null;          
          try {
               myFileUrl= new URL(fileUrl);
          } catch (MalformedURLException e) {
               e.printStackTrace();
          }
          try {
               HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
               conn.setDoInput(true);
               conn.connect();
               InputStream is = conn.getInputStream();

		//다운 받는 파일의 경로는 sdcard/ 아래 이다
		//단, sdcard에 접근하려면 uses-permission에 android.permission.WRITE_EXTERNAL_STORAGE을 추가해야한다.
               String mPath = "sdcard/HelloWorld.apk";
               FileOutputStream fos;
               File f = new File(mPath);
               if ( f.createNewFile() ) {
	              fos = new FileOutputStream(mPath);   
	              int read;
	              while ( (read =  is.read()) != -1) {
	           	  fos.write(read);
	              }
	              fos.close();
               }
          } catch (IOException e) {
               e.printStackTrace();
          }
          Toast.makeText(getApplicationContext(), "download complete", 0).show();
          
	// 안드로이드 패키지 매니저를 통해 다운 받은 apk 파일을 처리하도록 한다.
          File apkFile = new File(Environment.getExternalStorageDirectory()+ "/HelloWorld.apk");
          Intent intent = new Intent(Intent.ACTION_VIEW);
          intent.setDataAndType( Uri.fromFile(apkFile), "application/vnd.android.package-archive");
          startActivity(intent);
     }
	 
	@Override
	public boolean shouldOverrideUrlLoading(WebView view, final String urlStr) {
		// <a> 태그의 href 속성 값이 urlStr로 전달되므로, 파일을 다운로드 하면 된다.
		downloadFile(urlStr);
		return super.shouldOverrideUrlLoading(view, urlStr);
	}
}