政策更新 | 开发者如何处理软件包可见性

政策更新 | 开发者如何处理软件包可见性

我们正在 Android 平台上进行多项变更来增强用户隐私和平台安全性,旨在为用户提供更安全的体验。以 Android 11 (API 级别 30) 或更高版本为目标的应用默认将只能获取 过滤后的已安装应用列表。如需访问过滤后列表以外的应用,则需要在应用内的 Android manifest 中使用 元素声明需要与之交互的应用。本文将介绍适应此特性的最佳实践。

查询应用并与之交互

您可以通过以下几种方式查询应用并与之交互:

  • 如果您知道想要查询或与之交互的特定应用集,请将其 软件包 名称包含在 元素内的一组 元素中。
<manifest package="com.example.game">
    <queries>
        <package android:name="com.example.store" />
        <package android:name="com.example.services" />
    </queries>
    ...
</manifest>
  • 如果您的应用需要查询或与一组具有特定用途的应用交互,但您可能不知道要添加的具体软件包名称,您可以将 intent 过滤器签名 列在您的 元素中。然后,您的应用便可发现具有匹配的 元素的应用。
<manifest package="com.example.game">
    <queries>
        <intent>
            <action android:name="android.intent.action.SEND" />
            <data android:mimeType="image/jpeg" />
        </intent>
    </queries>
    ...
</manifest>
  • 如果您需要查询 Content Provider,但不知道具体的软件包名称,则可以在 元素中声明该提供程序授权。
<manifest package="com.example.suite.enterprise">
    <queries>
        <provider android:authorities="com.example.settings.files" />
    </queries>
    ...
</manifest>

我们建议通过仅查询您需要与之交互的软件包来尽可能减少数据。QUERY_ALL_PACKAGES 或同等广泛的 元素应当仅由需要此级别信息的应用使用。我们新增的软件包可见性政策为新推出的 QUERY_ALL_PACKAGES 权限引入了一个审批流程,用于控制对设备上已安装应用清单的访问。您可以观看以下视频或阅读更多 政策更新

Activity 标记

大多数常见用例都不需要您的应用具有广泛的软件包可见性。对于许多场景,您可以使用 startActivity(),并在没有应用可以打开此 intent 时捕获异常。

try {
    val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        addCategory(CATEGORY_BROWSABLE)
    }
    startActivity(intent)
} catch (e:ActivityNotFoundException) {
    Snackbar.make(it,"Activity Not Found",Snackbar.LENGTH_LONG).show()
}

尽管您可以启动没有目标可见性的任何 Activity,但由于它是一个 隐式 intent,您在启动之前无法查询它的可用性,也无法了解将启动哪个特定的应用。如果您在它不解析的情况下启动,将收到通知。为了解决这一问题,您可以使用 intent 标记。

使用标记的常见示例是 自定义标签页,自定义标签页让应用可以自定义浏览器的外观。链接将在非浏览器应用 (如果有) 中正确打开,而标记则可以在开发者希望能够自由选择 "自定义标签页" 浏览器的高级用例中提供帮助。

FLAG_ACTIVITY_REQUIRE_NON_BROWSER

只有 intent 解析为非浏览器结果时,此标记才会启动它。如果此类结果不存在,将抛出 ActivityNotFoundException,然后,您的应用可以在自定义标签页中打开该网址。

val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        // The URL should either launch directly in a non-browser app (if it's
        // the default), or in the disambiguation dialog.
        addCategory(CATEGORY_BROWSABLE)
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER
}

如果一个 intent 包含此标记,则在调用直接启动浏览器应用或者向用户显示一个消歧对话框 (唯一选项是浏览器应用) 时,调用 startActivity() 会导致抛出 ActivityNotFoundException。要详细了解标记,请参阅 基于用例配置软件包可见性

自定义共享表单

建议使用系统提供的共享表单代替自定义表单。无需应用可见性,您也可以自定义系统共享表单。请参阅 文档 了解更多信息。

调试软件包可见性

您可以轻松检查 manifest,了解是否包括了所有 queries。为此,请访问 manifest 文件并选择 Merged Manifest。

您也可以启用软件包过滤的日志消息,了解默认可见性对您的应用有何影响:

$ adb shell pm log-visibility --enable YOUR_PACKAGE_NAME

后续步骤

有关软件包可见性的详细信息,您可以参阅以下资源:

乐享编码!

版权声明

禁止一切形式的转载-禁止商用-禁止衍生 申请授权

脉脉不得语
脉脉不得语
Zhengzhou Website
Android Developer | https://androiddevtools.cn and https://androidweekly.io Funder | GDG Zhengzhou Funder & Ex Organizer | http://Toast.show(∞) Podcast Host

你已经成功订阅到 Android 开发技术周报
太棒了!接下来,完成检验以获得全部访问权限 Android 开发技术周报
欢迎回来!你已经成功登录了。
Unable to sign you in. Please try again.
成功!您的帐户已完全激活,您现在可以访问所有内容。
Error! Stripe checkout failed.
Success! Your billing info is updated.
Error! Billing info update failed.
🍗