Android笔记--断点续传

          断点续传就是在下载资源过程中,网络出现中断后,下一次下载的时候能够接着上一次下载的地方继续下载,以达到节省流量及时间的效果。在Http1.1协议中默认支持获取文件的部分内容,这其中主要是通过头部的两个参数:Range和Content Range来实现的。客户端发请求时对应的是Range,服务器端响应时对应的是 Content-Range。

 栗子如下:

@Entity(tableName = "BreakPointFileTable")
public class BreakPointFileTable {
    @PrimaryKey(autoGenerate = true)
    public long id;
    public String fileName;
    public String fileDownloadUrl;
    public String fileSavePath;
    public long fileLength;
    public long startDownloadProgress;
    public long currentDownloadProgress;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getFileDownloadUrl() {
        return fileDownloadUrl;
    }

    public void setFileDownloadUrl(String fileDownloadUrl) {
        this.fileDownloadUrl = fileDownloadUrl;
    }

    public String getFileSavePath() {
        return fileSavePath;
    }

    public void setFileSavePath(String fileSavePath) {
        this.fileSavePath = fileSavePath;
    }

    public long getFileLength() {
        return fileLength;
    }

    public void setFileLength(long fileLength) {
        this.fileLength = fileLength;
    }

    public long getStartDownloadProgress() {
        return startDownloadProgress;
    }

    public void setStartDownloadProgress(long startDownloadProgress) {
        this.startDownloadProgress = startDownloadProgress;
    }

    public long getCurrentDownloadProgress() {
        return currentDownloadProgress;
    }

    public void setCurrentDownloadProgress(long currentDownloadProgress) {
        this.currentDownloadProgress = currentDownloadProgress;
    }

 
}
 public void download(final String url, final String fileName, final OnDownloadListener listener) {
        RandomAccessFile finalRandomFile = null;
        long downLoadFileLength = 0;
        long start = 0;
        File dir = createDir(FileTypeUtils.getFileType(fileName),getFileName(fileName));
        String name = fileName;
        File file = new File(dir, name);
        try {
            boolean fileDownloadExits = BreakPointDataBase.getDataBase().getResumeBreakPointDao().isFileDownloadExits(fileName);
            if (fileDownloadExits) {
                try {
                    finalRandomFile = new RandomAccessFile(file, "rwd");
                    List<BreakPointFileTable> allDownloadFileList = BreakPointDataBase.getDataBase().getResumeBreakPointDao().getDownloadFileByName(fileName);
                    if(allDownloadFileList.size()>0) {
                        start = allDownloadFileList.get(0).getStartDownloadProgress() + allDownloadFileList.get(0).getCurrentDownloadProgress();
                        downLoadFileLength = allDownloadFileList.get(0).getFileLength();
                        finalRandomFile.seek(start);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            } else {
                file.createNewFile();
                finalRandomFile = new RandomAccessFile(file, "rwd");
                finalRandomFile.seek(0);
                BreakPointFileTable breakPointFileTable = new BreakPointFileTable();
                breakPointFileTable.setFileName(file.getName());
                breakPointFileTable.setFileDownloadUrl(url);
                breakPointFileTable.setStartDownloadProgress(0);
                breakPointFileTable.setCurrentDownloadProgress(0);
                breakPointFileTable.setFileSavePath(file.getPath());
                BreakPointDataBase.getDataBase().getResumeBreakPointDao().insertDownloadFileInfo(breakPointFileTable);
            }
            Request.Builder builder = new okhttp3.Request.Builder();
            builder.addHeader("Authorization", "Basic " + com.decard.utils.Base64Util.encode(String.format("%s:%s", userName, password).getBytes()));
            if(start > 0 && downLoadFileLength > 0) {
                // 断点续传关键
                builder.addHeader("RANGE", "bytes=" + start + "-" + downLoadFileLength);
            }
            RandomAccessFile fileOperator = finalRandomFile;
            okhttp3.Request request = builder.url(url).build();
            call = okHttpClient.newCall(request);
            long finalStart = start;
            long finalDownLoadFileLength = downLoadFileLength;
            call.enqueue(new okhttp3.Callback() {
                long tempCurrentProgress = 0;
                long  tempFileLength = 0;

                @Override
                public void onFailure(okhttp3.Call call, java.io.IOException e) {
                    listener.onDownloadFailed();
                }
                @Override
                public void onResponse(okhttp3.Call call, okhttp3.Response response) throws java.io.IOException {
                    java.io.InputStream is = null;
                    byte[] buf = new byte[1024*5];
                    int len = 0;
                    java.io.FileOutputStream fos = null;
                    try {
                        // 下载中处理
                        // 下载完成
                        BreakPointDataBase.getDataBase().getResumeBreakPointDao().deleteBreakPointFileInfo(
                                BreakPointDataBase.getDataBase().getResumeBreakPointDao().getAllDownloadFileList());
                        listener.onDownloadSuccess(file);
                    } catch (Exception e) {
                        // 网络异常 更新数据库
                        BreakPointDataBase.getDataBase().getResumeBreakPointDao()
                                .updateDownloadFileProgress(url, tempCurrentProgress, tempFileLength);
                        e.printStackTrace();
                        listener.onDownloadFailed();
                    } finally {
                       ...
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

注意: 在断点续传中 第一次能够获取文件总长度,续传过程中 获取的是文件部分长度,所以在计算进度时需要注意。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值