最近在为Flutter端封装 下载apk并安装 的功能,众所周知,在安装之前我们要请求 ‘允许安装未知来源’ 这个权限,然后我就写了以下代码(部分代码)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val isHasPermission = activity.packageManager?.canRequestPackageInstalls() ?: false
if (!isHasPermission) {
intoManageUnknownAppPage(activity)
}
}
private fun intoManageUnknownAppPage(
activity: Activity,
apkFile: File? = null
) {
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
intent.data = Uri.parse("package:${activity.packageName}")
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
activity.startActivity(intent)
}
写完之后,在我Android 10.0的测试机上试了一下,很完美,然后公司的Mi TV也会用到这个东西,在测试的时候竟然崩溃了,我就开始寻找问题,最后竟然发现在 MiTV 上竟然没有这个权限界面更没有这个权限设置,大意了…
我思考了一下,是不是可以先检测它有没有这个界面,然后再走相应的流程,脑子:可以的,手:你行你来,它俩打了一架,写出以下代码
try {
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
intent.data = Uri.parse("package:${activity.packageName}")
//这一步就是校验有没有这个Activity,如果没有就为null
val resolveActivity = intent.resolveActivity(activity.packageManager)
//如果为null的话可以直接去走安装,亲测可行
if (resolveActivity == null) {
toInstallApk(activity, apkFile)
return
}
} catch (e: RuntimeException) {
smartLog { e.printStackTrace() }
toInstallApk(activity, apkFile)
return
}
二、Android 11及以上的变动
本以为上面的代码可以愉快的运行,结果我拿出了一台Android 11的机器后…它正常的跳转到了权限管理界面,但是在我同意之后,进程竟然崩溃了,这让我百思不得其解。然后开始面向百度编程,很多人包括官方说这就是Android 11的变更,获取 ‘允许安装未知来源’ 权限将不再简单,改变它的状态将会时应用进程结束。但是没有人给出解决方案…
我又开始了漫长的搜索,终于,在一篇开源库的issue里找到了答案
顺便贴一下这位大佬的项目 app_installer
文归正传,在看了大佬的方法之后,我们只需要作一点改动,即只需要将版本判断那里改成:
//是否大于等于Android 8.0 并小于 Android 11
private val installApkJudgeRule: Boolean
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.R
这样就达成了仅在固定版本内进入那个页面去开启权限
三、总结在这里我想把安装apk的规范总结一下
要判断当前机型是否存在 ‘允许安装未知来源权限’ 页面注意在跳转到 ‘允许安装未知来源权限’ 页面 的代码try catch一下第三就是要及时关注每个版本的变更最后推荐一下,个人写的开源项目,包含下载并安装apk(已处理权限请求)、Uri转realPath等功能,具体可以在这里查看:CommonHelper
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)