验证 Android 应用链接

Android 应用链接是一种特殊类型的深层链接,可让您的网站网址直接在您的 Android 应用中打开相应内容,无需用户选择应用。Android 应用链接使用 Digital Asset Links API 建立信任,以便网站批准您的应用自动打开该网域的链接。如果系统成功验证您是这些网址的所有者,则会自动将这些网址 intent 路由到您的应用。

如需验证您对应用和网站网址的所有权,请完成以下步骤:

  1. 添加包含 autoVerify 属性的 intent 过滤器。此属性会向系统发出信号,告知系统应验证您的应用是否属于 intent 过滤器中使用的网址网域。

  2. 通过在以下位置托管 Digital Asset Links JSON 文件,声明您的网站和 intent 过滤器之间的关联

    https://domain.name/.well-known/assetlinks.json

您可以在以下资源中找到相关信息:

为应用链接验证添加了 intent 过滤器

如需为您的应用启用链接处理验证,请添加与以下格式匹配的 intent 过滤器:

<!-- Make sure you explicitly set android:autoVerify to "true". -->
<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />

    <!-- If a user clicks on a shared link that uses the "http" scheme, your
         app should be able to delegate that traffic to "https". -->
    <!-- Do not include other schemes. -->
    <data android:scheme="http" />
    <data android:scheme="https" />

    <!-- Include one or more domains that should be verified. -->
    <data android:host="..." />
</intent-filter>

虽然仅在每个主机的一个 <intent-filter> 声明中包含 autoVerify 就足够了,即使该主机在其他未标记声明中使用,也建议您将 autoVerify 添加到每个 <intent-filter> 元素中以保持一致。这还可确保在您移除或重构清单文件中的元素后,您的应用仍与您仍定义的所有网域相关联。

网域验证流程需要连接到互联网,并且可能需要一些时间才能完成。为了帮助提高该流程的效率,仅当某个网域在包含上方代码段中指定的确切格式的 <intent-filter> 元素内时,系统才会为以 Android 12 或更高版本为目标平台的应用验证该网域。例如,“http”和“https”以外的架构(例如 <data android:scheme="custom" />)会阻止 <intent-filter> 触发域名验证。

支持多个主机的应用链接

系统必须能够对照相应 intent 过滤器中相应网域上托管的 Digital Asset Links 文件验证应用网址 intent 过滤器的数据元素中指定的主机。如果验证失败,系统会默认采用标准行为解析相应 intent,具体如创建指向应用内容的深层链接中所述。 不过,该应用仍可通过验证,成为应用其他 intent 过滤器中定义的任何网址格式的默认处理程序。

注意:在 Android 11(API 级别 30)及更低版本中,除非系统为您在清单中定义的所有主机找到匹配的 Digital Asset Links 文件,否则不会将您的应用验证为默认处理程序。

例如,如果在 https://www.example.com/.well-known/assetlinks.json 中找到 assetlinks.json 文件,但在 https://www.example.net/.well-known/assetlinks.json 中未找到,则具有以下 intent 过滤器的应用仅针对 https://www.example.com 通过验证:

<application>

  <activity android:name=”MainActivity”>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="http" />
      <data android:scheme="https" />
      <data android:host="www.example.com" />
    </intent-filter>
  </activity>
  <activity android:name=”SecondActivity”>
    <intent-filter>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" />
     <data android:host="www.example.net" />
    </intent-filter>
  </activity>

</application>

注意:同一 intent 过滤器中的所有 <data> 元素会合并在一起,以涵盖合并后属性的所有变体。例如,上面的第一个 intent 过滤器包含一个仅声明 HTTPS 架构的 <data> 元素。但是,它与其他 <data> 元素组合在一起,以便 intent 过滤器同时支持 http://www.example.comhttps://www.example.com。因此,如需定义 URI 架构和网域的特定组合,您必须创建单独的 intent 过滤器。

支持多个子网域的应用链接

Digital Asset Links 协议将 intent 过滤器中的子网域视为唯一的独立主机。因此,如果您的 intent 过滤器列出了具有不同子网域的多个主机,您必须在每个网域上发布有效的 assetlinks.json。例如,以下 intent 过滤器包含 www.example.commobile.example.com 作为接受的 intent 网址主机。因此,必须在 https://www.example.com/.well-known/assetlinks.jsonhttps://mobile.example.com/.well-known/assetlinks.json 上发布有效的 assetlinks.json

<application>
  <activity android:name=”MainActivity”>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" />
      <data android:scheme="https" />
      <data android:host="www.example.com" />
      <data android:host="mobile.example.com" />
    </intent-filter>
  </activity>
