Android 11判断应用已安装坑点

文章目录

  • Android 11 wxApi.isWXAppInstalled() 返回false
    • 解决办法
      • 1、在清单文件的添加queries标签
      • 2、增加权限
      • 3、app的targetSdkVersion 改为29
    • 原因与说明
  • Android 11 获取已安装app列表问题
  • Android 11 应用可见性官方说明
    • 特定软件包名称
    • 在库中与托管应用通信
    • 与 intent 过滤器签名匹配的软件包
    • 使用特定授权的软件包
    • 所有应用(不推荐)

一个很久没有大更新的app,接用户反馈购买课程微信支付不了,通过app、后端的日志查看,确实有多次选择微信下单却未支付的操作。后来在一同事手机上复现,(app提示微信未安装,事实上已经安装)经过很久的折腾,得到结论。app调用的 wxApi.isWXAppInstalled() 来判断微信是否安装。最终在腾讯文档中找到了说明,原因是Android 应用可见性,要求做适配。

Android 11 wxApi.isWXAppInstalled() 返回false


解决办法

1、在清单文件的添加queries标签

manifest节点添加如下内容:

具体位置如下所示

由于是新的标签,因此需要升级开发工具,否则会出现编译错误:

1)Android Studio 需要升级至 3.3 及以上,建议升级至 4.0 及以上版本;

2)Android SDK Build-Tools 需要升级至 30 及以上版本;

3)com.android.tools.build:gradle 需要升级至 3.6.0 版本,建议升级至最新的 3.6.4 版本。

2、增加权限

3、app的targetSdkVersion 改为29

这种方法也能解决上面问题,但实际上也留下了一个坑,时间一久,自己或其他小伙伴把apilevel 升上去,再次入坑。

原因与说明

主要原因是因为Android 11加强了应用可见性,原来的调用方式没有变,但系统内部是做了更苛刻的条件进行判断。什么是可见性在这里可见性指其他应用是否能被当前应用检测到(是否已经安装了某个app,一般这种需求不多或特定应用才会检测是否已经安装某个app)。
微信SDK内部是封装了对微信应用的检测,源码:

其中就获取”com.tencent.mm“ 的packageInfo,在Android 11上,代码执行是异常的,所以返回的一致是false。
Android 11 系统策略更新,请开发者及时适配

<manifest package=“com.example.app”>

// 在应用的AndroidManifest.xml添加如下标签

// 指定微信包名


</manifest>

添加以上标签之后,需要开发者升级编译工具,否则会出现编译错误。

1)Android Studio 需要升级至 3.3 及以上,建议升级至 4.0 及以上版本;

2)Android SDK Build-Tools 需要升级至 30 及以上版本;

3)com.android.tools.build:gradle 需要升级至 3.6.0 版本,建议升级至最新的 3.6.4 版本。

Android 11 获取已安装app列表问题

其实还是来自第一个问题,既然指定单个包名获取不到packgeinfo,那么获取所有的应用之后,进行匹配会如何,答案是否定的。

getInstalledApplications 是新的接口。如上两个接口返回的列表,在Android 11上,正常情况下返回了系统预装的app和当前app的packageinfo,不会返回其他已安装应用,因此替代单一包名的检测是行不通的。重要的是那些管理手机应用的app此时就需要采用上面第二种方法了,否则获取不到其他app。

Android 11 应用可见性官方说明

Android 11可见性官方说明

您的App运行在Android 11(API 级别 30)或更高版本系统,默认情况下,系统会自动让部分应用对您的app可见,但会过滤掉其他应用。本指南将介绍如何让上述其他应用对您的app可见。

如果您的应用以 Android 11 或更高版本为目标平台,并且需要与应用(自动可见的应用除外)交互,请在您应用的清单文件中添加 元素。在元素中,按软件包名称、按 intent 签名或按 Provider 授权指定其他应用,如以下部分所述。

特定软件包名称

如果您知道要查询或与之交互的一组特定应用(例如,与您的应用集成的应用或您使用其服务的应用),请将其包名添加到元素内的一组元素中:

注意:如果在应用的清单中声明了 <package> 元素,则与该软件包名称关联的应用会出现在对 PackageManager 进行的任何与该应用的组件匹配的查询的结果中。

在库中与托管应用通信

如果要开发 Android 库,可以通过在 AAR 清单文件中添加 <queries> 元素来声明软件包可见性需求。此 <queries> 元素与应用可在自己的清单中声明的元素功能相同。

如果您的库涉及与“托管”应用通信(例如使用绑定服务),请添加用于指定托管应用的软件包名称的 <package> 元素:

通过添加此声明,可以检查是否已安装托管应用并与之交互,例如通过调用 bindService() 来完成。此交互的结果是,使用这个库的调用方应用会自动对托管应用可见。

与 intent 过滤器签名匹配的软件包

您的应用可能需要查询一组具有特定用途的应用或与之交互,但您可能不知道要添加的具体软件包名称。在这种情况下,您可以在<queries> 元素中列出 intent 过滤器签名。然后,您的应用就可以发现具有匹配的 <intent-filter> 元素的应用。

以下示例允许您的应用看到支持 JPEG 图片共享功能的已安装应用:

元素有一些限制:

  • 必须只添加一个 <action> 元素。
  • 不能在 <data> 元素中使用 path、pathPrefix、pathPattern 或 port 属性。系统的行为就像您将每个属性的值都设为通用通配符 (*) 一样。
  • 不能使用 元素的 mimeGroup 属性。
  • 在单个 元素的 元素中,以下每个属性最多使用一次:
    • mimeType
    • scheme
    • host
      可以在多个 <data> 元素之间分配这些属性,也可以在单个 <data> 元素中使用这些属性。

元素支持通用通配符 (*) 作为一些属性的值:

  • <action> 元素的 name 属性。
  • <data> 元素的 mimeType 属性的子类型 (image/*)。
  • <data> 元素的 mimeType 属性的类型和子类型 (/)。
  • <data> 元素的 scheme 属性。
  • <data> 元素的 host 属性。
    除非前面列表中另有说明,否则系统不支持混合使用文本和通配符,如 prefix*。

使用特定授权的软件包

如果您需要查询 Content Provider 但不知道具体的软件包名称,您可以在 <provider> 元素中声明该提供程序授权,如以下代码段所示:

可以在单个 <queries> 元素中声明所有提供程序授权。此格式取决于您声明提供程序授权的数量:

  • 单个 <provider> 元素
    在元素中,声明以英文分 分隔的授权列表。
  • 多个 <provider> 元素
    在每个元素中,声明单项授权或以英文分 分隔的授权列表。

所有应用(不推荐)

在极少数情况下,可能需要查询设备上的所有已安装应用或与之交互,不管这些应用包含哪些组件。为了允许您的应用看到其他所有已安装应用,系统会提供 QUERY_ALL_PACKAGES 权限。

下面列出了适合添加 QUERY_ALL_PACKAGES 权限的用例的一些示例:

  • 无障碍应用
  • 浏览器
  • 设备管理应用
  • 安全应用
  • 防病毒应用

不过,在绝大多数情况下,可以通过以下方式实现您应用的用例:与一组自动可见的应用交互,并在您的清单文件中声明您的应用需要访问的其他应用。为了尊重用户隐私,您的应用应请求应用正常工作所需的最小软件包可见性。

这项来自 Google Play 的政策更新为需要 QUERY_ALL_PACKAGES 权限的应用提供了相关准则。

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年6月4日
下一篇 2022年6月4日

相关推荐