一、效果图
三个按钮,分别控制下载任务的开始、暂停和结束
下载任务在后台运行,下载状态在通知里可以查看
下载完成后在SD卡中找到已下载的文件查看:
二、代码
1、新建DownloadListener回调接口
/**
* 定义一个回调接口,用于对于下载过程中的各种状态进行监听和回调
*/
public interface DownloadListener {
//用于通知当前的下载进度
void onProgress(int progress);
//用于通知下载成功事件
void onSuccess();
//用于通知下载失败事件
void onFailed();
//用于通知下载暂停事件
void onPaused();
//用于同事下载取消事件
void onCanceled();
}
2、新建一个DownloadTask类用于实现下载功能
/**
* 下载功能的实现
*/
/**
* AsyncTask中传入3个泛型参数
* 第一个指定为String,表示在执行AsyncTask的时候需要传入一个字符串参数给后台任务
* 第二个指定为Integer,表示使用整型数据来作为进度显示单位
* 第三个泛型参数指定为Integer,则表示使用整型数据来反馈执行结果
*/
public class DownloadTask extends AsyncTask<String,Integer,Integer> {
//表示下载成功
public static final int TYPE_SUCCESS = 0;
//表示下载失败
public static final int TYPE_FAILED = 1;
//表示暂停下载
public static final int TYPE_PAUSED = 2;
//表示取消下载
public static final int TYPE_CANCELED = 3;
private DownloadListener listener;
private boolean isCanceled = false;
private boolean isPaused = false;
private int lastProgress;
DownloadTask(DownloadListener listener){
this.listener = listener;
}
/**
* 这个方法用于在后台执行具体的下载逻辑
* @param strings
* @return
*/
@Override
protected Integer doInBackground(String... strings) {
InputStream is = null;
RandomAccessFile savedFile = null;
File file = null;
try{
long downloadLength = 0;//记录已下载的文件长度
String downloadUrl = strings[0];//根据参数获取到下载的URL地址
String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));//根据URL地址解析出下载的文件名
//指定将文件下载到SD卡的Download目录
String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
file = new File(directory + fileName);
//判断目录中是否已经存在要下载的文件了
if(file.exists()){
//已存在,读取已下载的字节数
downloadLength = file.length();
}
//调用getContentLength()方法来获取待下载的文件的总长度
long contentLength = getContentLength(downloadUrl);
//文件长度等于0则说明文件有问题
if(contentLength == 0 ){
return TYPE_FAILED;
//已下载字节和文件总字节相等,说明已经下载完成了
}else if(contentLength == downloadLength){
return TYPE_SUCCESS;
}
//使用OkHttp发送一条网络请求
//在请求中添加一个header,用于告诉服务器我们想要从哪个字节开始下