Android 11判断应用已安装坑点


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

Android 11 wxApi.isWXAppInstalled() 返回false


解决办法

以下方法任意一种都可以解决问题

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

manifest节点添加如下内容:

   <queries>
         <package android:name="com.tencent.mm" />
   </queries>

具体位置如下所示

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="...">
    <queries>
       <package android:name="com.tencent.mm" />
   </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、增加权限

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>

3、app的targetSdkVersion 改为29

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

原因与说明

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

public final boolean isWXAppInstalled() {
        if (this.detached) {
            throw new IllegalStateException("isWXAppInstalled fail, WXMsgImpl has been detached");
        } else {
            try {
                PackageInfo var1;
                return (var1 = this.context.getPackageManager().getPackageInfo("com.tencent.mm", 64)) == null ? false : WXApiImplComm.validateAppSignature(this.context, var1.signatures, this.checkSignature);
            } catch (NameNotFoundException var2) {
                return false;
            }
        }
    }

其中就获取”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,那么获取所有的应用之后,进行匹配会如何,答案是否定的。

var pkgs = packageManager.getInstalledPackages(0)
var apps = packageManager.getInstalledApplications(0);

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

<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>

Android 11 应用可见性官方说明

Android 11可见性官方说明

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

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

特定软件包名称

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

<manifest package="com.example.game">
    <queries>
        <package android:name="com.example.store" />
        <package android:name="com.example.services" />
    </queries>
    ...
</manifest>

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

在库中与托管应用通信

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

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

<!-- Place inside the <queries> element. -->
<package android:name=PACKAGE_NAME />

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

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

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

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

<manifest package="com.example.game">
    <queries>
        <intent>
            <action android:name="android.intent.action.SEND" />
            <data android:mimeType="image/jpeg" />
        </intent>
    </queries>
    ...
</manifest>

<intent> 元素有一些限制:

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

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

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

使用特定授权的软件包

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

<manifest package="com.example.suite.enterprise">
    <queries>
        <provider android:authorities="com.example.settings.files" />
    </queries>
    ...
</manifest>

注意:如果 元素包含 元素,您可能会在 Android Studio 中看到与 <provider> 元素相关的编辑器警告。只要您使用的是 Android Gradle 插件的最新“点”版本,您的 build 就不受影响,因此您可以忽略该警告。如需了解详情,请参阅有关为 Android 11 中的软件包可见性准备 Gradle build 的博文。

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

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

所有应用(不推荐)

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

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

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

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

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

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Win11安装Android应用,需要通过Microsoft Store上的新功能"Android应用支持"实现。在Win11系统中,用户可以从Microsoft Store下载安装Android应用。 首先,用户需要打开Microsoft Store应用商店。在搜索栏中输入想要安装Android应用的名称,然后点击搜索按钮进行搜索。搜索结果中会显示与关键词相关的应用程序。 接下来,用户可以选择想要安装Android应用,并点击它的图标进行查看。在应用的详细页面中,可以了解应用的描述、标签、评级以及其他用户的评论。用户可以根据自己的需求和偏好来确定是否要安装应用。 如果用户决定安装应用,只需点击页面上的"获取"或"安装"按钮。应用会自动下载并安装到Win11系统中。用户可以在安装过程中查看进度,并等待安装完成。 安装完成后,用户可以在Win11系统的开始菜单、任务栏、或桌面快捷方式中找到已安装Android应用。点击相应的图标即可打开应用,并开始使用它。 需要注意的是,虽然Win11具有兼容运行Android应用的功能,但并非所有的Android应用都能完美适配Win11系统。某些应用可能会出现界面显示不正常、功能受限或不可使用等问题。用户在安装前可以查看相关的用户评论和评级,了解其他用户对该应用在Win11上的兼容性评价。 总的来说,Win11安装Android应用的过程相对简单,只需通过Microsoft Store搜索、选择、安装即可。用户可以根据自己的需求和喜好,体验更丰富的应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值