android下载封装类Download,支持断点下载

2024-09-04 18:08

本文主要是介绍android下载封装类Download,支持断点下载,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

各种回调, 支持断点下载

Java代码   收藏代码
  1. public class Download implements Serializable {  
  2.     private static final int START = 1;                 // 开始下载  
  3.     private static final int PUBLISH = 2;               // 更新进度  
  4.     private static final int PAUSE = 3;                 // 暂停下载  
  5.     private static final int CANCEL = 4;                // 取消下载  
  6.     private static final int ERROR = 5;                 // 下载错误  
  7.     private static final int SUCCESS = 6;               // 下载成功  
  8.     private static final int GOON = 7;                  // 继续下载  
  9.         
  10.     private static ExecutorService mThreadPool;         // 线程池  
  11.         
  12.     static {  
  13.         mThreadPool = Executors.newFixedThreadPool(5);  // 默认5个   
  14.     }  
  15.             
  16.     private int mDownloadId;                            // 下载id  
  17.     private String mFileName;                           // 本地保存文件名  
  18.     private String mUrl;                                // 下载地址  
  19.     private String mLocalPath;                          // 本地存放目录  
  20.     
  21.     private boolean isPause = false;                    // 是否暂停  
  22.     private boolean isCanceled = false;                 // 是否手动停止下载  
  23.         
  24.     private OnDownloadListener mListener;               // 监听器  
  25.         
  26.     /** 
  27.      * 配置下载线程池的大小 
  28.      * @param maxSize 同时下载的最大线程数 
  29.      */  
  30.     public static void configDownloadTheadPool(int maxSize) {  
  31.         mThreadPool = Executors.newFixedThreadPool(maxSize);  
  32.     }  
  33.         
  34.     /** 
  35.      * 添加下载任务 
  36.      * @param downloadId 下载任务的id 
  37.      * @param url        下载地址 
  38.      * @param localPath   本地存放地址 
  39.      */  
  40.     public Download(int downloadId, String url, String localPath) {  
  41.         if (!new File(localPath).exists()) {  
  42.             new File(localPath).mkdirs();  
  43.         }  
  44.             
  45.         Log.log("下载地址;" + url);  
  46.             
  47.         mDownloadId = downloadId;  
  48.         mUrl = url;  
  49.         String[] tempArray = url.split("/");  
  50.         mFileName = tempArray[tempArray.length-1];  
  51.         mLocalPath = localPath;  
  52.     }  
  53.         
  54.     /** 
  55.      * 设置监听器 
  56.      * @param listener 设置下载监听器 
  57.      * @return this 
  58.      */  
  59.     public Download setOnDownloadListener(OnDownloadListener listener) {  
  60.         mListener = listener;  
  61.         return this;  
  62.     }  
  63.         
  64.     /** 
  65.      * 获取文件名 
  66.      * @return 文件名 
  67.      */  
  68.     public String getFileName() {  
  69.         return mFileName;  
  70.     }  
  71.     
  72.     /** 
  73.      * 开始下载 
  74.      * params isGoon是否为继续下载 
  75.      */  
  76.     public void start(final boolean isGoon) {  
  77.         // 处理消息  
  78.         final Handler handler = new Handler() {  
  79.             @Override  
  80.             public void handleMessage(Message msg) {  
  81.                 switch (msg.what) {  
  82.                 case ERROR:  
  83.                     mListener.onError(mDownloadId);  
  84.                     break;  
  85.                 case CANCEL:  
  86.                     mListener.onCancel(mDownloadId);  
  87.                     break;  
  88.                 case PAUSE:  
  89.                     mListener.onPause(mDownloadId);  
  90.                     break;  
  91.                 case PUBLISH:  
  92.                     mListener.onPublish(mDownloadId, Long.parseLong(msg.obj.toString()));  
  93.                     break;  
  94.                 case SUCCESS:  
  95.                     mListener.onSuccess(mDownloadId);  
  96.                     break;  
  97.                 case START:  
  98.                     mListener.onStart(mDownloadId, Long.parseLong(msg.obj.toString()));  
  99.                     break;  
  100.                 case GOON:  
  101.                     mListener.onGoon(mDownloadId, Long.parseLong(msg.obj.toString()));  
  102.                     break;  
  103.                 }  
  104.             }  
  105.         };  
  106.             
  107.         // 真正开始下载  
  108.         mThreadPool.execute(new Runnable() {  
  109.             @Override  
  110.             public void run() {  
  111.                 download(isGoon,handler);  
  112.             }  
  113.         });  
  114.     }  
  115.         
  116.     /** 
  117.      * 下载方法 
  118.      * @param handler 消息处理器 
  119.      */  
  120.     private void download(boolean isGoon, Handler handler) {  
  121.         Message msg = null;  
  122.         Log.log("开始下载。。。");  
  123.         try {  
  124.             RandomAccessFile localFile = new RandomAccessFile(new File(  
  125.                     mLocalPath + File.separator + mFileName), "rwd");  
  126.     
  127.             DefaultHttpClient client = new DefaultHttpClient();  
  128.             client.setParams(getHttpParams());  
  129.             HttpGet get = new HttpGet(mUrl);  
  130.     
  131.             long localFileLength = getLocalFileLength();  
  132.             final long remoteFileLength = getRemoteFileLength();  
  133.             long downloadedLength = localFileLength;  
  134.                 
  135.             // 远程文件不存在  
  136.             if (remoteFileLength == -1l) {  
  137.                 Log.log("下载文件不存在...");  
  138.                 localFile.close();  
  139.                 handler.sendEmptyMessage(ERROR);  
  140.                 return;  
  141.             }  
  142.     
  143.             // 本地文件存在  
  144.             if (localFileLength > -1l && localFileLength < remoteFileLength) {  
  145.                 Log.log("本地文件存在...");  
  146.                 localFile.seek(localFileLength);  
  147.                 get.addHeader("Range""bytes=" + localFileLength + "-"  
  148.                         + remoteFileLength);  
  149.             }  
  150.                 
  151.             msg = Message.obtain();  
  152.                 
  153.             // 如果不是继续下载  
  154.             if(!isGoon) {  
  155.                 // 发送开始下载的消息并获取文件大小的消息  
  156.                 msg.what = START;  
  157.                 msg.obj = remoteFileLength;  
  158.             }else {  
  159.                 msg.what = GOON;  
  160.                 msg.obj = localFileLength;  
  161.             }  
  162.                 
  163.             handler.sendMessage(msg);  
  164.                 
  165.             HttpResponse response = client.execute(get);  
  166.             int httpCode = response.getStatusLine().getStatusCode();  
  167.             if (httpCode >= 200 && httpCode <= 300) {  
  168.                 InputStream in = response.getEntity().getContent();  
  169.                 byte[] bytes = new byte[1024];  
  170.                 int len = -1;  
  171.                 while (-1 != (len = in.read(bytes))) {  
  172.                     localFile.write(bytes, 0, len);  
  173.                     downloadedLength += len;  
  174. //                  Log.log((int)(downloadedLength/(float)remoteFileLength * 100));  
  175.                     if ((int)(downloadedLength/(float)remoteFileLength * 100) % 10 == 0) {  
  176.                         // 发送更新进度的消息  
  177.                         msg = Message.obtain();  
  178.                         msg.what = PUBLISH;  
  179.                         msg.obj = downloadedLength;  
  180.                         handler.sendMessage(msg);  
  181. //                      Log.log(mDownloadId + "已下载" + downloadedLength);  
  182.                     }  
  183.                         
  184.                     // 暂停下载, 退出方法  
  185.                     if (isPause) {  
  186.                         // 发送暂停的消息  
  187.                         handler.sendEmptyMessage(PAUSE);  
  188.                         Log.log("下载暂停...");  
  189.                         break;  
  190.                     }  
  191.                         
  192.                     // 取消下载, 删除文件并退出方法  
  193.                     if (isCanceled) {  
  194.                         Log.log("手动关闭下载。。");  
  195.                         localFile.close();  
  196.                         client.getConnectionManager().shutdown();  
  197.                         new File(mLocalPath + File.separator + mFileName)  
  198.                                 .delete();  
  199.                         // 发送取消下载的消息  
  200.                         handler.sendEmptyMessage(CANCEL);  
  201.                         return;  
  202.                     }  
  203.                 }  
  204.     
  205.                 localFile.close();  
  206.                 client.getConnectionManager().shutdown();  
  207.                 // 发送下载完毕的消息  
  208.                 if(!isPause) handler.sendEmptyMessage(SUCCESS);  
  209.             }  
  210.     
  211.         } catch (Exception e) {  
  212.             // 发送下载错误的消息  
  213.             handler.sendEmptyMessage(ERROR);  
  214.         }  
  215.     }  
  216.     
  217.     /** 
  218.      * 暂停/继续下载 
  219.      * param pause 是否暂停下载 
  220.      * 暂停 return true 
  221.      * 继续 return false 
  222.      */  
  223.     public synchronized boolean pause(boolean pause) {  
  224.         if(!pause) {  
  225.             Log.log("继续下载");  
  226.             isPause = false;  
  227.             start(true); // 开始下载  
  228.         }else {  
  229.             Log.log("暂停下载");  
  230.             isPause = true;  
  231.         }  
  232.         return isPause;  
  233.     }  
  234.     
  235.     /** 
  236.      * 关闭下载, 会删除文件 
  237.      */  
  238.     public synchronized void cancel() {  
  239.         isCanceled = true;  
  240.         if(isPause) {  
  241.             new File(mLocalPath + File.separator + mFileName)  
  242.             .delete();  
  243.         }  
  244.     }  
  245.     
  246.     /** 
  247.      * 获取本地文件大小 
  248.      * @return 本地文件的大小 or 不存在返回-1 
  249.      */  
  250.     public synchronized long getLocalFileLength() {  
  251.         long size = -1l;  
  252.         File localFile = new File(mLocalPath + File.separator + mFileName);  
  253.         if (localFile.exists()) {  
  254.             size = localFile.length();  
  255.         }  
  256.         Log.log("本地文件大小" + size);  
  257.         return size <= 0 ? -1l : size;  
  258.     }  
  259.     
  260.     /** 
  261.      * 获取远程文件打下 or 不存在返回-1 
  262.      * @return 
  263.      */  
  264.     public synchronized long getRemoteFileLength() {  
  265.         long size = -1l;  
  266.         try {  
  267.             DefaultHttpClient client = new DefaultHttpClient();  
  268.             client.setParams(getHttpParams());  
  269.             HttpGet get = new HttpGet(mUrl);  
  270.     
  271.             HttpResponse response = client.execute(get);  
  272.             int httpCode = response.getStatusLine().getStatusCode();  
  273.             if (httpCode >= 200 && httpCode <= 300) {  
  274.                 size = response.getEntity().getContentLength();  
  275.             }  
  276.     
  277.             client.getConnectionManager().shutdown();  
  278.         } catch (Exception e) {  
  279.             e.printStackTrace();  
  280.         }  
  281.     
  282.         Log.log("远程文件大小" + size);  
  283.         return size;  
  284.     }  
  285.     
  286.     /** 
  287.      * 设置http参数 不能设置soTimeout 
  288.      * @return HttpParams http参数 
  289.      */  
  290.     private static HttpParams getHttpParams() {  
  291.         HttpParams params = new BasicHttpParams();  
  292.     
  293.         HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);  
  294.         HttpProtocolParams.setUseExpectContinue(params, true);  
  295.         HttpProtocolParams  
  296.                 .setUserAgent(  
  297.                         params,  
  298.                         "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2041.4 Safari/537.36");  
  299.         ConnManagerParams.setTimeout(params, 4000);  
  300.         HttpConnectionParams.setConnectionTimeout(params, 4000);  
  301.             
  302.         return params;  
  303.     }  
  304.         
  305.     /** 
  306.      * 关闭下载线程池 
  307.      */  
  308.     public static void closeDownloadThread() {  
  309.         if(null != mThreadPool) {  
  310.             mThreadPool.shutdownNow();  
  311.         }  
  312.     }  
  313.     
  314.     public interface OnDownloadListener {  
  315.         public void onStart(int downloadId, long fileSize);  // 回调开始下载  
  316.         public void onPublish(int downloadId, long size);    // 回调更新进度  
  317.         public void onSuccess(int downloadId);               // 回调下载成功  
  318.         public void onPause(int downloadId);                 // 回调暂停  
  319.         public void onError(int downloadId);                 // 回调下载出错  
  320.         public void onCancel(int downloadId);                // 回调取消下载  
  321.         public void onGoon(int downloadId, long localSize);  // 回调继续下载  
  322.     }  





