创建深层链接

借助深层链接,您可以将用户从网络浏览器、通知、社交媒体、广告和其他来源直接引导至您的应用。深层链接提供直接的应用到应用和网站到应用转换,有助于您通过情境化、有针对性的内容来提高互动度。

本指南介绍了深层链接的工作原理,以及如何创建和测试指向您内容的深层链接。

对于引用您自己的网站或网域的深层链接,我们建议使用应用链接,以便为用户提供顺畅、可信的体验。

深层链接的工作原理

深层链接是 Android 的一项通用系统功能,所有版本和设备都支持此功能。它利用 Android 的 intent 系统将深层链接路由到感兴趣的应用。如果应用想要处理特定的深层链接 URI,则会在其应用清单文件中声明匹配的 intent 过滤器。

在运行时,当用户点按链接时,Android 会触发 intent 并尝试将其路由到应用。由于多个应用可以声明与给定 URI 匹配的 intent 过滤器,因此 Android 会按以下顺序执行这些操作来路由 intent:

  1. 如果用户指定了可以处理该 URI 的默认应用,就打开此应用。
  2. 打开唯一可以处理该 URI 的应用。
  3. 允许用户从消除歧义对话框中选择应用。

这意味着,即使您的 intent 过滤器与给定 URI 匹配,也不能保证系统会将深层链接 intent 路由到您的应用。用户在管理哪个应用处理 intent 方面发挥着关键作用,这让他们可以控制并提供选择。如需更好地控制指向您自己的网站和网域的深层链接,请尝试使用应用链接。

借助 Android 的消除歧义对话框,用户可以查看所有已注册处理深层链接 intent 的已安装应用。用户还可以选择一个应用作为此类链接的默认应用。用户设置默认应用后,系统将不再针对该特定 intent 显示对话框,而是会自动打开所选应用。

图 1. 消除歧义对话框

消除歧义对话框的行为在不同 Android 版本中有所不同。 例如,在 Android 12 及更高版本中,未经验证的应用链接网页链接通常会默认在网络浏览器中打开,而在之前的版本中,如果应用可以处理网页链接,则可能会显示消除歧义对话框。

注意:从 Android 12(API 级别 31)开始,仅当您的应用获准处理某个通用网络 intent 中包含的特定网域时,该网络 intent 才会解析 为应用中的 activity。如果您的应用未获准处理相应的网域,则该网络 intent 会解析为用户的默认浏览器应用。

深层链接的类型

