Download Util作った


DownloadAsyncTask

Downloadするやつ。AsyncTaskを継承してる

interface DownloadListener

Downloadしてるときに以下のタイミングでコールバックしてくれる人

  • void onUpdateReadSize(int readSize);
    • 読み込みサイズが変わったタイミングでコールバックされる
    • 16384byte毎に呼ばれる
    • 引数:読み込んだサイズ
  • void onPrepared(int fileSize);
    • 読み込み開始直前でコールバックする
    • 引数:DLファイルのサイズ
  • void onCompleted();
    • ダウンロード完了時
  • void onError();
    • エラッたとき
  • void onCanceled();
    • キャンセル時

コンストラク

引数

  • String fileUrl : ダウンロードパス
  • File outputFileDir : 保存先ディレクト
  • String fileName : 保存するファイル名
  • DownloadListener listener : リスな

使い方

  1. DownloadAsyncTaskを準備
  2. DownloadListener実装
  3. DownloadAsyncTask#executeを実行する

これだけ

URLConnection覚書

たかだかファイルDLくらいでHttpClientを使いたくなかったのでURLConnectionをつかったら以下の件ではまった。
2回連続してDownloadしようとすると失敗する。
ここを参考にさせてもらいました。
kazzzの日記: http://d.hatena.ne.jp/Kazzz/20110321
これをするとOKな様子

System.setProperty("http.keepAlive", "false");

ソース

DownloadAsyncTask
public class DownloadAsyncTask extends AsyncTask<Void, Integer, Boolean> {
	private static final String TAG = "DownloadAsyncTask";
	private static final int BUFFER_SIZE = 16384;
	private String fileUrl;
	private File outputFileDir;
	private String outputFileName;
	private File outputFile;
	private int fileSize;
	private int totalBytesRead;
	private DownloadListener listener;

	public void setListener(DownloadListener listener) {
		this.listener = listener;
	}

	public interface DownloadListener {
		void onUpdateReadSize(int readSize);

		void onPrepared(int fileSize);

		void onCompleted();

		void onError();

		void onCanceled();
	}

	public DownloadAsyncTask(String fileUrl, File outputFileDir, String fileName,
			DownloadListener listener) {
		_L.v(TAG, "outputDir:" + outputFileDir.toString() + " fileName:" + fileName);
		this.fileUrl = fileUrl;
		this.outputFileDir = outputFileDir;
		this.outputFileName = fileName;
		this.listener = listener;
	}

	@Override
	protected Boolean doInBackground(Void... params) {
		System.setProperty("http.keepAlive", "false");
		URLConnection cn = null;
		InputStream inputStream = null;

		BufferedOutputStream bufferedOutpuStream = null;
		BufferedInputStream bufferedInputStream = null;
		try {
			cn = new URL(fileUrl).openConnection();
			cn.connect();
			fileSize = cn.getContentLength();
			listener.onPrepared(fileSize);

			inputStream = cn.getInputStream();

			if (inputStream == null) {
				Log.e(getClass().getName(), "Unable to create InputStream for Url:" + fileUrl);
				listener.onError();

			}

			outputFile = new File(outputFileDir, outputFileName);

			if (outputFile.exists()) {
				outputFile.delete();
				outputFile = new File(outputFileDir, outputFileName);
			}
			bufferedInputStream = new BufferedInputStream(inputStream, BUFFER_SIZE);
			bufferedOutpuStream = new BufferedOutputStream(new FileOutputStream(outputFile, false),
					BUFFER_SIZE);

			byte buf[] = new byte[16384];
			int size = -1;
			while ((size = bufferedInputStream.read(buf)) != -1) {
				if (isCancelled()) {
					listener.onCanceled();
					break;
				}
				totalBytesRead += size;
				bufferedOutpuStream.write(buf, 0, size);
				publishProgress(totalBytesRead);
			}

		} catch (Exception e) {
			listener.onError();
			return false;

		} finally {
			try {
				if (bufferedOutpuStream != null) {
					bufferedOutpuStream.flush();
					bufferedOutpuStream.close();
				}
				if (bufferedInputStream != null) {
					bufferedInputStream.close();
				}
				if (inputStream != null) {
					inputStream.close();
				}

			} catch (IOException e) {
				listener.onError();
				return false;
			}
		}
		return true;
	}

	@Override
	protected void onPostExecute(Boolean result) {
		if (result) {
			listener.onCompleted();

		}
	}

	@Override
	protected void onProgressUpdate(Integer... values) {
		// _L.d(TAG, "onProgressUpdate :" + values[0]);
		listener.onUpdateReadSize(values[0]);
	}

	@Override
	protected void onCancelled() {
		super.onCancelled();
	}

}
DownloadActivity

DownloadAsyncTaskを使う人

public class DownloadActivity extends Activity {
	private static final String TAG = "DownloadActivity";
	private static final String ULR = "[DownlodURL]";
	

	private String fileName;
	private File downloadPath;
	private ProgressBar bar;
	private TextView textMessage;
	private TextView textSize;
	private TextView textMaxSize;
	Handler handler;

	private DownloadAsyncTask downloadTask;
	private DownloadListener listener = new DownloadListener() {

		@Override
		public void onPrepared(int fileSize) {
			_L.d("size:" + fileSize);
			final String maxSize;
			
			if(fileSize < 0){
				maxSize = "サイズ不明";
				bar.setMax(Integer.MAX_VALUE / 1000);
			}else{
				maxSize = String.valueOf(fileSize);
				bar.setMax(fileSize);
			}
//			Handler handler = new Handler();
			handler.post(new Runnable() {

				@Override
				public void run() {
					textMessage.setText("Download Start");
					textMaxSize.setText(maxSize);
				}
			});

		}

		@Override
		public void onError() {
			Toast.makeText(DownloadActivity.this, "m9(^Д^)プギャー", Toast.LENGTH_LONG)
			.show();
		}

		@Override
		public void onCompleted() {
			Log.v(TAG, "onCompleted");
			Toast.makeText(DownloadActivity.this, "Download Complete!!!", Toast.LENGTH_LONG)
					.show();
			textMessage.setText("Download Complete!!!");
			Log.v(TAG, "onCompleted out");
		}

		@Override
		public void onCanceled() {

		}

		@Override
		public void onUpdateReadSize(final int readSize) {
			bar.setProgress(readSize);
			textSize.setText("" + readSize);
			_L.v("" + readSize);
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.layout_download);
		
		downloadPath = FileUtil.getSdcard();
		fileName = FileUtil.getFileName(ULR);

		bar = (ProgressBar) findViewById(R.id.progressBar1);
		textMessage = (TextView) findViewById(R.id.text_message);
		textSize = (TextView) findViewById(R.id.text_size);
		textMaxSize = (TextView) findViewById(R.id.text_maxsize);
		handler = new Handler();
	}

	
	public void onClickDownloadButton(View v) {
		if (downloadTask == null || downloadTask.getStatus() != AsyncTask.Status.RUNNING) {
			downloadTask = new DownloadAsyncTask(ULR, downloadPath, fileName, listener);
			downloadTask.execute((Void) null);
		}else{
			Toast.makeText(this, "Dwonloading now...", Toast.LENGTH_SHORT).show();
		}
	}
}