</application>

或者,如果您使用通配符(例如 *.example.com)声明主机名,则必须在根主机名 (example.com) 发布 assetlinks.json 文件。例如,只要 assetlinks.json 文件在 https://example.com/.well-known/assetlinks.json 上发布,具有以下 intent 过滤器的应用就会通过 example.com 的任何子名称(例如 foo.example.com)的验证:

<application>
  <activity android:name=”MainActivity”>
    <intent-filter android:autoVerify="true">
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.DEFAULT" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" />
      <data android:host="*.example.com" />
    </intent-filter>
  </activity>
</application>

检查是否存在与同一网域关联的多个应用

如果您发布了多个应用,其中每个应用都与同一网域相关联,则它们都可以成功地通过验证。不过,如果这些应用可以解析完全相同的网域主机和路径,就像一个应用的精简版和完整版一样,则只有最近安装的应用才能解析该网域的网络 intent。

在这种情况下,请检查用户的设备上是否有可能发生冲突的应用,前提是具有必要的软件包可见性。然后,在您的应用中显示一个自定义选择器对话框,其中包含调用 queryIntentActivities() 所得到的结果。用户可以从该对话框中显示的匹配应用的列表中选择他们偏好的应用。

声明网站关联性

您必须在网站上发布 Digital Asset Links JSON 文件,以指示与网站相关联的 Android 应用并验证应用的网址 intent。 JSON 文件使用下列字段来识别关联的应用:

  • package_name:在应用的 build.gradle 文件中声明的应用 ID
  • sha256_cert_fingerprints:应用签名证书的 SHA256 指纹。您可以使用以下命令通过 Java 密钥工具生成指纹:
    keytool -list -v -keystore my-release-key.keystore
    
    此字段支持多个指纹,这些指纹可用于支持不同版本的应用,例如调试版 build 和正式版 build。

    如果您的应用使用的是 Play 应用签名,则本地运行 keytool 生成的证书指纹通常与用户设备上的证书指纹不匹配。您可以在 Play 管理中心开发者账号的 Release > Setup > App signing 下验证您是否为应用使用了 Play 应用签名;如果是,您还会在同一页面上找到适用于应用的正确 Digital Asset Links JSON 代码段。

以下示例 assetlinks.json 文件可为 com.example Android 应用授予链接打开权限:

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

将网站与多个应用相关联

