Android下载管理DownloadManager功能扩展和bug修改

2023-10-24 04:08

本文主要是介绍Android下载管理DownloadManager功能扩展和bug修改,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


本文主要介绍如何修改Android系统下载管理,以支持更多的功能及部分bug修改和如何编译生效。目前内容包括暂停下载、继续下载、通知设置NotiExtra和NotiClass、wifi切换到3g自动暂停、Bug修改。

 

PS: 很多童鞋不是自己做rom,所以就算修改了系统源码编译出来的包在其他系统上也不通用
这里推荐DownloadProvider@Github(并不是我的开源项目,我的项目为TrineaAndroidCommon@Github,包含图片缓存,下拉刷新,静默安装等,欢迎关注^_^),系统下载管理的独立版,可整合进自己的应用,感谢@DONG童鞋提供地址。

 

下面需要修改的DownloadManager.java所在目录为frameworks/base/core/java/android/app
DownloadInfo.java, DownloadProvider.java,DownloadThread.java文件所在目录为packages/providers/DownloadProvider/src/com/android/providers/downloads

 

1、暂停、继续下载功能
(1) DownloadProvider类修改

public int update(final Uri uri, final ContentValues values, final String where, final String[] whereArgs)

函数,修改后代码如下(只增加了一行有效代码):

