Android下载管理器DownloadManager

打印 上一主题 下一主题

主题 455|帖子 455|积分 1365

目次
一、构建下载请求-Request
二、举行下载操作-DownloadManager
三、查询下载进度-Query
四、事件广播监听
1.下载完成事件
2.下载举行时的通知栏点击事件
3.下载完成后的通知栏点击事件
五、停息、继承下载
六、根本使用案例代码

Android 从 2.3 (API9) 开始提供了专门的下载工具DownloadManager(下载管理器)统一管理下载操作。
下载管理器DownloadManager的对象从系统服务DOWNLOAD_SERVICE中获取,详细使用过程分为3步:构建下载请求(Request)、举行下载操作(DownloadManager)和查询下载进度(Query)。
一、构建下载请求-Request

要想使用下载功能,首先得构建一个下载请求(DownloadManager.Request),说明从那里下载、下载参数是什么、下载的文件生存到那里等。这个下载请求就是DownloadManager的内部类Request。以下是该类的常用方法:


  • DownloadManager构造函数:指定从哪个网络地址下载文件。
  • setAllowedNetworkTypes:指定答应下载的网络范例。若同时答应多种网络范例,则可使用竖线“|”把多种网络范例拼接起来。取值为:

  • DownloadManager.Request.NETWORK_WIFI WiFi 网络
  • DownloadManager.Request.NETWORK_MOBILE 移动网络(手机的数据连接)


  • setDestinationInExternalFilesDir:设置下载文件的生存路径(存于程序私有文件夹)。
  • setDestinationInExternalPublicDir:设置下载文件的生存路径(存于公共文件夹)。第一个参数为目次范例(主文件夹);第二个参数为主文件夹下的部分文件路径,为仅文件名时不加后缀名,为路径时需加后缀名;另外,如果指定目次已存在同名文件,系统就会将新下载的文件重命名,即在文件名末尾添加“-1” “-2”之类的序号。目次范例(主文件夹)取值如下:

  • Environment.DIRECTORY_PICTURES
  • Environment.DIRECTORY_DCIM
  • Environment.DIRECTORY_MUSIC
  • Environment.DIRECTORY_DOWNLOADS
  • Environment.DIRECTORY_SCREENSHORT


  • addRequestHeader:给 HTTP 请求添加头部参数。如断点续传的Range字头,根据已有字节数续接。
  • setMimeType:设置下载文件的媒体范例。一样平常无须设置,默认是服务器返回的媒体范例。参数为String型,如"text/html",HTML格式;"text/pain",纯文本格式;"image/jpeg",jpg图片格式。
  • setTitle:设置通知栏上的消息标题。如果不设置,默认标题就是下载的文件名。
  • setDescription:设置通知栏上的消息描述。如果不设置,默认显示系统估算的下载剩余时间。
  • setVisibleInDownloadsUi:设置是否显示在系统的下载页面上。
  • setNotificationVisibility: 设置通知栏的下载任务可见范例。取值如下:

  • DownloadManager.Request.VISIBILITY_HIDDEN   埋伏
  • DownloadManager.Request.VISIBILITY_VISIBLE   下载时可见(下载完成后消散)
  • DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED   下载举行时与完成后都可见
  • DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION   只有下载完成后可见
二、举行下载操作-DownloadManager

构建完下载请求才气举行下载的相干操作。以下是DownloadManager的常用方法:


  • enqueue:将下载请求参加任务队列中,排队等待下载。该方法返回本次下载任务的编号
  • remove:取消指定编号的下载任务。
  • openDownloadedFile:打开下载完成的文件。
  • getMimeTypeForDownloadedFile:获取下载完成文件的媒体范例。
  • query:根据查询请求获取符合条件的结果集游标Curosr。
三、查询下载进度-Query

固然下载进度可在通知栏上查看,但是如果App自身也想了解当前的下载进度,就要调用下载管理器的query方法。该方法的输入参数是一个Query对象,返回结果集的Cursor对象,这里的Cursor用法与SQLite中的Cursor 一样。
以下是Query类的常用方法说明:


  • setFilterByld:根据编号过滤下载任务。
  • setFilterByStatus:根据状态过滤下载任务。
设置完查询请求,即可调用 DownloadManager 对象的query方法,获得结果集的游标对象Cusor。该游标中包罗下载任务的完整字段信息,主要下载字段的取值如下:

  • DownloadManager.COLUMN_LOCAL_FILENAME   下载文件的本地生存路径
  • DownloadManager.COLUMN_MEDIA_TYPE   下载文件的媒体范例
  • DownloadManager.COLUMN_TOTAL_SIZE_BYTES   下载文件的总大小
  • DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR   已下载的文件大小
  • DownloadManager.COLUMN_STATUS   下载状态
