惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
P
Privacy & Cybersecurity Law Blog
P
Proofpoint News Feed
S
Schneier on Security
G
GRAHAM CLULEY
The Hacker News
The Hacker News
C
Cybersecurity and Infrastructure Security Agency CISA
Know Your Adversary
Know Your Adversary
C
Cyber Attacks, Cyber Crime and Cyber Security
爱范儿
爱范儿
M
MIT News - Artificial intelligence
V
Vulnerabilities – Threatpost
F
Fortinet All Blogs
月光博客
月光博客
Simon Willison's Weblog
Simon Willison's Weblog
罗磊的独立博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Hugging Face - Blog
Hugging Face - Blog
Spread Privacy
Spread Privacy
P
Proofpoint News Feed
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
Y
Y Combinator Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
T
Tor Project blog
T
Troy Hunt's Blog
Latest news
Latest news
N
Netflix TechBlog - Medium
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
Project Zero
Project Zero
N
News and Events Feed by Topic
F
Full Disclosure
酷 壳 – CoolShell
酷 壳 – CoolShell
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
CERT Recently Published Vulnerability Notes
H
Hacker News: Front Page
C
Cisco Blogs
I
Intezer
P
Privacy International News Feed
MongoDB | Blog
MongoDB | Blog
L
LINUX DO - 热门话题
Blog — PlanetScale
Blog — PlanetScale
Security Latest
Security Latest
Last Week in AI
Last Week in AI
Scott Helme
Scott Helme
B
Blog
博客园_首页
MyScale Blog
MyScale Blog
Cloudbric
Cloudbric

博客园 - mshwu

桥接模式(Bridge Pattern) 单例模式 工厂方法模式 命名空间的规划 Intent(二) Intent (一) Fragment (一) 2-1 Managing the Activity Lifecycle java1.5新特性(转) 1-4 Starting Another Activity 1-3 Building a Simple User Interface(创建简单的用户界面) 1-2 Android系统架构基本模式解析 1-1 Building Your First Android Application FTP Send File: Source Code Review(转) 动态操作文件 通用日志管理工具 触发器程序 通过CLP实现library之间的自动复制 (转) OVRDBF的用法
Download Manager
mshwu · 2013-09-09 · via 博客园 - mshwu

从Android 2.3(API level 9)开始Android用系统服务(Service)的方式提供了Download Manager来优化处理长时间的下载操作。Download Manager处理HTTP

连接并监控连接中的状态变化以及系统重启来确保每一个下载任务顺利完成。

在大多数涉及到下载的情况中使用Download Manager都是不错的选择,特别是当用户切换不同的应用以后下载需要在后台继续进行,以及对下载完成的处理相当重要的时候

相对比传统下载方式,Download Manager具有以下优点:

  • 采用service对下载处理做了很好的封装,同时封装了大部分异常处理,程序可专注于逻辑处理
  • 对于断点续传功能有很好的支持

例子:

下载文件,在这里返回的reference变量是系统为当前的下载请求分配的一个唯一的ID,我们可以通过这个ID重新获得这个下载任务,进行一些自己想要进行的操作或者查询

下载的状态以及取消下载等等。

我们可以通过addRequestHeader方法为DownloadManager.Request对象request添加HTTP头,也可以通过setMimeType方法重写从服务器返回的mime type。

我们还可以指定在什么连接状态下执行下载操作。setAllowedNetworkTypes方法可以用来限定在WiFi还是手机网络下进行下载,setAllowedOverRoaming方法

可以用来阻止手机在漫游状态下下载。

private void DownloadFile() {
 
    String serviceString = Context.DOWNLOAD_SERVICE;
    DownloadManager downloadManager;
    downloadManager = (DownloadManager)getSystemService(serviceString);
//创建下载请求    
     Uri uri = Uri.parse("http://developer.android.com/shareables/icon_templates-v4.0.zip");
    DownloadManager.Request request = new Request(uri);
//设置允许使用的网络类型,这里是移动网络和wifi都可以 
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE|DownloadManager.Request.NETWORK_WIFI); 
//将下载请求放入队列   
    long reference = downloadManager.enqueue(request);
    
    myDownloadReference = reference;
    Log.d(TAG, "Download Reference: " + reference);
  }