网站可以在同一 assetlinks.json 文件内声明与多个应用的关联。以下文件列表展示了一个声明示例文件,该文件分别声明了与两个应用的关联,并且位于 https://www.example.com/.well-known/assetlinks.json 中:

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.puppies.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
  },
  {
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.monkeys.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

不同的应用可以处理同一网络主机下的不同资源对应的链接。例如,app1 可以声明一个对应于 https://example.com/articles 的 intent 过滤器,而 app2 可以声明一个对应于 https://example.com/videos 的 intent 过滤器。

注意:与一个网域相关联的多个应用可以使用同一证书或不同证书进行签名。

将多个网站与同一应用相关联

多个网站可以在各自的 assetlinks.json 文件中声明与同一应用的关联性。以下文件列表示例展示了如何声明 example.com 和 example.net 与 app1 的关联性。第一个列表展示了 example.com 与 app1 的关联性:

https://www.example.com/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

下一个列表展示了 example.net 与 app1 的关联性。唯一的区别是托管这些文件的位置不同(.com.net):

https://www.example.net/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

发布 JSON 验证文件

您必须在以下位置发布 JSON 验证文件:

https://domain.name/.well-known/assetlinks.json

请确保以下几点:

  • 使用内容类型 application/json 发布 assetlinks.json 文件。
  • 无论应用的 intent 过滤器是否将数据架构声明为 HTTPS,都必须可通过 HTTPS 连接访问 assetlinks.json 文件。
  • assetlinks.json 文件必须无需重定向即可访问(无 301 或 302 重定向)。
  • 如果您的应用链接支持多个主机网域,那么您必须在每个网域上分别发布 assetlinks.json 文件。请参阅支持多个主机的应用链接
  • 请勿发布清单文件中的开发/测试网址无法供公众访问的应用(例如,任何只可通过 VPN 访问的应用)。作为这种情况下的应急措施,您可以配置 build 变体以针对开发 build 生成不同的清单文件。

Android App Links 验证

如果应用的至少一个 intent 过滤器中存在 android:autoVerify="true",则在搭载 Android 6.0(API 级别 23)或更高版本的设备上安装应用会导致系统自动验证与应用的 intent 过滤器中的网址相关联的主机。在 Android 12 及更高版本中,您还可以手动调用验证流程来测试验证逻辑。

自动验证

系统的自动验证涉及以下方面:

  1. 系统会检查所有包含以下任一项的 intent 过滤器:
    • 操作:android.intent.action.VIEW
    • 类别:android.intent.category.BROWSABLEandroid.intent.category.DEFAULT
    • 数据架构:httphttps
  2. 对于在上述 intent 过滤器中找到的每个唯一主机名,Android 会在 https://hostname/.well-known/assetlinks.json 查询 Digital Asset Links 文件的相应网站。

确认要与您的应用关联的网站列表,并且确认托管的 JSON 文件有效后,请立即在您的设备上安装应用。等待至少 20 秒,让系统完成异步验证流程。使用以下命令检查系统是否验证了您的应用并设置了正确的链接处理政策:

adb shell am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE \
    -d "http://domain.name:optional_port"

手动验证

从 Android 12 开始,您可以为安装在设备上的应用手动调用网域验证。无论您的应用是否以 Android 12 为目标平台,您都可以执行此流程。

建立互联网连接

如需执行网域验证,您的测试设备必须连接到互联网。

支持更新后的网域验证流程

如果您的应用以 Android 12 或更高版本为目标平台,则系统会自动使用更新后的网域验证流程。

否则,您可以手动启用更新后的验证流程。为此,请在终端窗口中运行以下命令:

adb shell am compat enable 175408749 PACKAGE_NAME

在设备上重置 Android App Links 的状态

在设备上手动调用网域验证之前,您必须在测试设备上重置 Android App Links 的状态。为此,请在终端窗口中运行以下命令:

adb shell pm set-app-links --package PACKAGE_NAME 0 all

此命令会将设备置于它在用户为任何网域选择默认应用之前所处的同一状态。

调用网域验证流程

在设备上重置 Android App Links 的状态之后,您可以执行验证本身。为此,请在终端窗口中运行以下命令:

adb shell pm verify-app-links --re-verify PACKAGE_NAME

查看验证结果

稍等片刻,在验证代理完成其请求之后,查看验证结果。为此,请运行以下命令:

adb shell pm get-app-links PACKAGE_NAME

此命令的输出类似于以下内容:

com.example.pkg:
    ID: 01234567-89ab-cdef-0123-456789abcdef
    Signatures: [***]
    Domain verification state:
      example.com: verified
      sub.example.com: legacy_failure
      example.net: verified
      example.org: 1026

成功通过验证的网域的网域验证状态为 verified。其他任何状态都表示无法执行网域验证。特别是,状态为 none 表示验证代理可能尚未完成验证流程。

以下列表显示了网域验证可能会为给定的网域返回的值:

none
没有为此网域记录任何内容。再等待几分钟,以便验证代理完成与网域验证相关的请求,然后再次调用网域验证流程
verified
为发出声明的应用成功验证了网域。
approved
强行批准了网域,通常是通过执行 shell 命令来实现的。
denied
强行拒绝了网域,通常是通过执行 shell 命令来实现的。
migrated
系统保留了使用旧版网域验证的某个先前流程的结果。
restored
在用户执行数据恢复之后批准了网域。系统假定网域之前已经过验证。
legacy_failure
旧版验证程序拒绝了网域。具体的失败原因未知。
system_configured
网域已通过设备配置自动批准。
错误代码为 1024 或更大

设备验证程序专用的自定义错误代码。

请仔细检查是否已建立网络连接,然后再次调用网域验证流程

请求用户将您的应用与网域相关联

如需使您的应用获准处理某个网域,另一种方法是让用户将您的应用与该网域相关联。

检查您的应用是否已获准处理网域

在提示用户之前,请检查您的应用是否是您在 <intent-filter> 元素中定义的网域的默认处理程序。您可以使用以下某种方法来查询批准状态:

DomainVerificationManager

以下代码段演示了如何使用 DomainVerificationManager API:

Kotlin

val context: Context = TODO("Your activity or fragment's Context")
val manager = context.getSystemService(DomainVerificationManager::class.java)
val userState = manager.getDomainVerificationUserState(context.packageName)

// Domains that have passed Android App Links verification.
val verifiedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_VERIFIED }

// Domains that haven't passed Android App Links verification but that the user
// has associated with an app.
val selectedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_SELECTED }

// All other domains.
val unapprovedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_NONE }

Java

Context context = TODO("Your activity or fragment's Context");
DomainVerificationManager manager =
        context.getSystemService(DomainVerificationManager.class);
DomainVerificationUserState userState =
        manager.getDomainVerificationUserState(context.getPackageName());

