package com.hawkbrowser.app; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import org.apache.http.HttpStatus; import com.hawkbrowser.util.CommonUtil; import android.os.AsyncTask; import android.os.Environment; import android.util.Log; public class DownloadAsyncTask extends AsyncTask<DownloadItem, Integer, DownloadItem> { private static int CONNECT_TIMEOUT = 10000; // ms private static int READ_TIMEOUT = 10000; // ms private DownloadManager mDownloadMgr; private DownloadItem mItem; public DownloadAsyncTask(DownloadManager downloadMgr) { mDownloadMgr = downloadMgr; } public DownloadItem item() { return mItem; } protected DownloadItem doInBackground(DownloadItem... params) { InputStream httpStream = null; try { mItem = params[0]; mItem.setStatus(DownloadItem.Status.ONPROGRESS); URL url = new URL(mItem.url()); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(READ_TIMEOUT); conn.setConnectTimeout(CONNECT_TIMEOUT); conn.setRequestMethod("GET"); if(mItem.progress() > 0) { String range = String.format("bytes=%d-", mItem.progress()); conn.setRequestProperty("Range", range); } conn.setDoInput(true); conn.connect(); int responseCode = conn.getResponseCode(); Log.d("Download", String.format("Response code: %d, url %s", responseCode, mItem.url())); if(HttpStatus.SC_OK == responseCode || HttpStatus.SC_PARTIAL_CONTENT == responseCode) { httpStream = conn.getInputStream(); saveToFile(httpStream); } else { mItem.setStatus(DownloadItem.Status.FAILED); } conn.disconnect(); } catch(Exception e) { Log.e("Download", CommonUtil.getExceptionStackTrace(e)); } finally { if(null != httpStream) { try { httpStream.close(); httpStream = null; } catch(Exception e) { } } } return params[0]; } protected void onPostExecute(DownloadItem item) { Log.d("download", "onPoseExecute: " + item.name()); mDownloadMgr.onDownloadFinished(item); } protected void onProgressUpdate(Integer... progress) { mItem.setProgress(progress[0].longValue()); mDownloadMgr.onProgressUpdate(mItem); } // This function is not called....... @Override protected void onCancelled(DownloadItem item) { Log.d("download", "onCancelled: " + item.name()); mDownloadMgr.onDownloadStoped(item); } @Override protected void onCancelled() { mDownloadMgr.onDownloadStoped(mItem); } private void saveToFile(InputStream inputStream) { Log.d("Download", String.format("save to file: %s", mItem.name())); String externalStorageState = Environment.getExternalStorageState(); if(!externalStorageState.equals(Environment.MEDIA_MOUNTED)) { mItem.setLocalFilePath(null); return; } FileOutputStream fos = null; File file = null; if(null != mItem.localFilePath()) { file = new File(mItem.localFilePath()); } else { file = CommonUtil.getUniqueFile( CommonUtil.getDownloadDataDir(), mItem.name()); } Log.d("Download", String.format("Output File: %s", file.getPath())); try { fos = new FileOutputStream(file, mItem.progress() > 0); mItem.setLocalFilePath(file.getPath()); byte[] buffer = new byte[4096]; int readLen = 0; int totalReadLen = 0; long timeLastProgressUpdate = System.nanoTime(); long progressUpdateDistance = 300 * 1000 * 1000; // 200ms while((readLen = inputStream.read(buffer)) != -1) { if(isCancelled()) { Log.d("download", "download cancel: " + mItem.name()); break; } fos.write(buffer, 0, readLen); totalReadLen += readLen; if(System.nanoTime() - timeLastProgressUpdate > progressUpdateDistance) { publishProgress(totalReadLen); totalReadLen = 0; timeLastProgressUpdate = System.nanoTime(); } } if(totalReadLen > 0) { publishProgress(totalReadLen); totalReadLen = 0; } fos.flush(); } catch(Exception e) { e.printStackTrace(); } finally { if(null != fos) { try { fos.close(); fos = null; } catch(Exception e) { } } } } }