需求中有需要簡易的下載文件的,例如圖片,音頻,視頻等。首先這個下載工具類沒有斷點下載,也就是說沒有暫停,緩存。不過解決日常工作中的小文件下載是綽綽有餘的。下面可以看一看
一、添加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到此完了。