안드로이드(android) WebView 페이지 이동과 웹에서 다운받은 파일 SDCARD 에서 확인

 

개발환경 : window 7 64bit, Eclipse Kepler, Android 4.2.2

 

웹브라우저 페이지 이동하듯 WebView 를 이용해 같은 기능을 구현할 것이다.

그리고 웹에서 파일에 대한 링크를 제공할 때, 그 파일을 다운받아

SDCARD 에 저장하고 저장된 파일을 확인해 볼 것이다.

오늘은 위에서 언급한 내용에 대한 샘플예제 소스이다.

 

1. 이동하고자 하는 웹페이지를 WebView 표시

 

이동하고자 하는 URL 이 있을경우 WebView::loadUrl 함수를 이용해 파라미터로

원하는 주소를 넣으면 된다. browser.loadUrl("http://google.co.kr/"); 와 같이

코드를 작성하고 실행했는데 아래와 같이 에러가 난다면 Permissions 을 빼먹었던지,

인터넷 연결이 안되어있는 경우이다.

 

 

Permissions AndroidManifest.xml 파일로 가서 추가하도록 한다.

xml 코드를 바로 작성해서 넣지 않고 wizard 화면을 이용해 넣는다면 아래 탭에서

Permissions 선택한다. 그리고 Add 버튼을 클릭해 Uses Permission 을 추가한다.

 

추가 되었다면 오른쪽 콤보박스에서 android.permission.INTERNET 을 선택하고

저장한다. 설정을 마쳤다면 다시 시작한다.

 

소스의 내용은 간단하게 구현되었다. setWebViewClient 함수에 WebViewClient

객체를 등록한다. WebViewClient 내에 shouldOverrideUrlLoading 함수가

있는데 WebView:: loadUrl 다음으로 실행된다. 여기에서 로딩중 작업을 진행하면

된다. 현재 구현된 소스는 없지만 앞으로 여기에 파일 다운로드를 구현 할것이므로

 

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import com.sample.R;

public class UrlLoad extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.urlload);

		WebView browser = (WebView) findViewById(R.id.browser);
		browser.setWebViewClient(new WebViewClient() {
			
			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				return super.shouldOverrideUrlLoading(view, url);
			}
		});
		browser.loadUrl("http://naver.com");
	}
}

 

2. 웹페이지를 통해 파일을 다운받아 SDCARD 에 저장해본다

 

위에서 설명했던 shouldOverrideUrlLoading  함수를 통해 다운로드 기능을

구현할 것이다. 웹뷰에서 보여지는 페이지에서 <a> 태그가 실행되면

shouldOverrideUrlLoadin 함수가 처리를 담당하게 된다. String url 파라미터로

다운로드 주소가 오게 된다.

 

두번째 체크해야 되는 부분은 sdcard 를 접근할수 있도록 permission 을 추가하는 것이다.

만약 하지 않으면 if ( f.createNewFile() )  부분에서 에러가 날것이다.

 

위에서 인터넷을 사용할수 있도록 했던 것 처럼 android.permission.WRITE_EXTERNAL_STORAGE 를 추가하자. 파일을 다운받기 위한 환경을 설정했으니 테스트를 위해 파일을 올려보자.

나는 블러그에 작은 파일 하나를 올려서 안드로이드로 접속해 다운 받을 예정이다.

안드로이드에서 접속하면 다음과 같은 화면을 볼수 있다. 여기서 파일을 클릭해 다운

받으면 된다.

 

처음에 인터넷에서 받은 예제소스로 구현을 했었다. 다운은 잘되는데 시간이

너무 오래걸리고 정확한 크기의 파일을 받아오지 못하는 것이다. 올려놓은

파일보다 더 많이 받는다던지 제대로 되지 않았다. 소스는 다음과 같다.

 

URL myFileUrl = null;
FileOutputStream fos = null;
HttpURLConnection conn = null;
try {
	myFileUrl = new URL(fileUrl);

	conn = (HttpURLConnection) myFileUrl.openConnection();
	conn.setDoInput(true);
	conn.connect();
	
	InputStream is = new URL(fileUrl).openStream();
	
	String mPath = "sdcard/appach.zip";

	File f = new File(mPath);
	if (f.createNewFile()) {
		fos = new FileOutputStream(mPath);
		int read = 0;
		int total = 0;
		while ((read = is.read()) != -1) {
			fos.write(read);
			total += read;
		}
		fos.flush();
		fos.close();
	}
	// 성공
	Toast.makeText(getApplicationContext(), "download complete", 0).show();
} catch (MalformedURLException e) {
	Toast.makeText(getApplicationContext(), "MalformedURLException : download fail", 0).show();
	if (fos != null) {
		try {fos.close();} catch (IOException e1){}
	}
	e.printStackTrace();
} catch (IOException e) {
	Toast.makeText(getApplicationContext(), "IOException : download fail", 0).show();
	if (fos != null) {
		try {fos.close();} catch (IOException e1){}
	}
	e.printStackTrace();
} finally {
	if (conn != null) {
		conn.disconnect();
	}
}

여기저기 인터넷을 뒤져 소스를 수정해서 제대로 된 로직을 구현할수 있었다.

위의 소스와 차이는 무작정 is.read() 해서 읽는게 아니고

byte buf[] = new byte[16384]; 와 같이 버퍼 크기를 크게 잡아서

읽어들였다는 것과 shouldOverrideUrlLoading 함수를 오버로딩해서 쓰는데

함수생성될 때 기본적으로 생성되는 return super.shouldOverrideUrlLoading(view, urlStr);

상위 클래스로 리턴값을 넘기는 소스를 두게 되면 두번 다운로드 되게 된다.

그래서 그부분을 없애고 return true;  로 수정해서 넣었다.

 

Posted by 녹두장군