Map<String, Integer> hostToStateMap = userState.getHostToStateMap();
List<String> verifiedDomains = new ArrayList<>();
List<String> selectedDomains = new ArrayList<>();
List<String> unapprovedDomains = new ArrayList<>();
for (String key : hostToStateMap.keySet()) {
    Integer stateValue = hostToStateMap.get(key);
    if (stateValue == DomainVerificationUserState.DOMAIN_STATE_VERIFIED) {
        // Domain has passed Android App Links verification.
        verifiedDomains.add(key);
    } else if (stateValue == DomainVerificationUserState.DOMAIN_STATE_SELECTED) {
        // Domain hasn't passed Android App Links verification, but the user has
        // associated it with an app.
        selectedDomains.add(key);
    } else {
        // All other domains.
        unapprovedDomains.add(key);
    }
}

命令行程序

在开发过程中测试您的应用时,您可以运行以下命令来查询贵单位拥有的网域的验证状态:

adb shell pm get-app-links --user cur PACKAGE_NAME

在以下示例输出中,虽然应用针对“example.org”网域的验证失败,但用户 0 已在系统设置中手动批准应用,并且没有其他软件包针对该网域进行验证。

com.example.pkg:
ID: ***
Signatures: [***]
Domain verification state:
  example.com: verified
  example.net: verified
  example.org: 1026
User 0:
  Verification link handling allowed: true
  Selection state:
    Enabled:
      example.org
    Disabled:
      example.com
      example.net

您还可以使用 shell 命令来模拟用户选择要与给定网域关联的应用的过程。adb shell pm 的输出提供了这些命令的完整说明。

提供请求的上下文

在您发出网域批准请求之前,请先为用户提供一些上下文。例如,您可以向用户显示启动画面、对话框或类似的界面元素,向用户说明为什么您的应用应该是某个特定网域的默认处理程序。

发出请求

在用户了解您的应用需要他们执行的操作之后,发出请求。为此,请调用一个 intent,其中包含 ACTION_APP_OPEN_BY_DEFAULT_SETTINGS intent 操作,以及与目标应用的 package:com.example.pkg 匹配的数据字符串,如以下代码段所示:

Kotlin

val context: Context = TODO("Your activity or fragment's Context")
val intent = Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:${context.packageName}"))
context.startActivity(intent)

Java

Context context = TODO("Your activity or fragment's Context");
Intent intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent);

调用该 intent 时,用户会看到一个名为默认打开的设置屏幕。此屏幕包含一个名为打开支持的链接的单选按钮,如图 1 所示。

当用户开启打开支持的链接时,一个名为要在此应用中打开的链接的部分下会出现一组复选框。在此处,用户可以选择想要与您的应用关联的网域。他们还可以选择添加链接以添加网域,如图 2 所示。当用户稍后选择他们所添加网域中的任何链接时,该链接会自动在您的应用中打开。

启用该单选按钮后,底部附近的一个部分会包含复选框以及一个名为“添加链接”的按钮
图 1. 系统设置屏幕,用户可以在该屏幕中选择默认情况下在您的应用中打开的链接。
每个复选框代表您可以添加的一个网域。该对话框的按钮包括“取消”和“添加”。
图 2. 用户可以在该对话框中选择要与您的应用关联的其他网域。

在您的应用中打开您的应用无法验证的网域

您的应用的主要功能可能是用作第三方应用来打开链接,而无法验证其处理的网域。如果是这种情况,请向用户说明:当他们选择某个网页链接时,无法在第一方应用与您的(第三方)应用之间进行选择。用户需要手动将网域与您的第三方应用相关联。

此外,不妨考虑引入一个对话框或 trampoline activity 来充当代理,让用户能够在第一方应用中打开链接(如果用户愿意这样做的话)。在设置此类对话框或 trampoline activity 之前,请先设置您的应用,使其具有对满足以下条件的第一方应用的软件包可见性:与您的应用的网络 intent 过滤器匹配。

测试应用链接

实现应用链接功能时,您应测试链接功能,以确保系统能够将您的应用与您的网站相关联,并按预期方式处理网址请求。

如需测试现有语句文件,您可以使用 语句列表生成器和测试器工具。

确认需要验证的主机列表

测试时,您应该对系统需要针对您的应用验证的已关联主机列表进行确认。创建一个列表,在其中列出所有相关网址,此类网址对应的 intent 过滤器包含以下属性和元素:

  • android:scheme 属性,值为 httphttps
  • 具有网域网址格式的 android:host 属性
  • android.intent.action.VIEW 操作元素
  • android.intent.category.BROWSABLE 类别元素

