Android系統下載管理DownloadManager功能介紹及使用樣本

來源:互聯網
上載者:User

標籤:

http://www.trinea.cn/android/android-downloadmanager/

本文主要結合源碼介紹Android系統下載管理DownloadManager的強大功能及使用
這是許久來準備寫的一系列部落格,這篇主要介紹DownloadManager的功能和樣本,後面還有兩篇會介紹下載管理的底層設計(DownloadProvider、DownloadManager、DownloadManagerUI)、下載管理如何進行功能增強和bug修改。

 

樣本APK可從這些地址下載:Google Play,  360手機小幫手,  百度手機小幫手,  小米市集,  豌豆莢

可運行代碼地址可見DownloadManager Demo,如下:

關於下載管理的廢話 

 

一、DownloadManager簡單介紹
DownloadManager是系統開放給第三方應用使用的類,包含兩個靜態內部類DownloadManager.Query和DownloadManager.Request。DownloadManager.Request用來請求一個下載,DownloadManager.Query用來查詢下載資訊,這兩個類的具體功能會在後面穿插介紹。DownloadManager的源碼可見[email protected]。

 

DownloadManager主要提供了下面幾個介面:
public long enqueue(Request request)執行下載,返回downloadId,downloadId可用於後面查詢下載資訊。若網路不滿足條件、Sdcard掛載中、超過最大並發數等異常會等待下載,正常則直接下載。
public int remove(long… ids)刪除下載,若下載中取消下載。會同時刪除下載檔案和記錄。
public Cursor query(Query query)查詢下載資訊。

 

public static Long getRecommendedMaxBytesOverMobile(Context context通過移動網路下載的最大位元組數
public String getMimeTypeForDownloadedFile(long id)得到下載的mimeType,如何設定後面會進行介紹

 

其它:通過查看代碼我們可以發現還有個CursorTranslator私人靜態內部類。這個類主要對Query做了一層代理。將DownloadProvider和DownloadManager之間做個映射。將DownloadProvider中的十幾種狀態對應到了DownloadManager中的五種狀態,DownloadProvider中的失敗、暫停原因轉換為了DownloadManager的原因。

 

二、下載管理樣本
下面具體介紹利用DownloadManager進行下載。
1、AndroidManifest中添加許可權

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

網路存取權限是必須的,為sdcard的話需要添加sdcard寫入權限。

 

2、調用DownloadManager.Request開始下載

 Java 
1234567891011 DownloadManager downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);String apkUrl = "http://img.meilishuo.net/css/images/AndroidShare/Meilishuo_3.6.1_10006.apk";DownloadManager.Request request = new DownloadManager.Request(Uri.parse(apkUrl));request.setDestinationInExternalPublicDir("Trinea", "MeiLiShuo.apk");// request.setTitle("MeiLiShuo");// request.setDescription("MeiLiShuo desc");// request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);// request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);// request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);// request.setMimeType("application/cn.trinea.download.file");long downloadId = downloadManager.enqueue(request);

上面調用downloadManager的enqueue介面進行下載,返回唯一的downloadId。

 

DownloadManager.Request除了建構函式的Uri必須外,其他設定都為可選設定。下面逐個介紹下:
request.setDestinationInExternalPublicDir(“Trinea”, “MeiLiShuo.apk”);表示設定為sd卡的Trinea檔案夾,檔案名稱為MeiLiShuo.apk。

setDestinationInExternalPublicDir源碼 

從源碼中我們可以看出下載完整目錄為Environment.getExternalStoragePublicDirectory(dirType)。不過file是通過file.mkdir()建立的,這樣如果上級目錄不存在就會建立檔案夾異常。所以下載前我們最好自己調用File的mkdirs方法遞迴建立子目錄,如下:

 Java 
12 File folder = new File(folderName);return (folder.exists() && folder.isDirectory()) ? true : folder.mkdirs();

否則,會報異常

 
12 java.lang.IllegalStateException: Unable to create directory: /storage/sdcard0/Trinea/aaat android.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java)

其他設定下載路徑介面為setDestinationUri,setDestinationInExternalFilesDir,setDestinationToSystemCache。其中setDestinationToSystemCache僅限系統app使用。

 

request.allowScanningByMediaScanner();表示允許MediaScanner掃描到這個檔案,預設不允許。

