Android 开发学习进程0.32 dwonloadmanager使用
downloadmanager时Android系统下载器,使用系统下载器可以避免用stream流读入内存可能导致的内存溢出问题。以下为downloadmanager初始化部分。apkurl为下载网络路径。Environment.DIRECTORY_DOWNLOADS 为系统的下载路径。即下载至外部存储。
mDownloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
String apkUrl = "https://qd.myapp.com/myapp/qqteam/AndroidQQ/mobileqq_android.apk";
Uri resource = Uri.parse(apkUrl);
DownloadManager.Request request = new DownloadManager.Request(resource);
//下载的本地路径,表示设置下载地址为SD卡的Download文件夹,文件名为mobileqq_android.apk。
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "mobileqq_android.apk");
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE | DownloadManager.Request.NETWORK_WIFI);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setVisibleInDownloadsUi(true);
request.setDescription("xiazaizhong");
//end 一些非必要的设置
id = mDownloadManager.enqueue(request);
//下载后的本地uri
uri = mDownloadManager.getUriForDownloadedFile(id);
enqueue方法为添加到下载队列,同时返回的id用于contentobserver监听下载进度.下载进度监听代码如下:
private DownloadContentObserver observer = new DownloadContentObserver();
class DownloadContentObserver extends ContentObserver {
public DownloadContentObserver() {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
// updateView();
if (scheduledExecutorService != null) {
scheduledExecutorService.scheduleWithFixedDelay(runnable, 0, 3, TimeUnit.SECONDS);
}
}
}
public static ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
public void updateView() {
int[] bytesAndStatus = getBytesAndStatus(id);
int currentSize = bytesAndStatus[0];//当前大小
int totalSize = bytesAndStatus[1];//总大小
int status = bytesAndStatus[2];//下载状态 1开始 2下载中 8下载完成
Message.obtain(handler, 0, currentSize, totalSize, status).sendToTarget();
}
public int[] getBytesAndStatus(long downloadId) {
int[] bytesAndStatus = new int[]{-1, -1, 0};
DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
Cursor c = null;
try {
c = mDownloadManager.query(query);
if (c != null && c.moveToFirst()) {
bytesAndStatus[0] = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR));
bytesAndStatus[1] = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_TOTAL_SIZE_BYTES));
bytesAndStatus[2] = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
}
} finally {
if (c != null) {
c.close();
}
}
return bytesAndStatus;
}
设置 DownloadContentObserver类监听下载进度,可在其重写的 onchange方法中更新UI,即updataView方法,但此会返回大量数据,在下载量大时可使用ScheduledExecutorService 设定定时任务,注册定时任务设定间隔时间查询进度,downloadcontentobserver需要在onresume 和 ondestroy方法中注册和注销代码在下,getBytesAndStatus方法获取队列中数组当前下载的进度 包括当前大小总大小,下载状态等。
注销和注册downloadcontentobserver的代码
private static final Uri CONTENT_URI = Uri.parse("content://downloads/my_downloads");
getContentResolver().registerContentObserver(CONTENT_URI, true, observer);
getContentResolver().unregisterContentObserver(observer);
定时任务中执行的runable 为更新UI的 updateView方法
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
updateView();
} catch (Exception e) {
e.printStackTrace();
}
}
};
最后即是updateView方法中发送message的handeler代码,message可传入两个bundle参数和一个object对象。从handler中取出可以更新UI 或逻辑操作了,注意声明handler时传入了 mainlooper,这样不用再特地主线程中更新UI,测试中下载完成时状态码为8,具体使用时可再次测试。下载结束后可将定时任务关闭置空。
private Handler handler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(@NonNull @NotNull Message msg) {
super.handleMessage(msg);
if (scheduledExecutorService != null) {
int currentSize = msg.arg1;
int totalSize = msg.arg2;
Object object = msg.obj;
tvDownload.setText(String.valueOf(((float) (currentSize / totalSize)) * 100));
if ((Integer) object == 8) {
scheduledExecutorService.shutdownNow();
scheduledExecutorService = null;
Toast.makeText(ControlerActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
}
Log.e(TAG, "handleMessage:" + currentSize + " " + totalSize + " " + object.toString());
}
}
};
最后测试下载的本地的uri是否正确,文件下载是否成功 Environment.getExternalStoragePublicDirectory获取外部存储的下载路径。还有下载完成点击通知跳转和下载完成监听功能不再详述。
File file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+"/mobileqq_android.apk");
if (file.exists()) {
Log.e(TAG, "exists yes"+file.length());
}else {
Log.e(TAG, "exists no" );
}
Android 开发学习进程0.32 dwonloadmanager使用的更多相关文章
- Android 开发学习进程0.16 layout_weight属性 R文件关联XML Module
layout_weight属性 layout_weight属性我们常常用到,但有时候会发现它还有一些奇怪的属性,比如大多数使用时会把宽度设置成0,但要是宽度不设置成0会有什么效果? layout_we ...
- Android 开发学习进程0.19 webview 的使用
Android 中的webview android 中的webview是可以在app内部打开HTML等的网页,不必再打开浏览器,有两种实现方法,即webviewclient webChromeclie ...
- Android开发学习进程0.18 SharePreference的使用 AIDL
SharePreference SharePreference是一种持久化存储手段,使用场景很多,如第一次打开时加载的用户协议等.适合小数据单进程的应用.将数据以键值对的形式存储在XML中. 使用方式 ...
- Android 开发学习进程0.17 Android资源文件selector textview显示两种不同字体
selector 是安卓资源文件的一种,它可以使按钮等实现不同状态下的不同UI,不用在代码中实现,而使用方式有两种,一种在color文件下 创建.xml可以使按钮等字体在不同状态下的变化,其二是在dr ...
- Android 开发学习进程0.15 adb cardview framelayout 控件设置状态获取焦点
Android设备调试桥 即adb 使用adb进行无线调试的一些常用命令 adb tcpip 5555 设置调试端口为5555 防止冲突 adb shell ifconfig wlan0 查询局域网中 ...
- Android 开发学习进程0.27 kotlin使用 和viewbinding的使用
kotlin-android-extensions 插件被废弃 笔者曾经尝试写过一部分的kotlin代码 主要是项目中一些代码是kotlin完成的,其中我认为 kotlin的kotlin-androi ...
- Android 开发学习进程0.28 腾讯TBS接入和相关问题
TBS 的接入和使用 TBS 的接入 腾讯TBS是X5内核的升级版,可以当作webview 来打开 网页,可以以用来打开docx doc pdf 等文件,这里主要使用的是文件功能. 依赖接入 api ...
- Android 开发学习进程0.14 Bindview recyclerview popwindow使用 window类属性使用
BindView ButterKnife 优势 绑定组件方便,使用简单 处理点击事件方便,如adapter中的viewholder 同时父组件绑定后子组件无需绑定 注意 在setcontentview ...
- Android 开发学习进程0.13 Androidstudio快捷键 xmlns
xmlns XML namespace xml命名空间 其中主要是定义xml文件定义位置 前缀有三种,android app tools 后面为唯一标识符URI android 表示为引用自安卓系统 ...
随机推荐
- Mybatis Plus 多租户架构实现(完美教程)
一.背景介绍 多租户技术或称多重租赁技术,简称SaaS,是一种软件架构技术,是实现如何在多用户环境下(此处的多用户一般是面向企业用户)共用相同的系统或程序组件,并且可确保各用户间数据的隔离性. 简单讲 ...
- [leetcode] 39. 组合总和(Java)(dfs、递归、回溯)
39. 组合总和 直接暴力思路,用dfs+回溯枚举所有可能组合情况.难点在于每个数可取无数次. 我的枚举思路是: 外层枚举答案数组的长度,即枚举解中的数字个数,从1个开始,到target/ min(c ...
- 查询rman备份信息常用指令
查询rman备份信息常用指令 ----登陆到rman $rman target / ----以精简的格式查看备份信息 RMAN> list backup of database summar ...
- BERT模型的OneFlow实现
BERT模型的OneFlow实现 模型概述 BERT(Bidirectional Encoder Representations from Transformers)是NLP领域的一种预训练模型.本案 ...
- 闵可夫斯基引擎Minkowski Engine
闵可夫斯基引擎Minkowski Engine Minkowski引擎是一个用于稀疏张量的自动微分库.它支持所有标准神经网络层,例如对稀疏张量的卷积,池化,解池和广播操作.有关更多信息,请访问文档页面 ...
- 如何在小型pcb的移动设备上获得更好的无线性能
如何在小型pcb的移动设备上获得更好的无线性能 How to get better wireless performance for mobile devices with small PCBs 小型 ...
- h265webplayer
h265webplayer https://github.com/ksvc/h265webplayer h265webplayer是金山云的Web端H.265视频播放器,该播放器Web SDK让您可以 ...
- JavaFx 创建快捷方式及设置开机启动
原文地址:JavaFx 创建快捷方式及设置开机启动 | Stars-One的杂货小窝 原本是想整个桌面启动器,需要在windows平台上实现开机启动,但我的软件都是jar文件,不是传统的exe文件,也 ...
- OpenFeign远程调用原理
之前对OpenFeign 了解到只用在接口上面打个注解,然后就可以通过内部调用去调用远程地址.研究完Feign生成对象以及代理对象的作用过程之后发现这个过程用到了Spring的好多东西,在之后的过程中 ...
- 并发王者课-铂金2:豁然开朗-“晦涩难懂”的ReadWriteLock竟如此妙不可言
欢迎来到<并发王者课>,本文是该系列文章中的第15篇. 在上篇文章中,我们介绍了Java中锁的基础Lock接口.在本文中,我们将介绍Java中锁的另外一个重要的基本型接口,即ReadWri ...