调用,如下:
Java代码   收藏代码
  1. Download d = new Download(1"http://baidu.com/test.zip","/sdcard/download/");  
  2.             d.setOnDownloadListener(new Download.OnDownloadListener() {  
  3.                 @Override  
  4.                 public void onSuccess(int downloadId) {  
  5.                     System.out.println(downloadId + "下载成功");  
  6.                 }  
  7.         
  8.                 @Override  
  9.                 public void onStart(int downloadId, long fileSize) {  
  10.                     System.out.println(downloadId + "开始下载,文件大小:" + fileSize);  
  11.                 }  
  12.         
  13.                 @Override  
  14.                 public void onPublish(int downloadId, long size) {  
  15.                     System.out.println("更新文件" + downloadId + "大小:" + size);  
  16.                 }  
  17.         
  18.                 @Override  
  19.                 public void onPause(int downloadId) {  
  20.                     System.out.println("暂停下载" + downloadId);  
  21.                 }  
  22.         
  23.                 @Override  
  24.                 public void onGoon(int downloadId, long localSize) {  
  25.                     System.out.println("继续下载" + downloadId);  
  26.                 }  
  27.         
  28.                 @Override  
  29.                 public void onError(int downloadId) {  
  30.                     System.out.println("下载出错" + downloadId);  
  31.                 }  
  32.         
  33.                 @Override  
  34.                 public void onCancel(int downloadId) {  
  35.                     System.out.println("取消下载" + downloadId);  
  36.                 }  
  37.             });  
  38.         
  39.             d.start(false);  