您可以在 Android 上支持三种类型的深层链接:

  • 自定义深层链接:这些深层链接使用自定义 URI scheme(例如 example://products/123)将用户直接引导至应用中的特定内容。它们非常适合内部 Navigation 或来自您控制的来源的链接,但它们不是标准网页链接,如果另一个应用注册了相同的自定义协议,它们仍可能会触发消除歧义对话框。
  • 网页链接:这些深层链接使用标准 httphttps 架构。它们是标准网址,因此用途更广泛,但在 Android 12 及更高版本中,它们几乎总是会触发消除歧义对话框,这意味着它们很可能会默认由用户的网络浏览器处理,而不是路由到您的应用。
  • 应用链接:自 Android 6.0(API 级别 23)起提供,这些是 经过验证的网页链接。通过网站关联流程,您可以向 Android 系统证明您拥有该网域。验证通过后,系统会自动将该网域的链接直接路由到您的应用,完全跳过消除歧义对话框。这为您的用户创造了可信且顺畅的体验。

为传入链接添加 intent 过滤器

如需创建指向您应用内容的链接,请在清单中添加一个包含以下元素和属性值的 intent 过滤器:

<action>

指定 ACTION_VIEW intent 操作,以便能够从 Google 搜索中 访问此 intent 过滤器。

<data>

添加一个或多个 <data> 标记,每个标记都代表一个解析为 Activity 的 URI 格式。<data> 标记必须至少包含 android:scheme 属性。

您可以添加更多属性,以进一步细化 Activity 接受的 URI 类型。例如,您可能拥有多个接受相似 URI 的 Activity,这些 URI 只是路径名称有所不同。在这种情况下,请使用 android:path属性或其pathPatternpathPrefix变体区分系统应针对不同 URI 路径打开哪个 Activity。

<category>

添加 BROWSABLE 类别。如果要从网络浏览器中访问 Intent 过滤器,就必须提供该类别。否则,在浏览器中点击链接便无法解析为您的应用。

另请添加 DEFAULT 类别。这样您的应用才可以响应隐式 intent。否则,只有在 intent 指定您的应用组件名称时,Activity 才能启动。

以下 XML 代码段展示了如何在清单中为深层链接指定 intent 过滤器。URI "example://gizmos""http://www.example.com/gizmos" 都会解析到此 Activity。

<activity
    android:name="com.example.android.GizmosActivity"
    android:label="@string/title_gizmos" >
    <intent-filter android:label="@string/filter_view_http_gizmos">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- Accepts URIs that begin with "http://www.example.com/gizmos” -->
        <data android:scheme="http"
              android:host="www.example.com"
              android:pathPrefix="/gizmos" />
        <!-- note that the leading "/" is required for pathPrefix-->
    </intent-filter>
    <intent-filter android:label="@string/filter_view_example_gizmos">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- Accepts URIs that begin with "example://gizmos” -->
        <data android:scheme="example"
              android:host="gizmos" />
    </intent-filter>
</activity>

请注意,<data> 元素是这两个 intent 过滤器的唯一区别。虽然 同一 intent 过滤器可以包含多个 <data> 元素,但如果您想要 声明唯一网址(例如特定的 schemehost 组合),请务必创建单独的过滤器,因为 同一 intent 过滤器中的多个 <data> 元素实际上会合并 在一起以涵盖合并后属性的所有变体。例如,请考虑以下情况:

<intent-filter>
  ...
  <data android:scheme="https" android:host="www.example.com" />
  <data android:scheme="app" android:host="open.my.app" />
</intent-filter>

看起来这似乎仅支持 https://www.example.comapp://open.my.app。但是,实际上除了这两种之外,它还支持 app://www.example.comhttps://open.my.app

注意:如果多个 Activity 包含解析为 同一经过验证的 Android 应用链接的 intent 过滤器,则无法保证哪个 Activity 处理该链接。

当您向应用清单添加包含 Activity 内容 URI 的 intent 过滤器后,Android 可以在运行时将所有包含匹配 URI 的 Intent 转发到您的应用。

如需详细了解如何定义 intent 过滤器,请参阅 允许其他应用启动您的 Activity

读取传入 intent 中的数据

在系统通过 intent 过滤器启动您的 Activity 后,您可以根据数据 provided by the Intent确定需要呈现的内容。调用 getData()getAction()方法检索与传入Intent相关联的数据和 操作。您可以在 Activity 生命周期的任何时间执行此 Activity ,但您通常应在早期回调时 (比如,onCreate()onStart)执行。

以下代码段展示了如何检索 Intent 中的数据:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    val action: String? = intent?.action
    val data: Uri? = intent?.data
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Intent intent = getIntent();
    String action = intent.getAction();
    Uri data = intent.getData();
}

请遵循以下最佳做法以改进用户体验:

测试深层链接

您可以将 Android 调试桥 与 Activity 管理器 (am) 工具 结合使用,以测试您为深层链接指定的 intent 过滤器 URI 是否可以解析为 正确的应用 Activity。您可以针对设备或模拟器运行 adb 命令。

使用 adb 测试 intent 过滤器 URI 的一般语法为:

$ adb shell am start
        -W -a android.intent.action.VIEW
        -d <URI> <PACKAGE>

例如,以下命令试图查看与指定 URI 相关的目标应用 Activity。

$ adb shell am start
        -W -a android.intent.action.VIEW
        -d "example://gizmos" com.example.android

注意:在路由中定义一组原始类型(例如 **@Serializable data class Product(val colors: List)**)时,自动 生成的深层链接网址格式为 **basePath?colors={value**}。如果您尝试 指定具有多个查询参数的 URI(例如 **basepath?colors=red&colors=blue**),则必须转义和号 (例如 **basepath?colors=red\&colors=blue**)。

您设置的清单声明和 intent 处理程序可以定义您的应用与某网站之间的关联,以及如何处理传入链接。不过,为了让系统将您的应用视为某一组 URI 的默认处理程序,您还必须请求系统验证此关联。 验证应用链接介绍了如何实现此验证。

如需详细了解 intent 和应用链接,请参阅以下资源: