標籤:android下載 android-async-http
android-async-http項目地址 https://github.com/loopj/android-async-http,android-async-http顧名思義是非同步http請求,不過它也支援同步請求的,本文主要使用了android-async-http做非同步請求下載檔案。每當app需要更新新版本的時候,就需要用到下載功能的,經研究android-async-http這個第三方開源項目還是挺好用的,這裡介紹給大家。
1、下載類DownloadManager.java
package com.figo.study.latin.mgr;import java.io.File;import java.io.IOException;import java.util.HashMap;import org.apache.http.Header;import android.content.Context;import android.net.ConnectivityManager;import android.os.Environment;import com.figo.study.R;import com.android.inputmethod.latin.model.AsyncDownload;import com.figo.study.util.FileUtil;import com.figo.study.util.NetworkUtil;import com.loopj.android.http.AsyncHttpClient;import com.loopj.android.http.FileAsyncHttpResponseHandler;/** * 非同步下載類 * @author figo * */public class DownloadManager { private boolean mUseWifiOnly = false; public DownloadManager() { } private HashMap<String, AsyncDownload> asyncDownlaods = null; public void init() { asyncDownlaods = new HashMap<String, AsyncDownload>(); } public void download(final Context context, String url, final String md5, String dirPath, String fileName, final DownloadListener callback) { try { callback.onStart(); if (!NetworkUtil.isNetworkUseful(context)) { callback.onError(context.getString(R.string.lbl_network_useless)); } if (mUseWifiOnly) { if (NetworkUtil.getNetworkType(context) != ConnectivityManager.TYPE_WIFI) { callback.onError(context.getString(R.string.lbl_not_support)); } return; } String sdPath = Environment.getExternalStorageDirectory() + "/"; AsyncHttpClient client =new AsyncHttpClient(); if (!asyncDownlaods.containsKey(url)) { AsyncDownload asyncDownload = new AsyncDownload(); asyncDownload.setAsyncHttpClient(client); asyncDownload.setFileName(sdPath + dirPath + fileName); asyncDownlaods.put(url, asyncDownload); }else { client=asyncDownlaods.get(url).getAsyncHttpClient(); } File file = new File(sdPath + dirPath, fileName); try { FileUtil.createSDDir(dirPath); file = FileUtil.createSDFile(dirPath + fileName); } catch (IOException e1) { if (e1 != null) { e1.printStackTrace(); } } FileAsyncHttpResponseHandler fileAsyncHttpResponseHandler = new FileAsyncHttpResponseHandler(file) { @Override public void onCancel() { super.onCancel(); System.out.print("cancel success!"); } @Override public void onProgress(int bytesWritten, int totalSize) { super.onProgress(bytesWritten, totalSize); int currentProgress = (int) ((bytesWritten * 1.0f / totalSize) * 100); callback.onProgress(currentProgress); } @Override public void onStart() { super.onStart(); } @Override public void onFailure(int arg0, Header[] arg1, Throwable arg2, File arg3) { if (arg2 != null) { arg2.printStackTrace(); } if (arg2 != null) { callback.onError(arg2.getMessage()); } else { callback.onError(context.getString(R.string.lbl_network_error)); } } @Override public void onSuccess(int arg0, Header[] arg1, File arg2) { String md5String = ""; try { md5String = FileUtil.getFileMD5String(arg2); } catch (Exception e) { if (e != null) { e.printStackTrace(); } }// if (md5.equals(md5String) == false) {// callback.onError(context.getString(R.string.lbl_md5_error));// } else {// callback.onSuccess();// } //測試放開 callback.onSuccess(); } }; client.setEnableRedirects(true);//允許重複下載 client.get(context, url, fileAsyncHttpResponseHandler); } catch (Exception e) { callback.onError(context.getString(R.string.lbl_system_err)); } } public void setDownloadWifiOnly(boolean value) { mUseWifiOnly = value; } public void cancelDownload(Context context, String url) { try { if (asyncDownlaods != null && asyncDownlaods.containsKey(url)) { //已經下載的檔案刪除 FileUtil.deleteFile(asyncDownlaods.get(url).getFileName()); //取消當前下載 AsyncHttpClient client = asyncDownlaods.get(url).getAsyncHttpClient(); if (client != null) { client.cancelRequests(context, true); } //當前key刪除 asyncDownlaods.remove(url); } } catch (Exception e) { if (e != null) { e.printStackTrace(); } } }}
2、下載監聽類DownloadListener.java
public interface DownloadListener { public void onStart(); public void onError(String errMessage); public void onSuccess(); public void onProgress(int progress);}
3、檔案管理類FileUtil.java
/** * */package com.figo.study.util;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import android.os.Environment;/** * @author figo * */public class FileUtil { //得到當前外部存放裝置的目錄( /SDCARD ) static String SDPATH = Environment.getExternalStorageDirectory() + "/"; /** * 預設的密碼字串組合,用來將位元組轉換成 16 進位表示的字元,apache校正下載的檔案的正確性用的就是預設的這個組合 */ protected static char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; protected static MessageDigest messagedigest = null; static { try { messagedigest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } public static String getFileMD5String(File file) throws IOException { InputStream fis; fis = new FileInputStream(file); byte[] buffer = new byte[1024]; int numRead = 0; while ((numRead = fis.read(buffer)) > 0) { messagedigest.update(buffer, 0, numRead); } fis.close(); return bufferToHex(messagedigest.digest()); } private static String bufferToHex(byte bytes[]) { return bufferToHex(bytes, 0, bytes.length); } private static String bufferToHex(byte bytes[], int m, int n) { StringBuffer stringbuffer = new StringBuffer(2 * n); int k = m + n; for (int l = m; l < k; l++) { appendHexPair(bytes[l], stringbuffer); } return stringbuffer.toString(); } private static void appendHexPair(byte bt, StringBuffer stringbuffer) { char c0 = hexDigits[(bt & 0xf0) >> 4];// 取位元組中高 4 位的數字轉換 // 為邏輯右移,將符號位一起右移,此處未發現兩種符號有何不同 char c1 = hexDigits[bt & 0xf];// 取位元組中低 4 位的數字轉換 stringbuffer.append(c0); stringbuffer.append(c1); } public static void main(String[] args) throws IOException { File file = new File("E:/test/crm_account_YYYY_MM_DD.txt"); String md5 = getFileMD5String(file); System.out.println("md5:" + md5); } /** * 在SD卡上建立檔案 * @param fileName * @return * @throws IOException */ public static File createSDFile(String fileName) throws IOException { File file = new File(SDPATH + fileName); if(file.exists()) { final File to = new File(file.getAbsolutePath() + System.currentTimeMillis()); file.renameTo(to); to.delete();// file.delete(); } file.createNewFile(); return file; } /** * 在SD卡上建立目錄 * @param dirName * @return */ public static File createSDDir(String dirName) { File dir = new File(SDPATH + dirName); if(!dir.exists()) { dir.mkdirs(); } return dir; } /** * 判斷SD卡上的檔案夾是否存在 * @param fileName * @return */ public boolean isFileExist(String fileName) { File file = new File(SDPATH + fileName); return file.exists(); } /** * 刪除檔案 * @param fileName * @return */ public static void deleteFile(String fileName) { try { File file = new File(fileName); if(file.exists()) { file.delete(); } } catch (Exception e) { if(e!=null) { e.printStackTrace(); } } }}
4、網路管理類NetworkUtil.java
public class NetworkUtil { public static int getNetworkType(Context mContext) { try { final ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); return networkInfo.getType(); } catch (Exception e) { return ConnectivityManager.TYPE_WIFI; } } public static boolean isNetworkUseful(Context mContext) { final ConnectivityManager connectivityManager = (ConnectivityManager) mContext .getSystemService(Context.CONNECTIVITY_SERVICE); final NetworkInfo mobNetInfoActivity = connectivityManager .getActiveNetworkInfo(); if (mobNetInfoActivity == null || !mobNetInfoActivity.isAvailable()) { return false; }else { return true; } }}
5、測試TestDownloadActivity.java
/** * */package com.figo.study.activity;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import com.figo.study.R;import com.android.inputmethod.latin.mgr.DownloadListener;import com.android.inputmethod.latin.view.HorizontalProgressBarWithNumber;import com.loopj.android.http.AsyncHttpClient;import com.loopj.android.http.FileAsyncHttpResponseHandler;/** * @author avazu * */public class TestDownloadActivity extends Activity { private HorizontalProgressBarWithNumber mProgressBar, mProgressBar1; private Button btnDownload, btnCancel, btn_pause_continue, btnDownload1, btnCancel1; AsyncHttpClient client = new AsyncHttpClient(); FileAsyncHttpResponseHandler fileAsyncHttpResponseHandler = null; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_download_test); initView(); } private void initView() { mProgressBar = (HorizontalProgressBarWithNumber) findViewById(R.id.id_progressbar); mProgressBar1 = (HorizontalProgressBarWithNumber) findViewById(R.id.id_progressbar1); // btn_pause_continue = (Button) findViewById(R.id.btn_pause_continue); // btn_pause_continue.setOnClickListener(new OnClickListener() { // // @Override // public void onClick(View v) { // // TODO Auto-generated method stub // fileAsyncHttpResponseHandler.sendRetryMessage(0); // } // }); final String url = "http://dl.wandoujia.com/files/phoenix/latest/wandoujia-wandoujia_web.apk?timestamp=1409388568830"; final String md5 = ""; final String dirPath = "study/download/"; final String fileName = "豌豆莢.apk"; btnDownload = (Button) findViewById(R.id.btn_download); try { btnDownload.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { BaseSkinApplication.shared().getDm().setDownloadWifiOnly(false); BaseSkinApplication.shared().getDm().download(TestDownloadActivity.this, url, md5, dirPath, fileName, new DownloadListener() { @Override public void onStart() { btnDownload.setVisibility(View.GONE); btnCancel.setVisibility(View.VISIBLE); } @Override public void onError(String errMessage) { } @Override public void onSuccess() { } @Override public void onProgress(int progress) { mProgressBar.setProgress(progress); } }); } }); } catch (Exception e) { e.printStackTrace(); } final String url1 = "http://msoftdl.360.cn/mobilesafe/shouji360/360safesis/360MobileSafe.apk"; final String md51 = ""; final String dirPath1 = "study/download/"; final String fileName1 = "360.apk"; btnDownload1 = (Button) findViewById(R.id.btn_download1); try { btnDownload1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { BaseSkinApplication.shared().getDm().setDownloadWifiOnly(false); BaseSkinApplication.shared().getDm().download(TestDownloadActivity.this, url1, md51, dirPath1, fileName1, new DownloadListener() { @Override public void onStart() { btnDownload1.setVisibility(View.GONE); btnCancel1.setVisibility(View.VISIBLE); } @Override public void onError(String errMessage) { } @Override public void onSuccess() { } @Override public void onProgress(int progress) { mProgressBar1.setProgress(progress); } }); } }); } catch (Exception e) { e.printStackTrace(); } btnCancel = (Button) findViewById(R.id.btn_cancel); btnCancel.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { BaseSkinApplication.shared().getDm().cancelDownload(TestDownloadActivity.this, url); btnDownload.setVisibility(View.VISIBLE); btnCancel.setVisibility(View.GONE); } }); btnCancel1 = (Button) findViewById(R.id.btn_cancel1); btnCancel1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { BaseSkinApplication.shared().getDm().cancelDownload(TestDownloadActivity.this, url1); btnDownload1.setVisibility(View.VISIBLE); btnCancel1.setVisibility(View.GONE); } }); }}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
android開發步步為營之67:使用android開源項目android-async-http非同步下載檔案