從Android2.3(API level 9)開始Android用系統服務(Service)的方式提供了Download Manager來優化處理長時間的下載操作。
Download Manager處理HTTP連接并監控連接中的狀態變化以及系統重啟來確保每一個下載任務順利完成。在大多數涉及到下載的情況中使用Download Manager都是不錯的選擇,特別是當用戶切換不同的應用以后下載需要在后臺繼續進行,以及當下載任務順利完成非常重要的情況(DownloadManager對于斷點續傳功能支持很好)。
簡單的使用方法
//創建下載任務,downloadUrl就是下載鏈接
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadUrl));
//指定下載路徑和下載文件名
request.setDestinationInExternalPublicDir("/download/", fileName);
//獲取下載管理器
DownloadManager downloadManager= (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
//將下載任務加入下載隊列,否則不會進行下載
downloadManager.enqueue(request);
使用的時候需要添加權限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Download Manager簡介
DownloadManager是系統開放給第三方應用使用的類,包含兩個靜態內部類:
DownloadManager.Request:用來請求一個下載
DownloadManager.Query:用來查詢下載信息,這兩個類的具體功能會在后面穿插介紹。
**使用Download Manager 流程: **
1.創建一個下載Request
2.將創建的Request添加到Download Manager 就好了
DownloadManager主要提供了下面幾個接口:
public long enqueue(Request request):執行下載,返回downloadId,downloadId可用于后面查詢下載信息。若網絡不滿足條件、Sdcard掛載中、超過最大并發數等異常會等待下載,正常則直接下載。
public int remove(long… ids)刪除下載,若下載中取消下載。會同時刪除下載文件和記錄。
首先創建一個下載請求 ------DownloadManager.Request
DownloadManager.Request除了構造函數的Uri外,其他設置都為可選設置;
1.創建Request
//downUrl為下載地址
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downUrl));
通過源代碼可以看出開 只能下載HTTP或者HTTPS的URI
2.指定下載路徑和下載文件名
該方法比較常用
//sdcard的目錄下的download文件夾,必須設置;downFileName為保存文件名
//當路徑中該文件已經存在時,會自動以迭代的方式命名。
request.setDestinationInExternalPublicDir("/download/", downFileName);
從源碼中我們可以看出下載完整目錄為
Environment.getExternalStoragePublicDirectory(dirType)。
不過在在API17(4.2)及以前版本中file是通過file.mkdir()創建的,這樣如果上級目錄不存在就會新建文件夾異常。所以版本兼容到4.2及以前的,在下載前我們最好自己調用File的mkdirs方法遞歸創建子目錄,如下:
File folder = new File(folderName);
return (folder.exists() && folder.isDirectory()) ? true : folder.mkdirs();
其他設置下載路徑接口:為setDestinationUri,setDestinationInExternalFilesDir,setDestinationToSystemCache。其中setDestinationToSystemCache僅限系統app使用。
以上四個方法中除了setDestinationToSystemCache是系統app使用外,其他三個方法最終也都是設置下載的目標URI;
3.設置不同網絡狀態是否下載
//只有允許WIFIi下載
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
表示下載允許的網絡類型,默認在任何網絡下都允許下載。
有NETWORK_MOBILE、NETWORK_WIFI、NETWORK_BLUETOOTH三種及其組合可供選擇。如果只允許wifi下載,而當前網絡為3g,則下載會等待。
Android API level 11 介紹了getRecommendedMaxBytesOverMobile類方法(靜態方法),返回一個當前手機網絡連接下的最大建議字節數,可以來判斷下載是否應該限定在WiFi條件下。
//移動網絡情況下是否允許漫游。默認是true
request.setAllowedOverRoaming(boolean allow)
4.設置下載中通知欄提示
//默認只顯示下載中通知
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
表示下載進行中和下載完成的通知欄是否顯示。
Request.VISIBILITY_VISIBLE:在下載進行的過程中,通知欄中會一直顯示該下載的Notification,當下載完成時,該Notification會被移除,這是默認的參數值。
Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED:在下載過程中通知欄會一直顯示該下載的Notification,在下載完成后該Notification會繼續顯示,直到用戶點擊該Notification或者消除該Notification。
Request.VISIBILITY_VISIBLE_NOTIFY_ONLY_COMPLETION:只有在下載完成后該Notification才會被顯示。
Request.VISIBILITY_HIDDEN:不顯示該下載請求的Notification。如果要使用這個參數,需要在應用的清單文件中加上DOWNLOAD_WITHOUT_NOTIFICATION權限。
注:該方法只支持API 11及以后(3.0),若在API 9 和API 10中可以用
//在API 11以后被標記為@Deprecated
request.setShowRunningNotification(boolean show);
//下載任務標題
request.setTitle(“Earthquakes”);
//下載文件描述
request.setDescription(“Earthquake XML”);
5.設置文件類型,可以在下載結束后自動打開該文件
我們可以通過addRequestHeader方法為DownloadManager.Request對象request添加HTTP頭;
也可以通過setMimeType方法重寫從服務器返回的mime type,設置下載文件的mineType。因為下載管理Ui中點擊某個已下載完成文件及下載完成點擊通知欄提示都會根據mimeType去打開文件,所以我們可以利用這個屬性。比如上面設置了mimeType為application/cn.trinea.download.file,我們可以同時設置某個Activity的intent-filter為application/cn.trinea.download.file,用于響應點擊的打開文件。
<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>
6.是否允許MediaScanner掃描到這個文件
//表示允許MediaScanner掃描到這個文件,默認不允許。
request.allowScanningByMediaScanner();
7.如果我們希望下載的文件可以被系統的Downloads應用掃描到并管理
request.setVisibleInDownloadsUi(boolean isVisible); 默認是允許的。
8.是否允許“計量式的網絡連接”執行下載操作
//不太明白這個是干嘛的 一般的時候使用默認的就好了
request.setAllowedOverMetered(boolean); 默認是允許的。
DownloadManager.Request的常用方法就這些了