基于DownloadManager的簡(jiǎn)單下載器編寫小結(jié)
一直聽說過Android自帶的DownloadManager,只是拖延癥發(fā)作,一直沒有時(shí)間去研究研究,其實(shí)在很多項(xiàng)目開發(fā)中,都有一個(gè)功能是非常重要的,那就是應(yīng)用的檢查更新了!基于DownloadManager,可以做一個(gè)輕量級(jí)的下載器,將下載任務(wù)交給系統(tǒng)去執(zhí)行,減輕自身APP的壓力,何樂而不為呢?!
DownloadManager的基本使用姿勢(shì)
通過getSystemService進(jìn)行實(shí)例化
DownloadManager downloadManager = (DownloadManager)context.getSystemService(Context.DOWNLOAD_SERVICE);
構(gòu)建下載請(qǐng)求
DownloadManager.Request request = new DownloadManager.Request(Uri.parse("目標(biāo)文件下載地址"));
//設(shè)置目標(biāo)文件夾,如果你想在系統(tǒng)的storage目錄下載一個(gè)testDownload/test/test.apk
request.setDestinationInExternalPublicDir("testDownload", "test/test.apk");
//設(shè)置下載所需的網(wǎng)絡(luò)環(huán)境,設(shè)置了移動(dòng)網(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);
否則將會(huì)拋出一個(gè)securityException
//設(shè)置文件類型為apk類型,當(dāng)downloadManager調(diào)用openFile時(shí)會(huì)喚起相應(yīng)的程序
request.setMimeType("application/cn.trinea.download.file");
//開始下載,得到一個(gè)唯一的downloadId,大有用處
long downloadId = downloadManager.enqueue(request);
如何獲取下載的情況呢
private int[] getBytesAndStatus(long downloadId) {
//構(gòu)建一個(gè)數(shù)組,存放已下載文件大小、總大小、下載狀態(tài)
int[] bytesAndStatus = new int[]{
-1, -1, 0
};
//通過構(gòu)建下載請(qǐng)求時(shí)獲得的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;
}
注冊(cè)監(jiān)聽文件下載成功的廣播
private BroadcastReceiver downloadCompleteReceiver;
downloadCompleteReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//文件下載成功時(shí)
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;
}
}
}
};
//注冊(cè),這里只能攔截文件下載成功的廣播,并不能進(jìn)行進(jìn)度監(jiān)聽,在適當(dāng)?shù)牡胤饺∠嗛啅V播
context.registerReceiver(downloadCompleteReceiver,
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
網(wǎng)上很多博客都是通過自定義ContentObserver獲取本地文件變化,其實(shí)可以另辟蹊徑,通過一個(gè)定時(shí)器間隔調(diào)用以上getBytesAndStatus(long downloadId)能達(dá)到同樣的效果,用Rxjava實(shí)現(xiàn)一個(gè)簡(jiǎn)單的定時(shí)器
/**
* 由于DownloadManager自身沒有提供實(shí)時(shí)進(jìn)度的api,所以通過以下定時(shí)器獲取已下載的文件大小
*/
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基本的使用方式,那么基于它來封裝一個(gè)簡(jiǎn)單易用的下載器吧!
實(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ù)下載同樣的文件時(shí),本地檢測(cè)是否存在同樣的文件,進(jìn)行回調(diào)
}
});
DownloadHelper downloadHelper = builder.build();
//開始下載
downloadHelper.start();
//移除下載任務(wù)
downloadHelper.deleteDownloadFile();
源碼請(qǐng)到https://github.com/yuwenque/SimpleDownloadHelper.git
- DownloadManager實(shí)現(xiàn)文件下載功能
- Android基于自帶的DownloadManager實(shí)現(xiàn)下載功能示例
- Android中DownloadManager實(shí)現(xiàn)文件下載實(shí)例詳解
- android中DownloadManager實(shí)現(xiàn)版本更新,監(jiān)聽下載進(jìn)度實(shí)例
- Android開發(fā)之自帶下載器DownloadManager的使用示例代碼
- 使用Android系統(tǒng)提供的DownloadManager來下載文件
- Android中使用DownloadManager類來管理數(shù)據(jù)下載的教程
相關(guān)文章
實(shí)例詳解android studio如何導(dǎo)入.so文件的方法
通過實(shí)例給大家詳細(xì)講解了如何在android studio如何導(dǎo)入.so文件以及中間遇到的問題解決辦法,需要的讀者們可以仔細(xì)學(xué)習(xí)一下。2017-12-12
Android Studio實(shí)現(xiàn)簡(jiǎn)單計(jì)算器APP
這篇文章主要為大家詳細(xì)介紹了Android Studio實(shí)現(xiàn)簡(jiǎn)單計(jì)算器APP,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03
android自定義彈出框樣式的實(shí)現(xiàn)方法
這篇文章主要為大家詳細(xì)介紹了android自定義彈出框樣式的實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
Android Studio實(shí)現(xiàn)標(biāo)題欄和狀態(tài)欄的隱藏
這篇文章主要介紹了Android Studio實(shí)現(xiàn)標(biāo)題欄和狀態(tài)欄的隱藏功能,在文中給大家補(bǔ)充介紹了android studio 去掉標(biāo)題欄狀態(tài)欄的完整代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧2017-11-11
使用Chrome瀏覽器調(diào)試Android App詳解
這篇文章主要介紹了使用Chrome瀏覽器調(diào)試Android App詳解,本網(wǎng)講解了使用Facebook開源Stetho實(shí)現(xiàn)在Chrome中調(diào)試Android App中,需要的朋友可以參考下2015-05-05
Android官方的側(cè)滑控件DrawerLayout的示例代碼
這篇文章主要介紹了Android官方的側(cè)滑控件DrawerLayout的示例代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09
Android UI控件之ImageSwitcher實(shí)現(xiàn)圖片切換效果
這篇文章主要為大家詳細(xì)介紹了Android UI控件之ImageSwitcher實(shí)現(xiàn)圖片切換效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Android重力傳感器實(shí)現(xiàn)滾動(dòng)的彈球
所謂傳感器能夠探測(cè)如光、熱、溫度、重力、方向 等等的功能,本文給大家介紹Android傳感器應(yīng)用之重力傳感器實(shí)現(xiàn)滾動(dòng)的彈球,對(duì)android重力傳感器相關(guān)知識(shí)感興趣的朋友一起看看吧2015-12-12