注册一个广播接受者来接收ACTION_DOWNLOAD_COMPLETE广播对下载完成的处理,

这个广播会包含一个EXTRA_DOWNLOAD_ID信息在intent中包含了已经完成的这个下载的ID,

query方法返回一个包含了下载任务细节的Cursor。

query方法传递一个DownloadManager.Query对象作为参数,通过DownloadManager.Query对象的setFilterById方法可以筛选我们希望查询的下

载任务的ID。也可以使用setFilterByStatus方法筛选我们希望查询的某一种状态的下载任务,传递的参数是DownloadManager.STATUS_*常量,可以指定

正在进行、暂停、失败、完成四种状态。

Download Manager包含了一系列COLUMN_*静态String常量,可以用来查询Cursor中的结果列索引。我们可以查询到下载任务的各种细节,包括状态,

文件大小,已经下载的字节数,标题,描述,URI,本地文件名和URI,媒体类型以及Media Provider download URI。

final DownloadManager  downloadManager = (DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
    
    /**
     * Listing 6-4: Monitoring downloads for completion 
     */

    IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
        
    BroadcastReceiver receiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
        long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
        if (myDownloadReference == reference) {
          
          Query myDownloadQuery = new Query();
          myDownloadQuery.setFilterById(reference);
          
          Cursor myDownload = downloadManager.query(myDownloadQuery);
          if (myDownload.moveToFirst()) {
            int fileNameIdx = 
              myDownload.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME);
            int fileUriIdx = 
              myDownload.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);

            String fileName = myDownload.getString(fileNameIdx);
            String fileUri = myDownload.getString(fileUriIdx);
        
            // TODO Do something with the file.
            Log.d(TAG, fileName + " : " + fileUri);
          }
          myDownload.close();

        }
      }
    };
        
    registerReceiver(receiver, filter);

注册一个BroadcastReceiver来监控处理ACTION_NOTIFICATION_CLICKED action:

private void notificationClick() {
  
    IntentFilter filter = new IntentFilter(DownloadManager.ACTION_NOTIFICATION_CLICKED);

    BroadcastReceiver receiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
        String extraID = DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS;
        long[] references = intent.getLongArrayExtra(extraID);
        for (long reference : references)
          if (reference == myDownloadReference) {
            // Do something with downloading file.
          }
      }
    };

    registerReceiver(receiver, filter);
  }
  
  private void listing607() {
    /**

默认情况下,所有通过Download Manager下载的文件都保存在一个共享下载缓存中,使用系统生成的文件名每一个Request对象都可以制定一个下载

保存的地址,通常情况下,所有的下载文件都应该保存在外部存储中,所以我们需要在应用清单文件中加上WRITE_EXTERNAL_STORAGE权限,

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

否则,会报错!

AndroidManifest.xml文件内容如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.paad.internet"
  android:versionCode="1"
  android:versionName="1.0" >
    
  <uses-permission android:name="android.permission.INTERNET"/>
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

  <application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
      android:name=".MyActivity"
      android:label="@string/app_name" >
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
  </application>

</manifest>

Download Manager Notifications样式定制

默认情况下,通知栏中会显示被Download Manager管理的每一个download每一个Notification会显示当前的下载进度和文件的名字,可以更改其样式,一些常用的接口如下所示,可基于自身的应用要求进行调整

禁止发出通知,既后台下载

         request.setShowRunningNotification(false); 

不显示下载界面

         request.setVisibleInDownloadsUi(false); 

设置下载后文件存放的位置

        request.setDestinationInExternalFilesDir(this,  Environment.DIRECTORY_DOWNLOADS, “Bugdroid.png”)

附上书上的一个Sample: download manage