最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于DownloadManager的簡單下載器編寫小結(jié)

 更新時間:2017年12月17日 09:05:53   作者:YWQalways樂觀自信愛  
Android自帶的DownloadManager是一個很好的下載文件的工具。該類在API level 9之后出現(xiàn),它已經(jīng)幫我們處理了下載失敗、重新下載等功能,整個下載過程全部交給系統(tǒng)負(fù)責(zé),不需要我們過多的處理,非常的nice。關(guān)鍵的是用起來也很簡單,稍微封裝一下就可以幾句話搞定下載

一直聽說過Android自帶的DownloadManager,只是拖延癥發(fā)作,一直沒有時間去研究研究,其實(shí)在很多項(xiàng)目開發(fā)中,都有一個功能是非常重要的,那就是應(yīng)用的檢查更新了!基于DownloadManager,可以做一個輕量級的下載器,將下載任務(wù)交給系統(tǒng)去執(zhí)行,減輕自身APP的壓力,何樂而不為呢?!

DownloadManager的基本使用姿勢

通過getSystemService進(jìn)行實(shí)例化

DownloadManager downloadManager = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);
構(gòu)建下載請求

DownloadManager.Request request = new DownloadManager.Request(Uri.parse("目標(biāo)文件下載地址"));
//設(shè)置目標(biāo)文件夾,如果你想在系統(tǒng)的storage目錄下載一個testDownload/test/test.apk
request.setDestinationInExternalPublicDir("testDownload", "test/test.apk");
//設(shè)置下載所需的網(wǎng)絡(luò)環(huán)境,設(shè)置了移動網(wǎng)絡(luò)和WiFi環(huán)境下均能下載 request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
//通知欄設(shè)置
//顯示在通知欄
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);

注意?。。∪绻x擇不顯示在通知欄,那么必須聲明以下權(quán)限

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

然后設(shè)置不可見

request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);

否則將會拋出一個securityException

//設(shè)置文件類型為apk類型,當(dāng)downloadManager調(diào)用openFile時會喚起相應(yīng)的程序
request.setMimeType("application/cn.trinea.download.file");
 //開始下載,得到一個唯一的downloadId,大有用處
long downloadId = downloadManager.enqueue(request);

如何獲取下載的情況呢

