安卓中大文件的加载需要用到断点续传,正好用到,翻出老代码稍改。。。。。。
一、涉及到的技术点
1.1 okHttp 的header
注:downloadLength 之前下载的长度
Request request = new Request.Builder().url(url).addHeader("RANGE", "bytes=" + downloadLength + "-").build();
1.2 文件过滤之前下载的
if(file.exists()){
downloadLength=file.length();
}else{
String tags=file.getParent();
MyFileUtil.createFile(file);
}
savedFile = new RandomAccessFile(file, "rw");
savedFile.seek(downloadLength);//跳过已经下载的字节
1.3 okhttp下载
二、核心代码
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.List;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
/**
* Created by biyunlong on 2018/4/19.
*/
public class DownLoadUtils {
private int oldProgress;
private static DownLoadUtils downloadUtil;
private final OkHttpClient okHttpClient;
private boolean isPaused = false;
private long downloadLength=0;
private RandomAccessFile savedFile = null;
public static DownLoadUtils getInstance() {
if (downloadUtil == null) {
downloadUtil = new DownLoadUtils();
}
return downloadUtil;
}
private DownLoadUtils() {
okHttpClient = new OkHttpClient();
}
public void download(final String url, final File file,final OnDownloadListener listener) {
initFile(file);
Request request = new Request.Builder().url(url).addHeader("RANGE", "bytes=" + downloadLength + "-").build();
okHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
// 下载失败
listener.onDownloadFailed();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream is = null;
byte[] buf = new byte[2048];
int len ;
try {
is = response.body().byteStream();
long total =getContentLength(url);
if(downloadLength>=total){
listener.onDownloadSuccess(file);
return;
}
long sum = 0;
while ((len = is.read(buf)) != -1) {
if (isPaused) {
return;
}
sum += len;
savedFile.write(buf, 0, len);
int progress = (int) ((sum * 1.0f + downloadLength) * 100 / total);
if (progress > oldProgress) {
// 下载中
listener.onDownloading(progress);
oldProgress = progress;
}
if(progress>=100){
// 下载完成
listener.onDownloadSuccess(file);
return;
}
}
} catch (Exception e) {
listener.onDownloadFailed();
} finally {
try {
if (savedFile != null) {
savedFile.close();
}
if (is != null) is.close();
} catch (IOException e) {
listener.onDownloadFailed();
}
}
}
});
}
/**
* @param url
* @return 从下载连接中解析出文件名
*/
private String getNameFromUrl(String url) {
return url.substring(url.lastIndexOf("/") + 1);
}
private void initFile( final File file){
isPaused = false;
oldProgress = 0;
savedFile = null;
if(file.exists()){
downloadLength=file.length();
}else{
String tags=file.getParent();
MyFileUtil.createFile(file);
}
String tag=file.getParent();
List<String>list=MyFileUtil.getFileName(file.getParent());
for(int i=0;i<list.size();i++){
if(!list.get(i).equals(file.getAbsolutePath())){
File df=new File(list.get(i));
df.delete();
}
}
try {
savedFile = new RandomAccessFile(file, "rw");
savedFile.seek(downloadLength);//跳过已经下载的字节
} catch (IOException e) {
e.printStackTrace();
}
}
public void stopDownload() {
isPaused = true;
}
/**
* 得到下载内容的大小
* @param downloadUrl
* @return
*/
private long getContentLength(String downloadUrl){
OkHttpClient client=new OkHttpClient();
Request request=new Request.Builder().url(downloadUrl).build();
try {
Response response=client.newCall(request).execute();
if(response!=null&&response.isSuccessful()){
long contentLength=response.body().contentLength();
response.body().close();
return contentLength;
}
} catch (IOException e) {
e.printStackTrace();
}
return 0;
}
public interface OnDownloadListener {
/**
* 下载成功
*/
void onDownloadSuccess(File str);
/**
* @param progress 下载进度
*/
void onDownloading(int progress);
/**
* 下载失败
*/
void onDownloadFailed();
}
}