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使用的更多相关文章

  1. Android 开发学习进程0.16 layout_weight属性 R文件关联XML Module

    layout_weight属性 layout_weight属性我们常常用到,但有时候会发现它还有一些奇怪的属性,比如大多数使用时会把宽度设置成0,但要是宽度不设置成0会有什么效果? layout_we ...

  2. Android 开发学习进程0.19 webview 的使用

    Android 中的webview android 中的webview是可以在app内部打开HTML等的网页,不必再打开浏览器,有两种实现方法,即webviewclient webChromeclie ...

  3. Android开发学习进程0.18 SharePreference的使用 AIDL

    SharePreference SharePreference是一种持久化存储手段,使用场景很多,如第一次打开时加载的用户协议等.适合小数据单进程的应用.将数据以键值对的形式存储在XML中. 使用方式 ...

  4. Android 开发学习进程0.17 Android资源文件selector textview显示两种不同字体

    selector 是安卓资源文件的一种,它可以使按钮等实现不同状态下的不同UI,不用在代码中实现,而使用方式有两种,一种在color文件下 创建.xml可以使按钮等字体在不同状态下的变化,其二是在dr ...

  5. Android 开发学习进程0.15 adb cardview framelayout 控件设置状态获取焦点

    Android设备调试桥 即adb 使用adb进行无线调试的一些常用命令 adb tcpip 5555 设置调试端口为5555 防止冲突 adb shell ifconfig wlan0 查询局域网中 ...

  6. Android 开发学习进程0.27 kotlin使用 和viewbinding的使用

    kotlin-android-extensions 插件被废弃 笔者曾经尝试写过一部分的kotlin代码 主要是项目中一些代码是kotlin完成的,其中我认为 kotlin的kotlin-androi ...

  7. Android 开发学习进程0.28 腾讯TBS接入和相关问题

    TBS 的接入和使用 TBS 的接入 腾讯TBS是X5内核的升级版,可以当作webview 来打开 网页,可以以用来打开docx doc pdf 等文件,这里主要使用的是文件功能. 依赖接入 api ...

  8. Android 开发学习进程0.14 Bindview recyclerview popwindow使用 window类属性使用

    BindView ButterKnife 优势 绑定组件方便,使用简单 处理点击事件方便,如adapter中的viewholder 同时父组件绑定后子组件无需绑定 注意 在setcontentview ...

  9. Android 开发学习进程0.13 Androidstudio快捷键 xmlns

    xmlns XML namespace xml命名空间 其中主要是定义xml文件定义位置 前缀有三种,android app tools 后面为唯一标识符URI android 表示为引用自安卓系统 ...

随机推荐

  1. 项目实践之工作流引擎基本文档!Activiti工作流框架中流程引擎API和服务详解

    流程引擎的API和服务 流程引擎API(ProcessEngine API)是与Activiti打交道的最常用方式 Activiti从ProcessEngine开始.在ProcessEngine中,可 ...

  2. CSS的起步

    初学CSS CSS语法规范 选择器{样式} 给谁改样式{改什么样式} 写在style标签里 健值对形式,分号结尾 color:red; <style> p { color:red; fon ...

  3. Zabbix企业分布式监控工具

    前言:在工作中常常需要对服务器进行监控,但是要选择一款合适监控软件可不容易,今天介绍下zabbix这款监控软件 一.Zabbix介绍1.Zabbix是一个企业级的.开源的.分布式的监控套件2.Zabb ...

  4. JVM-栈帧之局部变量表

    1.栈帧的内部结构 每个栈帧中存储着: 局部变量表(Local Variables) 操作数栈(Operand Stack)(或表达式栈) 动态链接(Dynamic Linking)(或指向运行时常量 ...

  5. NVIDIA GPU上的Tensor线性代数

    NVIDIA GPU上的Tensor线性代数 cuTENSOR库是同类中第一个GPU加速的张量线性代数库,提供张量收缩,归约和逐元素运算.cuTENSOR用于加速在深度学习训练和推理,计算机视觉,量子 ...

  6. nvGRAPH原理概述

    nvGRAPH原理概述 nvGRAPH的API参考分析. 简介 数据分析是高性能计算的不断增长的应用.许多高级数据分析问题可以称为图形问题.反过来,当今许多常见的图形问题也可以称为稀疏线性代数.这是N ...

  7. 多尺度目标检测 Multiscale Object Detection

    多尺度目标检测 Multiscale Object Detection 我们在输入图像的每个像素上生成多个锚框.这些定位框用于对输入图像的不同区域进行采样.但是,如果锚定框是以图像的每个像素为中心生成 ...

  8. windows 下安装Charles,破解,安装证书,设置可抓取https包

    参考地址: https://www.zzzmode.com/mytools/charles/ 一.下载后进行安装  二.安装后进行破解 按照参考中的链接破解即可 三.Charles在windows证书 ...

  9. 在Visual Studio 中使用git——标记(Tag)管理(十)

    在Visual Studio 中使用git--什么是Git(一) 在Visual Studio 中使用git--给Visual Studio安装 git插件(二) 在Visual Studio 中使用 ...

  10. LeetCode 每日一题「判定字符是否唯一」

    我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. 题目 ...