private int[] getBytesAndStatus(long downloadId) {

    //構(gòu)建一個數(shù)組,存放已下載文件大小、總大小、下載狀態(tài)
    int[] bytesAndStatus = new int[]{
        -1, -1, 0
    };
    //通過構(gòu)建下載請求時獲得的downloadId進(jìn)行文件查詢
    DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
    Cursor cursor = null;
    try {
      cursor = downloadManager.query(query);
      if (cursor != null && cursor.moveToFirst()) {
        //已經(jīng)下載文件大小
        bytesAndStatus[0] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
        //下載文件的總大小
        bytesAndStatus[1] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
        //下載狀態(tài)
        bytesAndStatus[2] = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
      }
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return bytesAndStatus;
  }

注冊監(jiān)聽文件下載成功的廣播

private BroadcastReceiver downloadCompleteReceiver;
downloadCompleteReceiver = new BroadcastReceiver() {
      @Override
      public void onReceive(Context context, Intent intent) {
        //文件下載成功時
         DownloadManager.Query query = new DownloadManager.Query();
        //通過下載的id查找
        query.setFilterById(downloadId);
        Cursor c = downloadManager.query(query);
        if (c.moveToFirst()) {
            int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
            switch (status) {
              //下載完成
              case DownloadManager.STATUS_SUCCESSFUL:

                 break;

               }

         }
      }
    };
//注冊,這里只能攔截文件下載成功的廣播,并不能進(jìn)行進(jìn)度監(jiān)聽,在適當(dāng)?shù)牡胤饺∠嗛啅V播
context.registerReceiver(downloadCompleteReceiver,
        new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

網(wǎng)上很多博客都是通過自定義ContentObserver獲取本地文件變化,其實(shí)可以另辟蹊徑,通過一個定時器間隔調(diào)用以上getBytesAndStatus(long downloadId)能達(dá)到同樣的效果,用Rxjava實(shí)現(xiàn)一個簡單的定時器

/**
 * 由于DownloadManager自身沒有提供實(shí)時進(jìn)度的api,所以通過以下定時器獲取已下載的文件大小
 */
  private void updateProgress() {
        //每隔0.5秒刷新一次進(jìn)度,在適當(dāng)?shù)牡胤接浀米N timeDisposable
        Disposable timeDisposable = Observable.interval(500, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread()).subscribe(new DataConsumer<Long>() {
          @Override
          public void acceptData(@io.reactivex.annotations.NonNull Long aLong) {

            int [ ] bytesAndStatus = getBytesAndStatus(downloadId);
            //todo 在這里進(jìn)行回調(diào)即可
          }
        });

  }

了解完DownloadManager基本的使用方式,那么基于它來封裝一個簡單易用的下載器吧!

實(shí)現(xiàn)效果

 DownloadHelper.Builder builder = new DownloadHelper.Builder(this).title("下載通知")
          .description("正在下載新版本V1.2.0")
          .downloadUrl("http://download.sj.qq.com/upload/connAssitantDownload/upload/MobileAssistant_1.apk")
          .fileSaveName("MobileAssistant_1.apk").fileSavePath("testDownload")
          .notifyVisible(true)
          .fileType(DownloadHelper.FileType.APK).apkInstallHint(true).onProgressListener(new DownloadHelper.OnDownloadProgressListener() {
            @Override
            public void onProgress(int downloadedSize, int totalSize) {

              int progress =(int)((downloadedSize*1.0f/totalSize)*100);
              Logger.d("progress=%d",progress);
               //進(jìn)度回調(diào)

            }

            @Override
            public void onSuccess(Uri fileUri) {
             //文件下載成功回調(diào)的Uri
 

            }

            @Override
            public void onFail() {
             //文件下載失敗
  

            }

            @Override
            public void fileAlreadyExits(File file) { 
            //當(dāng)你想重復(fù)下載同樣的文件時,本地檢測是否存在同樣的文件,進(jìn)行回調(diào)
             
            }
          });
      DownloadHelper downloadHelper = builder.build();
      //開始下載
      downloadHelper.start();
      //移除下載任務(wù)
      downloadHelper.deleteDownloadFile();

源碼請到https://github.com/yuwenque/SimpleDownloadHelper.git

相關(guān)文章

  • Android Gradle Plug 4.1.0 升級后gradle獲取manifest位置失敗問題解決

    Android Gradle Plug 4.1.0 升級后gradle獲取manifest位置失敗問題解決

    這篇文章主要介紹了Android Gradle Plug 4.1.0 升級后gradle獲取manifest位置失敗問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Java程序員轉(zhuǎn)Android開發(fā)必讀經(jīng)驗(yàn)一份

    Java程序員轉(zhuǎn)Android開發(fā)必讀經(jīng)驗(yàn)一份

    小編最近幾日偷偷的發(fā)現(xiàn)部分Java程序員想轉(zhuǎn)安卓開發(fā),故此加緊補(bǔ)充知識,為大家搜集資料,積極整理前人的經(jīng)驗(yàn),希望可以給正處于困惑中的你,帶來些許的幫助。
    2017-11-11
  • Flutter路由守衛(wèi)攔截的實(shí)現(xiàn)

    Flutter路由守衛(wèi)攔截的實(shí)現(xiàn)

    路由守衛(wèi)攔截最常見的應(yīng)用場景就是對用戶數(shù)據(jù)權(quán)限的校驗(yàn),本文主要介紹了Flutter路由守衛(wèi)攔截的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Android自定義view制作絢麗的驗(yàn)證碼

    Android自定義view制作絢麗的驗(yàn)證碼

    這篇文章主要介紹了Android自定義view制作絢麗的驗(yàn)證碼的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • android實(shí)現(xiàn)狀態(tài)欄添加圖標(biāo)的函數(shù)實(shí)例

    android實(shí)現(xiàn)狀態(tài)欄添加圖標(biāo)的函數(shù)實(shí)例

    這篇文章主要介紹了android實(shí)現(xiàn)狀態(tài)欄添加圖標(biāo)的函數(shù),較為詳細(xì)的分析了Android狀態(tài)欄添加及刪除圖標(biāo)的具體實(shí)現(xiàn)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • Android應(yīng)用隱私合規(guī)檢測實(shí)現(xiàn)方案詳解

    Android應(yīng)用隱私合規(guī)檢測實(shí)現(xiàn)方案詳解

    這篇文章主要介紹了Android應(yīng)用隱私合規(guī)檢測實(shí)現(xiàn)方案,我們需要做的就是提前檢測好自己的應(yīng)用是否存在隱私合規(guī)問題,及時整改過來,下面提供Xposed Hook思路去檢測隱私合規(guī)問題,建議有Xposed基礎(chǔ)的童鞋閱讀,需要的朋友可以參考下
    2022-07-07
  • Android 圖片選擇詳解及實(shí)例代碼

    Android 圖片選擇詳解及實(shí)例代碼

    這篇文章主要介紹了 Android 圖片選擇詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • 全面解析Android系統(tǒng)指紋啟動流程

    全面解析Android系統(tǒng)指紋啟動流程

    這篇文章主要介紹了全面解析Android系統(tǒng)指紋啟動流程,對Android啟動原理感興趣的同學(xué)可以參考下
    2021-04-04
  • Android中ViewPager你所不知道的優(yōu)化技巧分享

    Android中ViewPager你所不知道的優(yōu)化技巧分享

    提到ViewPager想必各位同學(xué)一點(diǎn)都不陌生,它是Android中最常用的組件之一,這篇文章小編就帶大家一起來看看ViewPager一些新的優(yōu)化方式吧
    2024-04-04
  • flutter 路由跳轉(zhuǎn)的實(shí)現(xiàn)示例

    flutter 路由跳轉(zhuǎn)的實(shí)現(xiàn)示例

    這篇文章主要介紹了flutter 路由跳轉(zhuǎn)的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評論

嵊州市| 九龙坡区| 兰坪| 仁怀市| 岗巴县| 东兰县| 佛山市| 徐汇区| 饶河县| 丰台区| 乐陵市| 林芝县| 禄丰县| 珠海市| 石泉县| 安义县| 岚皋县| 翁源县| 长宁区| 山西省| 罗江县| 拉萨市| 疏附县| 土默特右旗| 大竹县| 泉州市| 乌拉特后旗| 潞城市| 洪泽县| 株洲市| 阿拉善盟| 胶南市| 嵊泗县| 泸定县| 凌云县| 沙河市| 连云港市| 大兴区| 论坛| 苍南县| 晋中市|