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. 只需5分钟!一文读懂CSS布局(二) -- flex布局

    目录 简介 基本概念 容器属性 1. flex-direction 测试代码 2. flex-wrap 3. flex-flow 4. justify-content 5. align-items 6 ...

  2. System Verilog设计例化和连接

  3. Dubbo-admin安装测试

    1.下载dubbo-admin 下载地址 2.解压到本地 3.在项目目录下打包dubbo-admin 使用命令 mvn clean package -Dmaven.test.skip=true 第一次 ...

  4. CVPR2019:无人驾驶3D目标检测论文点评

    CVPR2019:无人驾驶3D目标检测论文点评 重读CVPR2019的文章,现在对以下文章进行点评. Stereo R-CNN based 3D Object Detection for Autono ...

  5. CountDownLatch原理详解

    介绍 当你看到这篇文章的时候需要先了解AQS的原理,因为本文不涉及到AQS内部原理的讲解. CountDownLatch是一种同步辅助,让我们多个线程执行任务时,需要等待线程执行完成后,才能执行下面的 ...

  6. TCPIP原理

    ------------恢复内容开始------------ OSI参考模型 osi参考模型结构 对等通信 注释: 每一层都有自己的协议 每一层都利用下层提供的服务与对等层通信 PDU=protoco ...

  7. 高吞吐、低延迟 Java 应用的 GC 优化实践

    本篇原文作者是 LinkedIn 的 Swapnil Ghike,这篇文章讲述了 LinkedIn 的 Feed 产品的 GC 优化过程,虽然文章写作于 April 8, 2014,但其中的很多内容和 ...

  8. java面试技巧及层次。

    不断的积累,从打算找工作之日起,就要坚持在每天闲暇之余学习其中几道题目,日积月累,等到出去面试时,一切都水到渠成,面试时就自然会游刃有余了. 答题时,先答是什么,再答有什么作用和要注意什么,这里给人的 ...

  9. 安卓开发(3)—1— Activity

    安卓开发(3)-1- Activity 3.1 Activity是什么: 在前面安卓概述中有提到,Activity是Android开发中的四大组件,所有在app里可以看到的东西都是Activity里面 ...

  10. c#将图片Image转换为内存流MemoryStream

    HttpWebResponse resp = (HttpWebResponse)wRequest.GetResponse(); Stream stream = resp.GetResponseStre ...