Android基於Okhttp3的檔案下載工具類
阿新 • • 發佈:2019-02-03
需求中有需要簡易的下載檔案的,例如圖片,音訊,視訊等。首先這個下載工具類沒有斷點下載,也就是說沒有暫停,快取。不過解決日常工作中的小檔案下載是綽綽有餘的。下面可以看一看
一、新增okhttp3的遠端依賴
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:okhttp-urlconnection:3.4.1'
二、新增網路和檔案讀寫許可權
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
三、全部程式碼
package com.qiumilianmeng.qmlm.utils; import android.os.Handler; import android.os.Message; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; /** * Created by yufs on 2017/8/16. */ public class DownloadUtil { public static final int DOWNLOAD_FAIL=0; public static final int DOWNLOAD_PROGRESS=1; public static final int DOWNLOAD_SUCCESS=2; private static DownloadUtil downloadUtil; private final OkHttpClient okHttpClient; public static DownloadUtil getInstance() { if (downloadUtil == null) { downloadUtil = new DownloadUtil(); } return downloadUtil; } private DownloadUtil() { okHttpClient = new OkHttpClient(); } /** * */ public void download(final String url,final String saveDir,final OnDownloadListener listener){ this.listener=listener; Request request=new Request.Builder().url(url).build(); okHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Message message=Message.obtain(); message.what=DOWNLOAD_FAIL; mHandler.sendMessage(message); } @Override public void onResponse(Call call, Response response) throws IOException { InputStream is=null; byte[] buf=new byte[2048]; int len=0; FileOutputStream fos=null; //儲存下載檔案的目錄 String savePath=isExistDir(saveDir); try{ is=response.body().byteStream(); long total=response.body().contentLength(); File file=new File(savePath,getNameFromUrl(url)); fos=new FileOutputStream(file); long sum=0; while((len = is.read(buf))!=-1){ fos.write(buf,0,len); sum+=len; int progress=(int)(sum*1.0f/total*100); //下載中 Message message=Message.obtain(); message.what=DOWNLOAD_PROGRESS; message.obj=progress; mHandler.sendMessage(message); } fos.flush(); //下載完成 Message message=Message.obtain(); message.what=DOWNLOAD_SUCCESS; message.obj=file.getAbsolutePath(); mHandler.sendMessage(message); }catch (Exception e){ Message message=Message.obtain(); message.what=DOWNLOAD_FAIL; mHandler.sendMessage(message); }finally{ try{ if(is!=null) is.close(); }catch (IOException e){ } try { if(fos!=null){ fos.close(); } }catch (IOException e){ } } } }); } private String getNameFromUrl(String url) { return url.substring(url.lastIndexOf("/")+1); } private String isExistDir(String saveDir) throws IOException { File downloadFile=new File(saveDir); if(!downloadFile.mkdirs()){ downloadFile.createNewFile(); } String savePath=downloadFile.getAbsolutePath(); return savePath; } private Handler mHandler=new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what){ case DOWNLOAD_PROGRESS: listener.onDownloading((Integer) msg.obj); break; case DOWNLOAD_FAIL: listener.onDownloadFailed(); break; case DOWNLOAD_SUCCESS: listener.onDownloadSuccess((String) msg.obj); break; } } }; OnDownloadListener listener; public interface OnDownloadListener{ /** * 下載成功 */ void onDownloadSuccess(String path); /** * 下載進度 * @param progress */ void onDownloading(int progress); /** * 下載失敗 */ void onDownloadFailed(); } }
部分程式碼參考網路上okhttp3的使用,其中需要注意的是okhttp3中的Callback回撥是發生在工作執行緒,也就是說此回撥方法不能直接返回進度更新ui,需要使用handler切換回主執行緒。
四、使用方法
DownloadUtil.getInstance().download(videoUrl, MyApplication.PATH_DOWNLOAD_VIDEO, new DownloadUtil.OnDownloadListener() { @Override public void onDownloadSuccess(String path) { btn_download.setClickable(true); dialog.hide(); ToastMgr.showLong(NetVideoPlayerActivity.this,"視訊已儲存:"+path); } @Override public void onDownloading(int progress) { dialog.setMessage("已下載"+progress+"%"); } @Override public void onDownloadFailed() { dialog.hide(); btn_download.setClickable(true); } });
videoUrl是你需要下載的檔案地址,一般為網路檔案地址,MyApplication.PATH_DOWNLOAD_VIDEO是我專案中SD卡上的一個檔案目錄,此目錄也就是儲存下載檔案的地址,而檔名稱是已網路檔名稱命名的,也可自行修改,ok到此完了。