声明包可见性需求

在创建应用时,务必考虑设备上您的应用需要与之交互的其他应用。如果您的应用以 Android 11(API 级别 30)或更高版本为目标平台,系统会自动使某些应用对您的应用可见,但默认情况下会过滤掉其他应用。本指南介绍如何使这些其他应用对您的应用可见。

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

特定软件包名称

如果您知道要查询或与之交互的特定应用,例如与您的应用集成的应用或您使用的其服务的应用,请在 <queries> 元素内的一组 <package> 元素中包含其软件包名称

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

在库中与主机应用通信

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

如果您的库涉及与主机应用通信,例如使用绑定服务,请包含一个 <package> 元素,其中指定主机应用的软件包名称

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

通过包含此声明,您可以检查主机应用是否已安装并与之交互,例如通过调用 bindService()。使用您的库的调用应用会因本次交互而自动对主机应用可见

匹配 Intent 过滤器签名的软件包

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

以下代码示例展示了一个 <intent> 元素,可让应用看到支持 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> 元素中使用 pathpathPrefixpathPatternport 属性。系统的行为就像您将每个属性的值设置为通用通配符 (*) 一样。
  • 您不能使用 mimeGroup 元素的 <data> 属性。
  • 在单个 <intent> 元素的 <data> 元素中,您最多只能使用以下每个属性一次:

    • mimeType
    • scheme
    • host

    您可以将这些属性分布在多个 <data> 元素中或在单个 <data> 元素中使用它们。

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

  • <action> 元素的 name 属性。
  • <data> 元素的 mimeType 属性的子类型 (image/*)。
  • <data> 元素的 mimeType 属性的类型和子类型 (*/*)。
  • <data> 元素的 scheme 属性。
  • <data> 元素的 host 属性。

除非前面的列表中另有规定,否则系统不支持文本和通配符的混合使用,例如 prefix*

使用特定授权的软件包

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

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

您可以在单个 <queries> 元素中声明提供方授权。在 <queries> 元素中,您可以声明一个或多个 <provider> 元素。一个 <provider> 元素可以包含单个提供方授权,或以分号分隔的提供方授权列表。

所有应用(不建议)

在极少数情况下,您的应用可能需要查询或与设备上所有已安装应用(无论它们包含哪些组件)进行交互。为了让您的应用能够查看所有其他已安装应用,系统提供了 QUERY_ALL_PACKAGES 权限。

在某些用例中,适合包含 QUERY_ALL_PACKAGES 权限,例如:

  • 辅助功能应用
  • 浏览器
  • 设备管理应用
  • 安全应用
  • 防病毒应用

不过,通常可以通过与自动可见的应用集交互,以及在清单文件中声明您的应用需要访问的其他应用来满足您的应用用例。为了尊重用户隐私,您的应用应请求实现其功能所需的最小包可见性。

这项来自 Google Play 的政策更新为需要 QUERY_ALL_PACKAGES 权限的应用提供了指导。