技术标签: 安卓 android android studio kotlin
最近在为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的变更,获取 ‘允许安装未知来源’ 权限将不再简单,改变它的状态将会时应用进程结束。但是没有人给出解决方案…
我又开始了漫长的搜索,终于,在一篇开源库的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的规范总结一下
最后推荐一下,个人写的开源项目,包含下载并安装apk(已处理权限请求)、Uri转realPath等功能,具体可以在这里查看:CommonHelper
import numpy as npimport numpy as npdef shulie(first,end,step): x = [] for i in np.arange(first, end,step): x.append(i) return xfirst --首个数字end--尾数字step--间隔...
const double eps = 1e-8;typedef list&lt;int&gt;::iterator liit;inline int sign(double d){ if(d &lt; -eps) return -1; return (d &gt; eps) ? 1 : 0;}struct point{ double x, y, z; point...
利用Toad管理本地数据库 利用Toad管理本地数据库,相对于使用sqlplus来说,要更加直观和方便,而且,更容易操作一些,对于某些大的表格,查询结果一目了然。总的来说,需要以下几步:第一步:安装本地数据库这个过程和一般的安装没什么区别,但要注意以下两点:1. 在安装数据库的时候有,“创建启动数据库(附加720MB)”,指定全局数据库名:myOrcl,以
前端笔记知识点整合之CSS(下) 一、浮动1.1 各个语言的主要知识点HTML:标签语义化(那么怎么样布局才是合理的?没有绝对的对和错)CSS: 样式: 布局: 标准流(标准文档流、普通文档流):盒子模型(width/height+padding+border+margin) 块元素行内元素 浮动...
subprocess.Popen阻塞
为什么80%的码农都做不了架构师?>>> ...
以评测的形式通过一个非常简单的例子,把ADO.NET与PowerBuilder进行多方面的比较,从而揭示两种平台下数据库应用开发能力,包括功能、性能、体系结构的综合评价。1. 评测对象描述 .NET框架提供了强大的WINDOWS FORMS 工具,可以快速开发用户界面。同时,.NET框架提供了丰富的对象用来管理数据库操作,这些类总称为ADO.NET,ADO.NET主要是一种
python 打印十六进制How to print integers in hexadecimal format in Python? 如何在Python中以十六进制格式打印整数? To print an integer i in hexadecimal format in Python: 要在Python中以十六进制格式打印整数i: print hex(i)Answered by anony...
9.4 Go 数据格式1.1. msgpack格式官方msgpack官网用一句话总结: It’s like JSON. but fast and small. 简单来讲,它的数据格式与json类似,但是在存储时对数字、多字节字符、数组等都做了很多优化,减少了无用的字符,二进制格式,也保证不用字符化带来额外的存储空间的增加。msgpack使用示例代码package ma...
<br />以前写博客主要是把自己感兴趣的东西存下来,没有思考,所以虽然数量不少,但没什么精品<br /> <br />写博客还是得有计划、有目的,坚持不懈 :-)<br /> <br />技术博客<br />csdn.net C/C++,程序员<br />cnblogs.com .Net<br />blogjava.com Java<br />csai.cn 系统分析<br />infoq.com 敏捷<br /
世界真的很大 今天考试的第三题 发现了点性质但是时间复杂度分析不能过 实在是没有什么思路了写了个暴力 寄希望于评测机跑的快一点没想到居然是正解看题先:description: 在很久很久以前,曾经有两个国家和睦相处,无忧无虑的生活着。一年一度的评比大会开始了,作为和平的两国,一个朋友圈数量最多的永远都是最值得他人的尊敬,所以现在就是需要你求朋友圈的最大数目。 两个国家看成是AB两国
转自:http://blog.csdn.net/yejiansnake/article/details/2175778MFC下CSocket编程详解: 1. 常用的函数和注意事项(详细的函数接口说明请查看MSDN): CSocket::Create 初始化(一般写服务器程序都不要用为好,用下面的 CSocket::Socket 初始化) CSocket