request.setTitle(“MeiLiShuo”);設定下載中通知欄提示的標題
request.setDescription(“MeiLiShuo desc”);設定下載中通知欄提示的介紹
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
表示下載進行中和下載完成的通知欄是否顯示。預設只顯示下載中通知。VISIBILITY_VISIBLE_NOTIFY_COMPLETED表示下載完成後顯示通知欄提示。VISIBILITY_HIDDEN表示不顯示任何通知欄提示,這個需要在AndroidMainfest中添加許可權android.permission.DOWNLOAD_WITHOUT_NOTIFICATION.

 

request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
表示下載允許的網路類型,預設在任何網路下都允許下載。有NETWORK_MOBILE、NETWORK_WIFI、NETWORK_BLUETOOTH三種及其組合可供選擇。如果只允許wifi下載,而當前網路為3g,則下載會等待。
request.setAllowedOverRoaming(boolean allow)移動網路情況下是否允許漫遊。

 

request.setMimeType(“application/cn.trinea.download.file”);
設定下載檔案的mineType。因為下載管理Ui中點擊某個已下載完成檔案及下載完成點擊通知欄提示都會根據mimeType去開啟檔案,所以我們可以利用這個屬性。比如上面設定了mimeType為application/cn.trinea.download.file,我們可以同時設定某個Activity的intent-filter為application/cn.trinea.download.file,用於響應點擊的開啟檔案。

 Java 
1234567 <intent-filter> <action android:name="android.intent.action.VIEW" />  <category android:name="android.intent.category.DEFAULT" />  <data android:mimeType="application/cn.trinea.download.file" /></intent-filter>

request.addRequestHeader(String header, String value)
添加請求下載的網路連結的http頭,比如User-Agent,gzip壓縮等

 

3 下載進度狀態監聽及查詢

下載進度狀態監聽代碼 

其中我們會監聽Uri.parse(“content://downloads/my_downloads”)。然後查詢下載狀態和進度,發送handler進行更新,handler中處理就是設定進度條和狀態等。

其中DownloadManagerPro.getBytesAndStatus的主要代碼如下,可直接引入[email protected](歡迎star和fork^_^)作為你項目的library(如何拉取代碼及添加公用庫):

下載進度狀態查詢代碼 

從上面代碼可以看出我們主要調用DownloadManager.Query()進行查詢。DownloadManager.Query為下載管理對外開放的資訊查詢類,主要包括以下介面:

setFilterById(long… ids)根據下載id進行過濾
setFilterByStatus(int flags)根據下載狀態進行過濾
setOnlyIncludeVisibleInDownloadsUi(boolean value)根據是否在download ui中可見進行過濾。

 

orderBy(String column, int direction)根據列進行排序,不過目前僅支援DownloadManager.COLUMN_LAST_MODIFIED_TIMESTAMP和DownloadManager.COLUMN_TOTAL_SIZE_BYTES排序。

 

4 下載成功監聽
下載完成後,下載管理會發出DownloadManager.ACTION_DOWNLOAD_COMPLETE這個廣播,並傳遞downloadId作為參數。通過接受廣播我們可以開啟對下載完成的內容進行操作。代碼如下:

下載成功監聽 

 

5、響應通知欄點擊
(1) 響應下載中通知欄點擊
點擊下載中通知欄提示,系統會對下載的應用單獨發送Action為DownloadManager.ACTION_NOTIFICATION_CLICKED廣播。intent.getData為content://downloads/all_downloads/29669,最後一位為downloadId。
如果同時下載多個應用,intent會包含DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS這個key,表示下載的的downloadId數組。這裡設計到下載管理通知欄的顯示機制,會在下一篇具體介紹。

 

(2) 響應下載完成通知欄點擊
下載完後會調用下面代碼進行處理,從中我們可以發現系統會調用View action根據mimeType去查詢。所以可以利用我們在介紹的DownloadManager.Request的setMimeType函數。

openDownload源碼 

 

如果介面上過多元素需要更新,且網速較快不斷的執行onChange會對頁面效能有一定影響。推薦ScheduledExecutorService定期查詢,如下:

 Java 
123456789 public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);Runnable command = new Runnable() {  @Override public void run() { updateView(); } };scheduledExecutorService.scheduleAtFixedRate(command, 0, 3, TimeUnit.SECONDS);

表示3秒定時重新整理

Android系統下載管理DownloadManager功能介紹及使用樣本

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.