05/23
2013

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

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

更多下载相关开源项目可见  Android 下载

 

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类修改

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

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

 

(2) DownloadThread类修改

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

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

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

 

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

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

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

 

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

第二步修改变为在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)

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

145 thoughts on “Android下载管理DownloadManager功能扩展和bug修改

  1. Pingback: Android公共库——图片缓存 网络缓存 下拉及底部更多ListView 公共类 | 数据魔方

  2. DownloadProvider@Github 暂停有bugDownloadInfo.java函数void startIfReady(long now) 需要修改为 void startIfReady(long now) { synchronized (this) { if (!isReadyToStart(now)) { //设置了暂停就返回 return; } if (Constants.LOGV) { Log.v(Constants.TAG, “Service spawning thread to handle download ” + mId + ” mHasActiveThread=” + mHasActiveThread); } if (mHasActiveThread) { return; //throw new IllegalStateException(“Multiple threads on same download”); } if (mStatus != Downloads.STATUS_RUNNING) { mStatus = Downloads.STATUS_RUNNING; ContentValues values = new ContentValues(); values.put(Downloads.COLUMN_STATUS, mStatus); mContext.getContentResolver().update(getAllDownloadsUri(), values, null, null); if (Constants.LOGV) { Log.v(Constants.TAG, “Service startIfReady return ” + mId); } //比如在这里调用pauseDownload(),刚好暂停在这按下 //return; 在这里返回后,到下一次进入isReadyToStart()之前设置暂停下载,则不会再执行后边DownloadThread,下载状态会变更为正在下载,不会再开启下载线程 } DownloadThread downloader = new DownloadThread(mContext, mSystemFacade, this); mHasActiveThread = true; mSystemFacade.startThread(downloader); } }

  3. 我发现了一个bug,不知道作者你有发现吗?是下载大于100mb的文件,手动暂停,再手动继续,然后就会出现失败,要重新下载。原因:mismatched content length求解答

  4. 楼主你的这个downloadprovider可以直接拷贝过去用么?还有就是支持用户操作的暂停和继续下载吗?我看了没太懂。感觉好像要修改Android底层的源码是的。

  5. 我们的项目需要一个下载管理,可是我不会你的TrineaAndroidCommon@Github项目在我手机上无法运行你推荐的DownloadProvider@Github项目在我手机上总是下载失败,求楼主帮忙呀