下载
1. 获取 DownloadManager 对象
DownloadManager对象 属于系统服务,通过 getSystemService 来进行安装
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
一般获取完成后会变成全局变量,方便之后使用
2. 开始下载
在使用 DownloadManager 进行下载的时候,就会用到 DownloadManager.Request
首先会创建出一个 DownloadManager.Request对象,在构造方法中接收 Uri,其实就是下载地址.
然后是文件的存放路径,这里需要说明,DownloadManager 下载的位置是不能放到内置存贮位置的,必须放到 Enviroment 中,这里建议放到自己应用的文件夹,不要直接放到 SD卡 中,也就是通过 getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) 获取到的路径,该位置的文件是属于应用自己的,在应用卸载时也会随着应用一起被删除掉,并且在使用该文件夹的时候,是不需要 SD卡 读写权限的
然后通过 request.setDestinationUri 来设置存储位置,最后将请求加入到 downloadManager 中,会获得一个 downloadID,这个 downloadID 比较重要,之后下载状态,进度的查询都靠这个 downloadID
进度查询
在查询下载进度的时候,会通过 downloadId 来指定查询某一任务的具体进度:
在查询进度的时候会使用到 DownloadManager.Query 这个类,在查询的时候,也是使用的 Cursor,跟查询数据库是一样的,进度信息会需要拿到文件的总大小,和当前大小,自己算一下,最后 Cursor对象 在使用过后不要忘记关闭了
下载完成
下载完成后,DownloadManager 会发送一个广播,并且会包含 downloadId 的信息:
注册这个广播接收者
其他
这里需要注意一点,在下载完成后需要提升一下文件的读写权限,否则在安装的时候会出现apk解析失败的页面,就是别人访问不了我们的apk文件
chmod 是Linux下设置文件权限的命令,后面的三个数字每一个代表不同的用户组
权限分为三种:读(r=4),写(w=2),执行(x=1)
那么这三种权限就可以组成7种不同的权限,分别用1-7这几个数字代表,例如7 = 4 + 2 + 1,那么就代表该组用户拥有可读,可写,可执行的权限;5 = 4 + 1,就代表可读可执行权限
而三位数字就带包,该登陆用户,它所在的组,以及其他人
安装
普通模式
-
7.0之前
在7.0之前安装的时候,只需要通过 隐式Intent 来跳转,并且指定安装的文件 Uri 即可
-
7.0之后
在Android7.0之后的版本运行上述代码会出现 android.os.FileUriExposedException
“私有目录被限制访问”是指在 Android7.0 中为了提高私有文件的安全性,面向 Android N 或更高版本的应用私有目录将被限制访问。
而7.0的” StrictMode API 政策” 是指禁止向你的应用外公开 file:// URI。 如果一项包含文件 file:// URI类型 的 Intent 离开你的应用,应用失败,并出现 FileUriExposedException 异常。之前代码用到的Uri.fromFile就是商城一个file://的Uri 在7.0之后,我们需要使用 FileProvider 来解决
第一步:在 AndroidManifest.xml 清单文件中注册 provider
需要注意一下几点:
-
exported:必须为 false
-
grantUriPermissions : true,表示授予 URI 临时访问权限。
-
authorities 组件标识,都以包名开头,避免和其它应用发生冲突。
第二步: 指定共享文件的目录,需要在 res文件夹 中新建 xml 目录,并且创建 file_paths
path=”“,是有特殊意义的,它代表根目录,也就是说你可以向其它的应用共享根目录及其子目录下任何一个文件了。
第三步:使用 FileProvider
相较于之前的代码,会把 Uri 改成使用 FiliProvider 创建的 Uri,并且添加 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) 来对目标应用临时授权该 Uri 所代表的文件,而且 getUriForFile 中的 authority 参数需要填写清单文件中的 authorities 的值
-
混合
兼容 7.0 的安装代码是不能在 7.0 之前的版本运行的,这个时候就需要进行版本的判断了:
root模式
如果应用已经获取了 root 权限了,那么我们可以实现自动安装,即不会出现应用安装的页面,会在后台自己慢慢的安装,这个时候使用的就是用代码去写命令行了
这个方法就是将命令写入到手机的 shell 中,su 就代表 root 权限了,而命令执行成功的话,会返回0的,接下来是安装命令
String command = "pm install -r " + mApkPath;
-r 代表强制安装,否则如果手机中已有该应用的话就会安装失败了,值得注意的是,要想等待命令执行的结果这个过程是很漫长的,所以在使用命令的时候是需要放到主线程中的
整体项目
在写完整代码的时候需要把下载的代码写到 Service 中,否则你的 downloadid 就得通过别的方式去存储了,而查询下载进度,也是需要一直去查了,那么就需要写一个循环,并且放到子线程中,我们用 RxJava 做会比较舒服
本文详细介绍如何在Android应用中实现文件下载功能,包括使用DownloadManager进行下载操作、下载进度查询、下载完成后的权限设置及不同Android版本下的安装流程。
8057

被折叠的 条评论
为什么被折叠?