if (Binder.getCallingPid() != Process.myPid()) {filteredValues = new ContentValues();copyString(Downloads.Impl.COLUMN_APP_DATA, values, filteredValues);copyInteger(Downloads.Impl.COLUMN_VISIBILITY, values, filteredValues);Integer i = values.getAsInteger(Downloads.Impl.COLUMN_CONTROL);if (i != null) {filteredValues.put(Downloads.Impl.COLUMN_CONTROL, i);startService = true;}// trinea BEGIN, added by trinea@trinea.cn 2013/03/01copyInteger(Downloads.Impl.COLUMN_STATUS, values, filteredValues);// trinea ENDcopyInteger(Downloads.Impl.COLUMN_CONTROL, values, filteredValues);copyString(Downloads.Impl.COLUMN_TITLE, values, filteredValues);copyString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI, values, filteredValues);copyString(Downloads.Impl.COLUMN_DESCRIPTION, values, filteredValues);copyInteger(Downloads.Impl.COLUMN_DELETED, values, filteredValues);
} else {

其中以// trinea BEGIN开头,// trinea END结尾为修改部分,下面代码示例同样如此。因为DownloadProvider安全策略对非该进程id的修改会过滤掉COLUMN_STATUS状态,所以我们需要添加该行。

 

(2) DownloadThread类修改

private void setupDestinationFile ( State state , InnerState innerState )

函数中这个注释掉一个else if,如下:

// trinea BEGIN, noted by trinea@trinea.cn 2013/03/01
//} else if (mInfo.mETag == null && !mInfo.mNoIntegrity) {
//    // This should've been caught upon failure
//    if (Constants.LOGVV) {
//        Log.d(TAG, "setupDestinationFile() unable to resume download, deleting "
//                + state.mFilename);
//    }
//    f.delete();
//    throw new StopRequestException(Downloads.Impl.STATUS_CANNOT_RESUME,
//            "Trying to resume a download that can't be resumed");
// trinea END

上面一段代码表示一个验证过程,可以去掉。

mETag为数据库中的etag字段值,代码中没有解释,感觉是一个验证值,类似hashcode。
mNoIntegrity为数据中no_integrity字段值,表示启动下载的应用程序能否验证下载的文件的完整性。不过坑爹的是对于etag和no_integrity都没有提供设置的接口

 

(3) DownloadManager类中添加对外接口

DownloadManager中添加暂停、继续接口

/*** pause download, added by trinea@trinea.cn 2013/03/01* * @param ids the IDs of the downloads to be paused* @return the number of downloads actually paused*/
public int pauseDownload(long... ids) {if (ids == null || ids.length == 0) {// called with nothing to remove!throw new IllegalArgumentException("input param 'ids' can't be null");}ContentValues values = new ContentValues();values.put(Downloads.Impl.COLUMN_CONTROL, Downloads.Impl.CONTROL_PAUSED);values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_PAUSED_BY_APP);if (ids.length == 1) {return mResolver.update(ContentUris.withAppendedId(mBaseUri, ids[0]), values,null, null);} return mResolver.update(mBaseUri, values, getWhereClauseForIds(ids),getWhereArgsForIds(ids));
}/*** resume download, added by trinea@trinea.cn 2013/03/01* * @param ids the IDs of the downloads to be resumed* @return the number of downloads actually resumed*/
public int resumeDownload(long... ids) {if (ids == null || ids.length == 0) {// called with nothing to remove!throw new IllegalArgumentException("input param 'ids' can't be null");}ContentValues values = new ContentValues();values.put(Downloads.Impl.COLUMN_CONTROL, Downloads.Impl.CONTROL_RUN);values.put(Downloads.Impl.COLUMN_STATUS, Downloads.Impl.STATUS_RUNNING);if (ids.length == 1) {return mResolver.update(ContentUris.withAppendedId(mBaseUri, ids[0]), values,null, null);} return mResolver.update(mBaseUri, values, getWhereClauseForIds(ids),getWhereArgsForIds(ids));
}

无论是暂停还是继续我们都是同时把Downloads.Impl.COLUMN_CONTROL和Downloads.Impl.COLUMN_STATUS字段进行修改,因为在DownloadInfo的 private boolean isReadyToStart(long now) 函数中,会对COLUMN_CONTROL字段进行判断,如果是用户手动暂停的话,是不会自动继续的,部分代码如下:

private boolean isReadyToStart(long now) {if (DownloadHandler.getInstance().hasDownloadInQueue(mId)) {// already runningreturn false;}if (mControl == Downloads.Impl.CONTROL_PAUSED) {// the download is paused, so it's not going to startXlog.i(Constants.DL_ENHANCE, "Download is paused " +"then no need to start");return false;}……
}

之后我们直接调用DownloadManager的pauseDownload和resumeDownload接口即可

 

PS:也可以试试不做第二步的修改,而将第一步DownloadProvider的update函数修改变为

// trinea BEGIN, added by trinea@trinea.cn 2013/03/01
copyInteger(Downloads.Impl.COLUMN_STATUS, values, filteredValues);
copyInteger(Downloads.Impl.COLUMN_NO_INTEGRITY, values, filteredValues);
// trinea END

第二步修改变为在public int resumeDownload(long… ids)加入

没有亲自试,不过按照逻辑应该也可以。

 

2、通知栏可以设置NotiExtra和NotiClass

(1) DownloadProvider类中修改private void checkInsertPermissions(ContentValues values)函数

在DownloadProvider insert之前会调用checkInsertPermissions检查不能被插入的字段插入,这里我们需要允许这两个字段存在。

 

(2) DownloadManager.Request添加对外接口

在Request中添加接口以及允许字段修改。通过允许设置NotiExtra和NotiClass,我们可以给系统传递更丰富的参数,在通知栏点击相应或是DownloadUi中通过broadcast将这些参数传递出来方便应用调用。

 

3、wifi切换到3g自动暂停
(1) 修改DownloadInfo.java

表示等待网络时始终只等待wifi

 

(2) 修改DownloadReceiver.java

修改为:

表示只有连接wifi时才唤醒service去检查是否下载

 

(3) 修改DownloadThread.java

表示如果网络变化并且表示网络断开时,下载状态变为等待网络。

 

4、Bug修改
(1) 当存储空间不足时,利用DownloadManager下载,只显示通知栏提示,在下载管理UI中不显示
DownloadManager的Cursor runQuery(ContentResolver resolver, String[] projection, Uri baseUri)函数修改如下:

DownloadManager的CursorTranslator类的private int translateStatus(int status) 函数修改如下:

 

5、编译安装

修改后是需要重新编译的,需同时编译framweork和DownloadProvider。

framework编译命令为:./makeMtk model mm frameworks/base/core/
编译后apk所在路径为out\target\product\model\system\framework\secondary_framework.jar,之后push到system/framework重启即可。编译命令中model为机型,非mtk平台命令有所不同

 

DownloadProvider编译命令为./makeMtk model mm packages/providers/DownloadProvider/
编译后apk所在路径为out\target\product\model\system\app\DownloadProvider.apk,之后push到system/app即可(可能需要先删除/system/app/目录下的DownloadProvider.odex)




这篇关于Android下载管理DownloadManager功能扩展和bug修改的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/272577

相关文章

Spring Boot整合Redis注解实现增删改查功能(Redis注解使用)

《SpringBoot整合Redis注解实现增删改查功能(Redis注解使用)》文章介绍了如何使用SpringBoot整合Redis注解实现增删改查功能,包括配置、实体类、Repository、Se... 目录配置Redis连接定义实体类创建Repository接口增删改查操作示例插入数据查询数据删除数据更

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

使用EasyPoi快速导出Word文档功能的实现步骤

《使用EasyPoi快速导出Word文档功能的实现步骤》EasyPoi是一个基于ApachePOI的开源Java工具库,旨在简化Excel和Word文档的操作,本文将详细介绍如何使用EasyPoi快速... 目录一、准备工作1、引入依赖二、准备好一个word模版文件三、编写导出方法的工具类四、在Export

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

在Node.js中使用.env文件管理环境变量的全过程

《在Node.js中使用.env文件管理环境变量的全过程》Node.js应用程序通常依赖于环境变量来管理敏感信息或配置设置,.env文件已经成为一种流行的本地管理这些变量的方法,本文将探讨.env文件... 目录引言为什么使php用 .env 文件 ?如何在 Node.js 中使用 .env 文件最佳实践引

C#实现高性能拍照与水印添加功能完整方案

《C#实现高性能拍照与水印添加功能完整方案》在工业检测、质量追溯等应用场景中,经常需要对产品进行拍照并添加相关信息水印,本文将详细介绍如何使用C#实现一个高性能的拍照和水印添加功能,包含完整的代码实现... 目录1. 概述2. 功能架构设计3. 核心代码实现python3.1 主拍照方法3.2 安全HBIT

python库pydantic数据验证和设置管理库的用途

《python库pydantic数据验证和设置管理库的用途》pydantic是一个用于数据验证和设置管理的Python库,它主要利用Python类型注解来定义数据模型的结构和验证规则,本文给大家介绍p... 目录主要特点和用途:Field数值验证参数总结pydantic 是一个让你能够 confidentl

录音功能在哪里? 电脑手机等设备打开录音功能的技巧

《录音功能在哪里?电脑手机等设备打开录音功能的技巧》很多时候我们需要使用录音功能,电脑和手机这些常用设备怎么使用录音功能呢?下面我们就来看看详细的教程... 我们在会议讨论、采访记录、课堂学习、灵感创作、法律取证、重要对话时,都可能有录音需求,便于留存关键信息。下面分享一下如何在电脑端和手机端上找到录音功能

Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧

《Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧》本文将通过实际代码示例,深入讲解Python函数的基本用法、返回值特性、全局变量修改以及异常处理技巧,感兴趣的朋友跟随小编一起看看... 目录一、python函数定义与调用1.1 基本函数定义1.2 函数调用二、函数返回值详解2.1 有返

Nginx屏蔽服务器名称与版本信息方式(源码级修改)

《Nginx屏蔽服务器名称与版本信息方式(源码级修改)》本文详解如何通过源码修改Nginx1.25.4,移除Server响应头中的服务类型和版本信息,以增强安全性,需重新配置、编译、安装,升级时需重复... 目录一、背景与目的二、适用版本三、操作步骤修改源码文件四、后续操作提示五、注意事项六、总结一、背景与