国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

android中DownloadManager實現版本更新,監聽下載進度實例

2019-12-12 03:24:33
字體:
來源:轉載
供稿:網友

DownloadManager簡介

DownloadManager是Android 2.3(API level 9)用系統服務(Service)的方式提供了DownloadManager來處理長時間的下載操作。它包含兩個靜態內部類DownloadManager.Query(用來查詢下載信息)和DownloadManager.Request(用來請求一個下載)。

DownloadManager主要提供了下面幾個方法:

public long enqueue(Request request)把任務加入下載隊列并返回downloadId,以便后面用于查詢下載信息。若網絡不滿足條件、Sdcard掛載中、超過最大并發數等異常會等待下載,正常則直接下載。

public int remove(long… ids)刪除下載,若取消下載,會同時刪除下載文件和記錄。

public Cursor query(Query query)查詢下載信息,包括下載文件總大小,已經下載的大小以及下載狀態等。

ContentObserver簡介

public void ContentObserver(Handler handler) 所有ContentObserver的派生類都需要調用該構造方法,參數:handler Handler對象用于在主線程中修改UI。

public void onChange(boolean selfChange)當觀察到的Uri中內容發生變化時,就會回調該方法。所有ContentObserver的派生類都需要重載該方法去處理邏輯。

觀察特定Uri的步驟如下:

1、創建我們特定的ContentObserver派生類,必須重載父類構造方法,必須重載onChange()方法去處理回調后的功能實現。

2、為指定的Uri注冊一個ContentObserver派生類實例,當給定的Uri發生改變時,回調該實例對象去處理,調用registerContentObserver()方法去注冊內容觀察者。

3、由于ContentObserver的生命周期不同步于Activity和Service等。因此,在不需要時,需要手動的調用unregisterContentObserver()注銷內容觀察者。

效果圖:

一:執行下載

下載配置

downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);downloadObserver = new DownloadChangeObserver();//在執行下載前注冊內容監聽者registerContentObserver();DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));/**設置用于下載時的網絡狀態*/request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);/**設置通知欄是否可見*/request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN);/**設置漫游狀態下是否可以下載*/request.setAllowedOverRoaming(false);/**如果我們希望下載的文件可以被系統的Downloads應用掃描到并管理,我們需要調用Request對象的setVisibleInDownloadsUi方法,傳遞參數true.*/request.setVisibleInDownloadsUi(true);/**設置文件保存路徑*/request.setDestinationInExternalFilesDir(getApplicationContext(), "phoenix", "phoenix.apk");/**將下載請求放入隊列, return下載任務的ID*/downloadId = downloadManager.enqueue(request);//執行下載任務時注冊廣播監聽下載成功狀態registerBroadcast();

添加權限

<!--網絡通信權限--><uses-permission android:name="android.permission.INTERNET"/><!--SD卡寫入數據權限--><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><!--SD卡創建與刪除權限--><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><!--VISIBILITY_HIDDEN表示不顯示任何通知欄提示的權限--><uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/><!--DownloadManager--><uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/>在清單文件中注冊Service<!--版本更新服務--><service android:name="com.github.phoenix.service.DownloadService"></service>

二:監聽下載進度

注冊ContentObserver

三個參數分別是所要監聽的Uri、false表示精確匹配此Uri,true表示可以匹配其派生的Uri、ContentObserver的派生類實例。

/*** 注冊ContentObserver*/private void registerContentObserver() { /** observer download change **/ if (downloadObserver != null) {   getContentResolver().registerContentObserver(Uri.parse("content://downloads/my_downloads"), true, downloadObserver); }}

查詢已下載數據大小

為了提高性能,在這里開啟定時任務,每2秒去查詢數據大小并發送到handle中更新UI。