使用此列表检查每个指定的主机和子网域上是否提供了 Digital Asset Links JSON 文件。

确认 Digital Asset Links 文件

对于每个网站,使用 Digital Asset Links API 确认已正确托管和定义 Digital Asset Links JSON 文件:

https://digitalassetlinks.googleapis.com/v1/statements:list?
   source.web.site=https://domain.name:optional_port&
   relation=delegate_permission/common.handle_all_urls

您可以在测试过程中检查系统当前的链接处理设置。使用以下命令获取已连接设备上所有应用的现有链接处理政策列表:

adb shell dumpsys package domain-preferred-apps

执行以下命令也可以实现此操作:

adb shell dumpsys package d

注意:请确保在安装应用后等待至少 20 秒,以让系统完成验证流程。

该命令会返回设备上定义的每位用户或每个配置文件的清单,前面带有以下格式的标头:

App linkages for user 0:

在此标头之后,输出会使用以下格式列出相应用户的链接处理设置:

Package: com.android.vending
Domains: play.google.com market.android.com
Status: always : 200000002

此列表可以指示对于此用户,哪些应用与哪些网域相关联:

  • Package - 以软件包名称标识应用,与应用清单文件中声明的内容一致。
  • Domains - 显示相关主机的完整列表,该应用处理此类主机的网络链接,使用空格作为分隔符。
  • Status - 显示该应用的现有链接处理设置。已通过验证并且清单文件中包含 android:autoVerify="true" 的应用会显示 always 状态。此状态后的十六进制数字与 Android 系统的用户应用链接偏好设置记录有关。此值并不表示验证是否成功。

注意:如果用户在验证完成之前更改应用的应用链接设置,则即使验证失败,验证仍可能会显示误报。不过,如果用户显式允许该应用在不进行询问的情况下打开支持的链接,则即使出现这种验证失败的情况也没关系。这是因为用户偏好设置优先于程序化验证(或缺少验证)。因此,链接会直接转到您的应用,而不会显示对话框,就好像验证已成功一样。

测试示例

为了让应用链接验证成功,系统必须能够针对您在给定 intent 过滤器中指定并且符合应用链接标准的每个网站验证您的应用。以下示例展示了一个定义了若干个应用链接的清单文件配置:

<application>

    <activity android:name=”MainActivity”>
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" />
            <data android:scheme="https" />
            <data android:host="www.example.com" />
            <data android:host="mobile.example.com" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" />
            <data android:host="www.example2.com" />
        </intent-filter>
    </activity>

    <activity android:name=”SecondActivity”>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" />
            <data android:host="account.example.com" />
        </intent-filter>
    </activity>

      <activity android:name=”ThirdActivity”>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="https" />
            <data android:host="map.example.com" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="market" />
            <data android:host="example.com" />
        </intent-filter>
      </activity>

</application>

平台会尝试从以上清单文件中验证的主机列表是:

www.example.com
mobile.example.com
www.example2.com
account.example.com

平台不会尝试从上述清单中验证的主机列表如下:

map.example.com (it does not have android.intent.category.BROWSABLE)
market://example.com (it does not have either an "http" or "https" scheme)

如需详细了解语句列表,请参阅 创建语句列表

修复常见的实现错误

如果无法验证 Android App Links,请检查以下常见错误。本部分使用 example.com 作为占位符域名;执行这些检查时,请将 example.com 替换为服务器的实际域名。

intent 过滤器设置不正确
检查 <intent-filter> 元素中是否包含应用不拥有的网址。
服务器配置不正确

检查服务器的 JSON 配置,并确保 SHA 值正确无误。

此外,请检查 example.com.(带有尾随句点)是否提供与 example.com 相同的内容。

服务器端重定向

如果您设置了重定向(例如以下重定向),系统不会验证应用的任何 Android App Links:

  • http://example.comhttps://example.com
  • example.comwww.example.com

此行为可保护应用的安全性。

服务器稳健性

检查您的服务器能否连接到客户端应用。

无法验证的链接

出于测试目的,您可能会有意添加不可验证的链接。请注意,在 Android 11 及更低版本中,这些链接会导致系统不验证您应用的所有 Android App Links。

assetlinks.json 中的签名不正确

验证您的签名是否正确且与用于对应用签名的签名一致。常见错误包括:

  • 使用调试证书为应用签名,并且在 assetlinks.json 中仅使用发布签名。
  • assetlinks.json 中使用小写签名。签名应大写。
  • 如果您使用的是 Play 应用签名,请确保您使用的是 Google 用于为您的每个版本签名的签名。您可以按照声明网站关联的说明来验证这些详细信息(包括完整的 JSON 代码段)。