• <kbd id="qyk40"></kbd>
  • <strike id="qyk40"></strike><samp id="qyk40"><pre id="qyk40"></pre></samp>

    一、DownloadManager簡單介紹
    DownloadManager是系統(tǒng)開放給第三方應(yīng)用使用的類,包含兩個靜態(tài)內(nèi)部類DownloadManager.Query和DownloadManager.Request。DownloadManager.Request用來請求一個下載,DownloadManager.Query用來查詢下載信息,這兩個類的具體功能會在后面穿插介紹。DownloadManager的源碼可見DownloadManager@Grepcode。

     

    DownloadManager主要提供了下面幾個接口:
    public long enqueue(Request request)執(zhí)行下載,返回downloadId,downloadId可用于后面查詢下載信息。若網(wǎng)絡(luò)不滿足條件、Sdcard掛載中、超過最大并發(fā)數(shù)等異常會等待下載,正常則直接下載。
    public int remove(long… ids)刪除下載,若下載中取消下載。會同時刪除下載文件和記錄。
    public Cursor query(Query query)查詢下載信息。

     

    public static Long getRecommendedMaxBytesOverMobile(Context context通過移動網(wǎng)絡(luò)下載的最大字節(jié)數(shù)
    public String getMimeTypeForDownloadedFile(long id)得到下載的mimeType,如何設(shè)置后面會進行介紹

     

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

     

    二、下載管理示例
    下面具體介紹利用DownloadManager進行下載。
    1、AndroidManifest中添加權(quán)限

     

    Java

    1

    2

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

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

    網(wǎng)絡(luò)訪問權(quán)限是必須的,下載地址為sdcard的話需要添加sdcard寫權(quán)限。

     

    2、調(diào)用DownloadManager.Request開始下載

     

    Java

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    DownloadManagerdownloadManager=(DownloadManager)getSystemService(DOWNLOAD_SERVICE);

    StringapkUrl="http://img.meilishuo.net/css/images/AndroidShare/Meilishuo_3.6.1_10006.apk";

    DownloadManager.Requestrequest=newDownloadManager.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");

    longdownloadId=downloadManager.enqueue(request);

    上面調(diào)用downloadManager的enqueue接口進行下載,返回唯一的downloadId。

     

    DownloadManager.Request除了構(gòu)造函數(shù)的Uri必須外,其他設(shè)置都為可選設(shè)置。下面逐個介紹下:
    request.setDestinationInExternalPublicDir(“Trinea”, “MeiLiShuo.apk”);表示設(shè)置下載地址為sd卡的Trinea文件夾,文件名為MeiLiShuo.apk。

    setDestinationInExternalPublicDir源碼

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

     

    Java

    1

    2

    Filefolder=newFile(folderName);

    return(folder.exists()&&folder.isDirectory())?true:folder.mkdirs();

    否則,會報異常

    1

    2

    java.lang.IllegalStateException:Unabletocreatedirectory:/storage/sdcard0/Trinea/aa

    atandroid.app.DownloadManager$Request.setDestinationInExternalPublicDir(DownloadManager.java)

    其他設(shè)置下載路徑接口為 setDestinationUri,setDestinationInExternalFilesDir,setDestinationToSystemCache。 其中setDestinationToSystemCache僅限系統(tǒng)app使用。

     

    request.allowScanningByMediaScanner();表示允許MediaScanner掃描到這個文件,默認(rèn)不允許。

    request.setTitle(“MeiLiShuo”);設(shè)置下載中通知欄提示的標(biāo)題
    request.setDescription(“MeiLiShuo desc”);設(shè)置下載中通知欄提示的介紹
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
    表示下載進行中和下載完成的通知欄是否顯示。默認(rèn)只顯示下載中通知。VISIBILITY_VISIBLE_NOTIFY_COMPLETED表示下載完 成后顯示通知欄提示。VISIBILITY_HIDDEN表示不顯示任何通知欄提示,這個需要在AndroidMainfest中添加權(quán)限 android.permission.DOWNLOAD_WITHOUT_NOTIFICATION.

     

    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
    表示下載允許的網(wǎng)絡(luò)類型,默認(rèn)在任何網(wǎng)絡(luò)下都允許下載。有NETWORK_MOBILE、NETWORK_WIFI、NETWORK_BLUETOOTH三種及其組合可供選擇。如果只允許wifi下載,而當(dāng)前網(wǎng)絡(luò)為3g,則下載會等待。
    request.setAllowedOverRoaming(boolean allow)移動網(wǎng)絡(luò)情況下是否允許漫游。

     

    request.setMimeType(“application/com.trinea.download.file”);
    設(shè)置下載文件的mineType。因為下載管理Ui中點擊某個已下載完成文件及下載完成點擊通知欄提示都會根據(jù)mimeType去打開文件,所以我們可以 利用這個屬性。比如上面設(shè)置了mimeType為application/com.trinea.download.file,我們可以同時設(shè)置某個 Activity的intent-filter為application/com.trinea.download.file,用于響應(yīng)點擊的打開文件。

     

    Java

    1

    2

    3

    4

    5

    6

    7

    <intent-filter>

        <actionandroid:name="android.intent.action.VIEW"/>

     

        <categoryandroid:name="android.intent.category.DEFAULT"/>

     

        <dataandroid:mimeType="application/com.trinea.download.file"/>

    </intent-filter>

    request.addRequestHeader(String header, String value)
    添加請求下載的網(wǎng)絡(luò)鏈接的http頭,比如User-Agent,gzip壓縮等

     

    3 下載進度狀態(tài)監(jiān)聽及查詢

    下載進度狀態(tài)監(jiān)聽代碼

    其中我們會監(jiān)聽Uri.parse(“content://downloads/my_downloads”)。然后查詢下載狀態(tài)和進度,發(fā)送handler進行更新,handler中處理就是設(shè)置進度條和狀態(tài)等。

    其中DownloadManagerPro.getBytesAndStatus的主要代碼如下,可直接引入TrineaAndroidCommon@Github(歡迎star和fork^_^)或TrineaAndroidCommon@GoogleCode作為你項目的library(如何拉取代碼及添加公共庫)

    下載進度狀態(tài)查詢代碼

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

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

     

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

     

    4 下載成功監(jiān)聽
    下載完成后,下載管理會發(fā)出DownloadManager.ACTION_DOWNLOAD_COMPLETE這個廣播,并傳遞downloadId作為參數(shù)。通過接受廣播我們可以打開對下載完成的內(nèi)容進行操作。代碼如下:

    下載成功監(jiān)聽

     

    5、響應(yīng)通知欄點擊
    (1) 響應(yīng)下載中通知欄點擊

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

     

    (2) 響應(yīng)下載完成通知欄點擊
    下載完后會調(diào)用下面代碼進行處理,從中我們可以發(fā)現(xiàn)系統(tǒng)會調(diào)用View action根據(jù)mimeType去查詢。所以可以利用我們在介紹的DownloadManager.Request的setMimeType函數(shù)。

    openDownload源碼

     

    如果界面上過多元素需要更新,且網(wǎng)速較快不斷的執(zhí)行onChange會對頁面性能有一定影響。推薦ScheduledExecutorService定期查詢,如下:

     

    Java

    1

    2

    3

    4

    5

    6

    7

    8

    9

    publicstaticScheduledExecutorServicescheduledExecutorService=Executors.newScheduledThreadPool(3);

    Runnablecommand=newRunnable(){

     

            @Override

            publicvoidrun(){

                updateView();

            }

        };

    scheduledExecutorService.scheduleAtFixedRate(command,0,3,TimeUnit.SECONDS);

    表示3秒定時刷新

     

    穩(wěn)定

    產(chǎn)品高可用性高并發(fā)

    貼心

    項目群及時溝通

    專業(yè)

    產(chǎn)品經(jīng)理1v1支持

    快速

    MVP模式小步快跑

    承諾

    我們選擇聲譽

    堅持

    10年專注高端品質(zhì)開發(fā)
    • 返回頂部
    午夜精品久久久久久| 久久精品无码一区二区三区免费| 五月天婷婷精品免费视频| 精品国产呦系列在线看| 国产成人精品久久二区二区| 久久精品国产亚洲沈樵| 久久国产美女免费观看精品 | 精品一卡2卡三卡4卡乱码精品视频| 午夜精品久久久久久毛片| 国内精品人妻无码久久久影院 | 久久亚洲精品无码播放| 日韩三级电影视频| 日韩在线视频播放免费视频完整版| 色综合91久久精品中文字幕| 国内精品乱码卡1卡2卡3免费| 精品爆乳一区二区三区无码av| 99精品国产高清一区二区| 亚洲αv在线精品糸列| 人妻少妇精品一区二区三区| 凹凸69堂国产成人精品视频| 日韩高清特级特黄毛片| 日韩免费人妻AV无码专区蜜桃| 加勒比精品久久一区二区三区| 国产精品区一区二区三| 精品伊人久久久久网站| 精品久久伦理中文字幕| 在线精品免费视频无码的| 亚洲精品无码专区久久| 国产精品亚洲一区二区麻豆| 2021国内久久精品| 国产精品亚洲精品观看不卡| 国产精品久久波多野结衣| 久热中文字幕在线精品免费| 精品久久无码中文字幕| 亚洲成a人片在线观看精品 | 嫖妓丰满肥熟妇在线精品| 午夜精品久久久久久久| 夜色www国产精品资源站| 久久久久久国产精品三级| 香蕉久久夜色精品升级完成| 久久91精品国产91久久|