android 应用以 Android 11(API 级别 30)或更高版本为目标平台获取其他应用信息失败

一、问题场景及现象

最近各应用市场发出需要兼容android11的要求,于是在新版本里面将目标版本升级到30,但是升级后发现应用中判断其他应用是否安装的方法执行失败,每次获取的安装状态都是未安装。最终定位到原因在android11上的版本兼容上。
在targetSdkVersion 升级到30之前,通过packagemanager去获取对应包名的信息是能获取成功的,但升级后就无法获取到对应的信息了

二、解决方法

在清单文件AndroidManifest.xml中声明以下权限即可

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
        tools:ignore="QueryAllPackagesPermission"/>
<!-- 如果QUERY_ALL_PACKAGES被媒体覆盖,通过以下标签使得匹配intent的app对于应用是可见的! -->
<queries>
    <intent>
      	<action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent>
</queries>

三、问题出现原因

在android11上,google进行了软件包可见性过滤,基本上将第三方开发的应用都进行过滤掉了。
点击查看对应官方文档
在这里插入图片描述
通过文档或截图,我们知道,如果我们使用的getInstalledApplications()方法去获取应用信息会受到影响,通过代码调试得到以下影响程度

不在清单文件中声明权限,packageManager.getInstalledPackages(0)获取的已安装应用只有系统级应用,无第三方开发app信息。
声明了QUERY_ALL_PACKAGES,再通过该方法即可拿到手机系统内所有应用,自然能获取某个包名对应的app是否安装、应用名称、版本号等

但是该权限是获取所有应用信息、在官方的推荐程度为不推荐、更推荐使用标签去进行精准匹配应用,
如我们在上面的解决方法中的标签,其表示匹配所有满足具有该intent定义的应用,普通应用都会定义有这样一个intent,其实也算是获取所有应用。
如果我们只需要知道某一个或某几个应用,我们可以这样去定义标签

<queries>
        <package android:name="com.tencent.mm" /> //微信
        <package android:name="com.tencent.mobileqq" /> //QQ
        <package android:name="应用包名" />
</queries>

四、扩展一下

国内某些手机会有一个“读取应用列表权限”、我们在使用getInstalledPackages(0)去获取所有安装的应用包时会触发该权限,会直接弹出一个系统应用权限申请,拒绝之后我们也会出现获取不到应用列表信息。
但是可以获取到指定包名的应用信息,当然这个获取会被上面的android11的权限影响,即无权限或该应用对本应用不可见即无法获取该应用权限

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值