Android DownloadProvider學習 (二)

 

 

 

DownloadManager.Request用來請求一個下載,DownloadManager.Query用來查詢下載信息,這兩個類的具體功能會在後面穿插介紹。DownloadManager的源碼可見DownloadManager@Grepcodecss

 

DownloadManager主要提供了下面幾個接口:
public int remove(long… ids)刪除下載,若下載中取消下載。會同時刪除下載文件和記錄。
 
java

public static Long getRecommendedMaxBytesOverMobile(Context context經過移動網絡下載的最大字節數
public String getMimeTypeForDownloadedFile(long id)獲得下載的mimeType,如何設置後面會進行介紹android

 

其它:經過查看代碼咱們能夠發現還有個CursorTranslator私有靜態內部類。這個類主要對Query作了一層代理。將 DownloadProvider和DownloadManager之間作個映射。將DownloadProvider中的十幾種狀態對應到了 DownloadManager中的五種狀態,DownloadProvider中的失敗、暫停緣由轉換爲了DownloadManager的緣由。git

 

一、AndroidManifest中添加權限github

網絡訪問權限是必須的,下載地址爲sdcard的話須要添加sdcard寫權限。網絡

 

 

 
 
Java
 
1
2
3
4
5
6
7
8
9
10
11
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/com.trinea.download.file");
long downloadId = downloadManager.enqueue(request);

上面調用downloadManager的enqueue接口進行下載,返回惟一的downloadId。app

 

DownloadManager.Request除了構造函數的Uri必須外,其餘設置都爲可選設置。下面逐個介紹下:
request.setDestinationInExternalPublicDir(「Trinea」, 「MeiLiShuo.apk」);表示設置下載地址爲sd卡的Trinea文件夾,文件名爲MeiLiShuo.apk。ide

從源碼中咱們能夠看出下載完整目錄爲Environment.getExternalStoragePublicDirectory(dirType)。 不過file是經過file.mkdir()建立的,這樣若是上級目錄不存在就會新建文件夾異常。因此下載前咱們最好本身調用File的mkdirs方法 遞歸建立子目錄,以下:函數

不然,會報異常性能

其餘設置下載路徑接口爲 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/com.trinea.download.file」);
設置下載文件的mineType。由於下載管理Ui中點擊某個已下載完成文件及下載完成點擊通知欄提示都會根據mimeType去打開文件,因此咱們能夠 利用這個屬性。好比上面設置了mimeType爲application/com.trinea.download.file,咱們能夠同時設置某個 Activity的intent-filter爲application/com.trinea.download.file,用於響應點擊的打開文件。

 

 

下載進度狀態監聽代碼
 

其中咱們會監聽 其中DownloadManagerPro.getBytesAndStatus的主要代碼以下,可直接引入TrineaAndroidCommon@Github(歡迎star和fork^_^)或TrineaAndroidCommon@GoogleCode做爲你項目的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排序。

 

DownloadManager.ACTION_DOWNLOAD_COMPLETE這個廣播,並傳遞downloadId做爲參數。經過接受廣播咱們能夠打開對下載完成的內容進行操做。代碼以下:

 

 

 

openDownload源碼
 

 

若是界面上過多元素須要更新,且網速較快不斷的執行onChange會對頁面性能有必定影響。推薦ScheduledExecutorService按期查詢,以下:

 
Java
 

1
2
3
4
5
6
7
8
9
public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
Runnable command = new Runnable() {
 
        @Override
        public void run() {
            updateView();
        }
    };
scheduledExecutorService.scheduleAtFixedRate(command, 0, 3, TimeUnit.SECONDS);
相關文章
相關標籤/搜索