下载状态的取值说明:

  • STATUS_PENDING   挂起,即正在等待
  • STATUS_RUNNING   运行中
  • STATUS_PAUSED   停息
  • STATUS_SUCCESSFUL   乐成
  • STATUS_FAILED   失败
  1. //方法总结
  2. //创建下载请求
  3. DownloadManager.Request request=new DownloadManager.Request(Uri.parse(urlString));
  4. //设置允许下载的网络类型
  5. request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI|DownloadManager.Request.NETWORK_MOBILE);
  6. //设置保存文件地址
  7. //公共文件夹-第一个参数为文件夹类型-第二个参数为主文件夹下的部分文件路径,为仅文件名时不加后缀名,为路径时需加后缀名
  8. request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,"MyDownloadManagerTest/myTestDownload.png");
  9. //app私有文件夹
  10. //request.setDestinationInExternalFilesDir(MainActivity.this, Environment.DIRECTORY_DOWNLOADS,"myTestDownload");
  11. //添加HTTP请求头参数,如断点续接Range字段(使用已有字节数续接)
  12. //request.addRequestHeader("Range", "bytes=" + downloadedBytes + "-");
  13. //设置下载文件的媒体类型,一般无需设置,默认服务器返回的媒体类型
  14. //request.setMimeType("image/jpeg");
  15. //设置通知栏标题,无设置默认下载的文件名
  16. request.setTitle("DownloadManager下载测试");
  17. //设置通知栏内容,无设置默认估算剩余时间
  18. //request.setDescription("通知栏内容");
  19. //设置是否显示在系统的下载页面上
  20. request.setVisibleInDownloadsUi(true);
  21. //设置通知栏显示类型
  22. request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
  23. //获取下载管理器
  24. DownloadManager downloadManager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
  25. //下载
  26. //将下载请求添加到任务队列
  27. long downloadId=downloadManager.enqueue(request);
  28. //取消下载
  29. downloadManager.remove(downloadId);
  30. //获取下载完成文件的媒体类型
  31. String fileString=downloadManager.getMimeTypeForDownloadedFile(downloadId);
  32. //查询下载情况
  33. //获取Query
  34. DownloadManager.Query query=new DownloadManager.Query();
  35. //根据下载ID过滤
  36. query.setFilterById(downloadId);
  37. //根据下载状态过滤
  38. query.setFilterByStatus(DownloadManager.STATUS_RUNNING);
  39. //查询-Cursor的使用方法与SEQLite一致
  40. Cursor cursor=downloadManager.query(query);
复制代码
四、事件广播监听

系统的下载服务还提供3种下载事件,开辟者可通过注册广播接收者监听对应的广播消息举行相应的处理。3种下载事件说明如下:
1.下载完成事件

在下载完成时,系统会发着名为 DownloadManager.ACTION_DOWNLOAD_COMPLETE(值为字符串 android.intent.action.DOWNLOAD_COMPLETE)的广播,因此可注册一个该广播的接收器,用来判断当前任务是否已下载完毕,并举行后续的业务处理。
2.下载举行时的通知栏点击事件

在下载过程中,只要用户点击通知栏上的下载任务,系统就会发出行为名称是DownloadManager.ACTION_NOTIFICATION_CLICKED(值为字符串 androidintent.action.DOWNLOAD_NOTIFICATION_CLICKED)的广播,可注册该广播的接收器举行相干处理,比如跳转到该任务的下载进度页面等。
3.下载完成后的通知栏点击事件

下载完成后点击触发的是系统的 Intent.ACION_VIEW(浏览行为)。对于浏览行为,系统会根据媒体范例主动探求对应App打开。因此,如果开辟者要控制此时的点击行为,可以调用Request对象的setMimeType方法设置媒体范例,这样 Android 就会按照这个范例打开相应的 APP
  1. public class MyReceiver extends BroadcastReceiver {
  2.     public void onReceive(Context context, Intent intent) {
  3.         //获取活动
  4.         String action=intent.getAction();
  5.         //下载完成触发广播
  6.         if(action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)){
  7.             //获取下载编号
  8.             //getLongExtra第二个参数为默认值
  9.             long downloadId=intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1);
  10.         }
  11.         //点击通知(未下载完)触发通知
  12.         else if(action.equals(DownloadManager.ACTION_NOTIFICATION_CLICKED)){
  13.             //获取全部下载编号
  14.             long[] downloadIds=intent.getLongArrayExtra(DownloadManager.EXTRA_DOWNLOAD_ID);
  15.             //检查是否是本应用下载的
  16.             for(long downloadId:downloadIds){
  17.                 //... ...
  18.             }
  19.         }
  20.         //点击通知(下载完)触发通知
  21.         else if (action.equals(Intent.ACTION_VIEW)) {
  22.             //获取下载编号
  23.             long downloadId=intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID,-1);
  24.         }
  25.     }
  26. }
复制代码
五、停息、继承下载

