非同期処理でネットワークからファイルをダウンロードして、指定のFileに保存するクラスを作りましたです。
今回の使い方アプリは、
ダウンロードボタンを押すと、ネットワークからダウンロードがスタート
終わったら、SDカードに保存します。
■作り方
AndroidManifest.xml にユーザー許可を追加します。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/>
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/loadStartButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Download" /> </LinearLayout>
AsyncFileLoader.java
AsyncTaskを使っています。
あと、InputStreamとOutputStreamを使って
少しずつ入力ファイルを読み込んで、
それを出力ファイルに書き込みます。
package com.kinkuma.util; import java.io.BufferedInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import android.os.AsyncTask; import android.util.Log; public class AsyncFileLoader extends AsyncTask<Void, Void, Boolean> { private final String TAG = "AsyncFileLoader"; private String _urlStr; private URL _url; private URLConnection _urlConnection; private final int TIMEOUT_READ = 5000; private final int TIMEOUT_CONNECT = 30000; private InputStream _inputStream; private BufferedInputStream _bufferedInputStream; private FileOutputStream _fileOutputStream; private File _outputFile; private byte[] buff = new byte[5 * 1024]; private int _totalByte = 0; private int _currentByte = 0; public AsyncFileLoader(String urlStr, File outputFile){ this._urlStr = urlStr; this._outputFile = outputFile; } @Override protected Boolean doInBackground(Void... params) { if(isCancelled()){ return false; } try{ int len; while((len = _bufferedInputStream.read(buff)) != -1){ _fileOutputStream.write(buff, 0, len); _currentByte += len; //publishProgress(); if(isCancelled()){ break; } } }catch(IOException e){ Log.d(TAG, "error on read file:" + e.toString()); return false; } return true; } @Override protected void onPreExecute(){ try{ connect(); }catch(IOException e){ Log.d(TAG, "error on preExecute:" + e.toString()); cancel(true); } } /* @Override protected void onProgressUpdate(Void... progress){ } */ @Override protected void onPostExecute(Boolean result){ if(result == true){ try{ close(); }catch(IOException e){ Log.d(TAG, "error on postExecute:" + e.toString()); } }else{ Log.d(TAG, "result: load error"); } } private void connect() throws IOException { _url = new URL(_urlStr); _urlConnection = _url.openConnection(); _urlConnection.setReadTimeout(TIMEOUT_READ); _urlConnection.setConnectTimeout(TIMEOUT_CONNECT); _inputStream = _urlConnection.getInputStream(); _bufferedInputStream = new BufferedInputStream(_inputStream, 1024 * 5); _fileOutputStream = new FileOutputStream(_outputFile); //_totalByte = _bufferedInputStream.available(); //this is not work _totalByte = _urlConnection.getContentLength(); _currentByte = 0; } private void close() throws IOException { _fileOutputStream.flush(); _fileOutputStream.close(); _bufferedInputStream.close(); } public int getLoadedBytePercent() { if(_totalByte <= 0){ return 0; } //Log.d(TAG, Integer.toString(_currentByte) + ":" + Integer.toString(_totalByte)); return (int)Math.floor(100 * _currentByte/_totalByte); } }
main activity
SDカードのパスを拾うために、Environment.getExternalStorageDirectory()を使いました。
package com.myprogress; import java.io.File; import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.Button; import com.kinkuma.util.AsyncFileLoader; public class DownloadingAndProgressbarActivity extends Activity { private final String TAG = "DownloadSample"; private Button _loadStartButton; private ProgressDialog _progressDialog; private Handler _progressHandler; private final String VIDEO_URL = "http://192.168.1.0/video/sample_movie.mp4"; private AsyncFileLoader _fileLoader; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); _loadStartButton = (Button)findViewById(R.id.loadStartButton); _loadStartButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { initFileLoader(); showDialog(0); _progressDialog.setProgress(0); _progressHandler.sendEmptyMessage(0); } }); _progressHandler = new Handler(){ public void handleMessage(Message msg){ super.handleMessage(msg); if(_fileLoader.isCancelled()){ _progressDialog.dismiss(); Log.d(TAG, "load canceled"); } else if(_fileLoader.getStatus() == AsyncTask.Status.FINISHED){ _progressDialog.dismiss(); }else{ _progressDialog.setProgress(_fileLoader.getLoadedBytePercent()); _progressHandler.sendEmptyMessageDelayed(0, 100); } } }; } @Override protected void onPause(){ Log.d(TAG, "onPause"); super.onPause(); cancelLoad(); } @Override protected void onStop(){ Log.d(TAG, "onStop"); super.onStop(); cancelLoad(); } private void cancelLoad() { if(_fileLoader != null){ _fileLoader.cancel(true); } } private void initFileLoader() { File sdCard = Environment.getExternalStorageDirectory(); File directory = new File(sdCard.getAbsolutePath() + "/SampleFolder"); if(directory.exists() == false){ directory.mkdir(); } File outputFile = new File(directory, "myvideo.mp4"); _fileLoader = new AsyncFileLoader(VIDEO_URL, outputFile); _fileLoader.execute(); } @Override protected Dialog onCreateDialog(int id){ switch(id){ case 0: _progressDialog = new ProgressDialog(this); _progressDialog.setIcon(R.drawable.ic_launcher); _progressDialog.setTitle("Downloading files.."); _progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); _progressDialog.setButton(DialogInterface.BUTTON_POSITIVE, "Hide", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Log.d(TAG, "hide"); } }); _progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Log.d(TAG, "cancel"); cancelLoad(); } }); } return _progressDialog; } }
■ 自作iPhoneアプリ 好評発売中!
・フォルメモ - シンプルなフォルダつきメモ帳
・ジッピー電卓 - 消費税や割引もサクサク計算!
■ LINEスタンプ作りました!
毎日使える。とぼけたウサギ