Android 安装Apk
在开发过程中,很多时候都需要我们的应用安装Apk,其实这很简单的,但是其中还是有一些坑,所以记录下。
权限
要让我们的应用能够安装Apk,我们要在AndroidManifest.xml
中添加android.permission.REQUEST_INSTALL_PACKAGES
权限,而且用户必须要开启“未知来源”权限。在Android 8.0以前,“未知来源”权限是针对所有应用的,只要打开了,所有的应用都可以安装Apk;但是在Android 8.0以后,google出于安全的考虑,将该权限改为只针对单个应用了,即你的应用要安装Apk你就必须为你的应用申请权限,并且用户为你的应用开启了权限,你的应用才可以安装Apk。这个权限你不用特意的引导用户开启,因为系统已经帮我们做了这件事了,只要你调用安装Apk的方法,系统就会引导用户去开启该权限,你要做的就是在注册表中加入该权限。
安装Apk
先上代码:
/**
* 安装APK
*/
fun installApk(context:Context, path: String) {
val file = File(path)
chmod777(file)
var uri = Uri.fromFile(file)
val intent = Intent(Intent.ACTION_VIEW)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
//7.0及以上需要做特殊处理
if (Build.VERSION.SDK_INT >= 24) {
//添加这一句表示对目标应用临时授权该Uri所代表的文件
uri = FileProvider.getUriForFile(AMCCleaner.context, "com.test.fileprovider", file)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
intent.setDataAndType(uri, "application/vnd.android.package-archive")
context.startActivity(intent)
}
首先,调用chmod777(file)
函数将该Apk文件改为可读可写。然后将该文件转化为Uri,创建Intent并设置Intent的action为Intent.ACTION_VIEW
,为Intent设置setDataAndType为intent.setDataAndType(uri, "application/vnd.android.package-archive")
,最后,调用startActivity(intent)
开始安装Apk。现在有的同学应该不知道Android 7.0以上添加的那两句代码是干嘛,这是因为Android 7.0强制启用了被称作 StrictMode的策略,带来的影响就是你的App对外无法暴露file://类型的URI了,所以我们要使用FileProvider,即要在Android 7.0以后加上面的两句代码。当然你还要在注册表中添加如下的代码:
<!-- 7.0调用安装程序 -->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.test.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<!-- 元数据 -->
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/app_file_paths"/>
</provider>
这里需要注意,authorities的值必须和代码中FileProvider.getUriForFile
函数的第二个参数的值保持一致。同时我们可以看到在<meta-data>
中的resource定义了一个资源路径,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external_files"
path=""/>
<files-path
name="files_path"
path=""/>
</paths>
在这个文件中,为每个目录添加一个XML元素指定目录。
paths 可以添加多个子路径:
<files-path>
分享app内部的存储;<external-path>
分享外部的存储;<cache-path>
分享内部缓存目录。
以上就是安装Apk的全部类容了,在写的时候注意权限和7.0以上的不同就可以了。