DownloadManager类不提供直接的停息下载的方式。它只提供了启动下载和取消下载的方法。
如果想要实现下载的停息功能,可以使用DownloadManager提供的remove()方法取消下载任务。然后,可以记录已下载的字节数和文件URL等信息,以便稍后重新启动下载时可以通过设置HTTP字头的Range字段恢复下载进度。
必要注意的是,为了支持断点续传,服务器必须能够处理并精确响应Range字段,返回适当范围的数据。同时,如果服务器不支持断点续传或不满足范围请求,它可能会忽略Range字段并返回完整的文件。因此,断点续传的乐成与否也取决于服务器的支持
  1. private long downloadId; // 用于记录下载任务的ID
  2. private boolean isPaused = false; // 标记下载是否被暂停
  3. /**
  4. * 第一次下载时参数使用0
  5. */
  6. private void startDownload(int downloadedBytes) {
  7.     // 创建下载请求
  8.     DownloadManager.Request request = new DownloadManager.Request(Uri.parse(urlString));
  9.     // 根据已下载的字节数设置请求头Range字段,以实现断点续传功能
  10.     request.addRequestHeader("Range", "bytes=" + downloadedBytes + "-");
  11.     // 其他设置...
  12.     // 获取下载管理器
  13.     DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
  14.     // 下载执行
  15.     downloadId = downloadManager.enqueue(request);
  16. }
  17. private void pauseDownload() {
  18.     // 取消下载任务
  19.     DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
  20.     downloadManager.remove(downloadId);
  21.     // 记录已下载的字节数()
  22.     long downloadedBytes = getDownloadedBytes(downloadId);
  23.     // 保存已下载的字节数及其他信息至本地,以便稍后恢复下载
  24.     isPaused = true;
  25. }
  26. private void resumeDownload() {
  27.     // 恢复下载,重新发起下载请求
  28.     isPaused = false;
  29.     // 从本地获取已下载的字节数及其他信息
  30.     // long downloadedBytes = getSavedDownloadedBytes();
  31.     startDownload(dowbloadedBytes);
  32. }
  33. private int getDownloadedBytes(downloadId){
  34.     int retI=0;
  35.     //获取Query
  36.     DownloadManager.Query query=new DownloadManager.Query();
  37.     //根据下载ID过滤
  38.     query.setFilterById(downloadId);
  39.    
  40.     // 获取下载管理器
  41.     DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
  42.    
  43.     //查询-Cursor的使用方法与SEQLite一致
  44.     Cursor cursor=downloadManager.query(query);
  45.     if(cursor.getCount()>0){
  46.         cursor.moveToNext();
  47.         retI=cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
  48.     }
  49.     return retI;
  50. }
复制代码
六、根本使用案例代码

  1. public class MainActivity extends AppCompatActivity {
  2.     private String urlString="https://bkimg.cdn.bcebos.com/pic/00e93901213fb80ee7dc88b530d12f2eb9389447?x-bce-process=image/resize,m_lfit,w_536,limit_1/quality,Q_70";
  3.     private URL url=null;
  4.     protected void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);
  6.         setContentView(R.layout.activity_main);
  7.         //获取控件
  8.         Button button=findViewById(R.id.button);
  9.         //获取URL
  10.         try {
  11.             url=new URL(urlString);
  12.         } catch (MalformedURLException e) {
  13.             throw new RuntimeException(e);
  14.         }
  15.         //添加监听器
  16.         button.setOnClickListener(new View.OnClickListener() {
  17.             public void onClick(View view) {
  18.                 if(!getNetworkState(MainActivity.this)){
  19.                     Toast.makeText(MainActivity.this,"无网络",Toast.LENGTH_SHORT).show();
  20.                     return;
  21.                 }
  22.                 Toast.makeText(MainActivity.this,"开始下载",Toast.LENGTH_SHORT).show();
  23.                 startDownload();
  24.             }
  25.         });
  26.     }
  27.     /**
  28.      * 获取网络状态
  29.      * @param context
  30.      * @return true连接 false未连接
  31.      */
  32.     private boolean getNetworkState(Context context){
  33.         ConnectivityManager cm= (ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
  34.         NetworkInfo networkInfo=cm.getActiveNetworkInfo();
  35.         if(networkInfo==null){
  36.             return false;
  37.         }
  38.         return true;
  39.     }
  40.     /**
  41.      * 开始下载-DownloadManager
  42.      */
  43.     private void startDownload(){
  44.         //创建下载请求
  45.         DownloadManager.Request request=new DownloadManager.Request(Uri.parse(urlString));                        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI|DownloadManager.Request.NETWORK_MOBILE);
  46.         request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,"myTestDownload");
  47.         request.setTitle("DownloadManager下载测试");
  48.         request.setVisibleInDownloadsUi(false);
  49.         request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
  50.         //获取下载管理器
  51.         DownloadManager downloadManager= (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
  52.         //将下载请求添加到任务对列
  53.         long downloadId=downloadManager.enqueue(request);
  54.     }
  55. }
复制代码

tag:生存文件;网络下载;存储;生存;下载;内存;路径

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连密封材料

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表