原址
http://www.oschina.net/code/snippet_1021353_38517#57000

这篇关于android下载封装类Download,支持断点下载的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1136653

相关文章

Android实现两台手机屏幕共享和远程控制功能

《Android实现两台手机屏幕共享和远程控制功能》在远程协助、在线教学、技术支持等多种场景下,实时获得另一部移动设备的屏幕画面,并对其进行操作,具有极高的应用价值,本项目旨在实现两台Android手... 目录一、项目概述二、相关知识2.1 MediaProjection API2.2 Socket 网络

Android实现悬浮按钮功能

《Android实现悬浮按钮功能》在很多场景中,我们希望在应用或系统任意界面上都能看到一个小的“悬浮按钮”(FloatingButton),用来快速启动工具、展示未读信息或快捷操作,所以本文给大家介绍... 目录一、项目概述二、相关技术知识三、实现思路四、整合代码4.1 Java 代码(MainActivi

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

前端下载文件时如何后端返回的文件流一些常见方法

《前端下载文件时如何后端返回的文件流一些常见方法》:本文主要介绍前端下载文件时如何后端返回的文件流一些常见方法,包括使用Blob和URL.createObjectURL创建下载链接,以及处理带有C... 目录1. 使用 Blob 和 URL.createObjectURL 创建下载链接例子:使用 Blob

Android实现打开本地pdf文件的两种方式

《Android实现打开本地pdf文件的两种方式》在现代应用中,PDF格式因其跨平台、稳定性好、展示内容一致等特点,在Android平台上,如何高效地打开本地PDF文件,不仅关系到用户体验,也直接影响... 目录一、项目概述二、相关知识2.1 PDF文件基本概述2.2 android 文件访问与存储权限2.

Android Studio 配置国内镜像源的实现步骤

《AndroidStudio配置国内镜像源的实现步骤》本文主要介绍了AndroidStudio配置国内镜像源的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、修改 hosts,解决 SDK 下载失败的问题二、修改 gradle 地址,解决 gradle

鸿蒙中Axios数据请求的封装和配置方法

《鸿蒙中Axios数据请求的封装和配置方法》:本文主要介绍鸿蒙中Axios数据请求的封装和配置方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.配置权限 应用级权限和系统级权限2.配置网络请求的代码3.下载在Entry中 下载AxIOS4.封装Htt

在Android平台上实现消息推送功能

《在Android平台上实现消息推送功能》随着移动互联网应用的飞速发展,消息推送已成为移动应用中不可或缺的功能,在Android平台上,实现消息推送涉及到服务端的消息发送、客户端的消息接收、通知渠道(... 目录一、项目概述二、相关知识介绍2.1 消息推送的基本原理2.2 Firebase Cloud Me

Android中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(