/*** 監聽下載進度*/private class DownloadChangeObserver extends ContentObserver { public DownloadChangeObserver() {   super(downLoadHandler);   scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(); } /**  * 當所監聽的Uri發生改變時,就會回調此方法  *  * @param selfChange 此值意義不大, 一般情況下該回調值false  */ @Override public void onChange(boolean selfChange) {   scheduledExecutorService.scheduleAtFixedRate(progressRunnable, 0, 2, TimeUnit.SECONDS); }}/*** 通過query查詢下載狀態,包括已下載數據大小,總大小,下載狀態** @param downloadId* @return*/private int[] getBytesAndStatus(long downloadId) { int[] bytesAndStatus = new int[]{     -1, -1, 0 }; DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId); Cursor cursor = null; try {   cursor = downloadManager.query(query);   if (cursor != null && cursor.moveToFirst()) {     //已經下載文件大小     bytesAndStatus[0] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));     //下載文件的總大小     bytesAndStatus[1] = cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));     //下載狀態     bytesAndStatus[2] = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));   } } finally {   if (cursor != null) {     cursor.close();   } } return bytesAndStatus;}

Activity與Service通信

既然我們要在Activity中實時更新下載進度,那么就需要Activity綁定Service建立通信。

在Service中提供一個接口實時回調進度值。用isBindService來標識Activity是否綁定過Service,在調用bindService(ServiceConnection conn)方法時,如果綁定成功會返回true,否則返回false,只有返回true時才可以進行解綁,否則報錯。

private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) {   DownloadService.DownloadBinder binder = (DownloadService.DownloadBinder) service;   DownloadService downloadService = binder.getService();   //接口回調,下載進度   downloadService.setOnProgressListener(new DownloadService.OnProgressListener() {     @Override     public void onProgress(float fraction) {       LogUtil.i(TAG, "下載進度:" + fraction);       bnp.setProgress((int)(fraction * 100));       //判斷是否真的下載完成進行安裝了,以及是否注冊綁定過服務       if (fraction == DownloadService.UNBIND_SERVICE && isBindService) {         unbindService(conn);         isBindService = false;         MToast.shortToast("下載完成!");       }     }   }); } @Override public void onServiceDisconnected(ComponentName name) { }};

三:廣播監聽下載成功

下載完成,自動安裝,記錄APK存儲路徑

在下載成功后把APK存儲路徑保存到SP中,同時關閉定時器,開啟apk安裝界面。

/*** 安裝APK* @param context* @param apkPath 安裝包的路徑*/public static void installApk(Context context, Uri apkPath) { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); //此處因為上下文是Context,所以要加此Flag,不然會報錯 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(apkPath, "application/vnd.android.package-archive"); context.startActivity(intent);}

四:善后處理

1、關閉定時器,線程

當收到下載完成的廣播時立即停掉定時器,取消線程。

2、解綁Service,注銷廣播,注銷ContentObserver

當Service解綁的時候,要把監聽下載完成的廣播和監聽下載進度的ContentObserver注銷。

3、刪除APK

當應用安裝成功后,再次啟動就執行刪除Apk操作。

/*** 刪除上次更新存儲在本地的apk*/private void removeOldApk() { //獲取老APK的存儲路徑 File fileName = new File(SPUtil.getString(Constant.SP_DOWNLOAD_PATH, "")); LogUtil.i(TAG, "老APK的存儲路徑 =" + SPUtil.getString(Constant.SP_DOWNLOAD_PATH, "")); if (fileName != null && fileName.exists() && fileName.isFile()) {   fileName.delete();   LogUtil.i(TAG, "存儲器內存在老APK,進行刪除操作"); }}

五:具體應用

首先上傳當前應用版本號給服務器,讓服務器檢查是否可以進行版本更新;如果可以進行版本更新,則綁定Service,開始下載APK,下載完成直接彈出安裝界面,同時記錄APK存儲路徑;待下次啟動時,檢查刪除APK。

源碼:DownloadManager_jb51.rar

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 玉龙| 临清市| 莱阳市| 黎平县| 谷城县| 亳州市| 商都县| 鸡泽县| 武胜县| 钟山县| 太仆寺旗| 靖西县| 阿拉善盟| 安西县| 崇左市| 湖口县| 曲阳县| 石屏县| 闽侯县| 香河县| 巴南区| 宜黄县| 拉孜县| 漠河县| 广饶县| 桂阳县| 元阳县| 富锦市| 綦江县| 宝坻区| 宁明县| 连云港市| 灵山县| 梅州市| 荣昌县| 盖州市| 东阿县| 武宁县| 平顺县| 平舆县| 嘉禾县|