验证 Android 应用链接

Android 应用链接是一种特殊的深度链接,允许您的网站 URL 立即在您的 Android 应用中打开相应内容,而无需用户选择应用。Android 应用链接使用 数字资产链接 API 来建立信任,证明您的应用已获得网站批准,可以自动打开该域的链接。如果系统成功验证您拥有这些 URL,系统会自动将这些 URL Intent 路由到您的应用。

要验证您同时拥有您的应用和网站 URL,请完成以下步骤

  1. 添加包含 autoVerify 属性的 Intent 过滤器。此属性向系统发出信号,表明它应该验证您的应用是否属于 Intent 过滤器中使用的 URL 域。

  2. 通过在以下位置托管数字资产链接 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" 之外的 scheme,例如 <data android:scheme="custom" />,将阻止 <intent-filter> 触发域验证。

支持多个主机的应用链接

系统必须能够根据 Intent 过滤器中相应 Web 域上托管的数字资产链接文件,验证应用 URL Intent 过滤器的数据元素中指定的主机。如果验证失败,系统将默认采用其标准行为来解析 Intent,如创建指向应用内容的深度链接中所述。但是,该应用仍然可以作为应用其他 Intent 过滤器中定义的任何 URL 模式的默认处理程序进行验证。

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

例如,如果应用具有以下 Intent 过滤器,则仅当在 https://www.example.com/.well-known/assetlinks.json 找到 assetlinks.json 文件,但在 https://www.example.net/.well-known/assetlinks.json 未找到时,它才通过 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 scheme 的 <data> 元素。但它与其他 <data> 元素组合,因此 Intent 过滤器同时支持 http://www.example.comhttps://www.example.com。因此,当您想要定义 URI scheme 和域的特定组合时,必须创建单独的 Intent 过滤器。

支持多个子域的应用链接

数字资产链接协议将您的 Intent 过滤器中的子域视为独特、独立的主机。因此,如果您的 Intent 过滤器列出了具有不同子域的多个主机,则必须在每个域上发布有效的 assetlinks.json。例如,以下 Intent 过滤器包含 www.example.commobile.example.com 作为接受的 Intent URL 主机。因此,必须在 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)声明主机名,则必须将 assetlinks.json 文件发布在根主机名(example.com)处。例如,如果应用具有以下 Intent 过滤器,只要 assetlinks.json 文件发布在 https://example.com/.well-known/assetlinks.json 处,它就可以通过 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>

检查与同一域关联的多个应用

如果您发布了多个应用,并且每个应用都与同一域关联,则它们都可以成功通过验证。但是,如果这些应用可以解析完全相同的域主机和路径(例如应用的精简版和完整版),则只有最近安装的应用才能解析该域的 Web Intent。

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

声明网站关联

必须在您的网站上发布 数字资产链接 JSON 文件,以指示与网站关联的 Android 应用并验证应用的 URL Intent。JSON 文件使用以下字段来识别关联的应用

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

    如果您正在为您的应用使用Play 应用签名,则在本地运行 keytool 生成的证书指纹通常与用户设备上的指纹不匹配。您可以在您的 Play 管理中心开发者账号中,在 发布 > 设置 > 应用签名 下验证您是否正在为您的应用使用 Play 应用签名;如果使用,您还会在同一页面上找到适用于您的应用的正确数字资产链接 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"]
  }
}]

不同的应用可能会处理同一 Web 主机下不同资源的链接。例如,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

确保以下几点

  • assetlinks.json 文件以内容类型 application/json 提供。
  • assetlinks.json 文件必须可以通过 HTTPS 连接访问,无论您应用的 Intent 过滤器是否将 HTTPS 声明为数据方案。
  • assetlinks.json 文件必须在没有任何重定向(无 301 或 302 重定向)的情况下可访问。
  • 如果您的应用链接支持多个主机域,则您必须在每个域上发布 assetlinks.json 文件。请参阅支持多个主机的应用链接
  • 请勿在清单文件中发布包含开发/测试 URL 的应用,这些 URL 可能无法公开访问(例如,只能通过 VPN 访问的任何 URL)。在这种情况下,一种解决方法是配置构建变体,为开发版本生成不同的清单文件。

Android 应用链接验证

当您应用的至少一个 Intent 过滤器中存在 android:autoVerify="true" 时,在运行 Android 6.0 (API 级别 23) 或更高版本的设备上安装您的应用,将导致系统自动验证与您应用 Intent 过滤器中 URL 相关联的主机。在 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 的数字资产链接文件。

确认要与应用关联的网站列表,并确认托管的 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 应用链接的状态

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

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

此命令将设备置于用户为任何域选择默认应用之前的相同状态。

调用域验证过程

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

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 状态表示验证代理可能尚未完成验证过程。

以下列表显示了域验证可针对给定域返回的可能返回值

此域尚未记录任何信息。再等待几分钟,让验证代理完成与域验证相关的请求,然后再次调用域验证过程
已验证
该域已成功为声明应用验证。
已批准
该域已被强制批准,通常通过执行 shell 命令完成。
已拒绝
该域已被强制拒绝,通常通过执行 shell 命令完成。
已迁移
系统保留了使用旧版域验证的先前过程的结果。
已恢复
用户执行数据恢复后,该域已获得批准。假定该域之前已验证。
旧版失败
该域被旧版验证器拒绝。具体失败原因不明。
系统配置
该域已由设备配置自动批准。
错误代码 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 的输出提供了这些命令的完整解释。

为请求提供上下文

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

发出请求

用户了解您的应用要求他们做什么后,发出请求。为此,请调用一个 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 所示。当用户稍后选择他们添加的域中的任何链接时,该链接会自动在您的应用中打开。

When the radio button is enabled, a section near the bottom
    includes checkboxes as well as a button called 'Add link'
图 1. 用户可以在其中选择默认情况下在您的应用中打开哪些链接的系统设置屏幕。
Each checkbox represents a domain that you can add. The
    dialog's buttons are 'Cancel' and 'Add.'
图 2. 用户可以在其中选择要与您的应用关联的其他域的对话框。

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

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

此外,考虑引入一个对话框或跳板 Activity,允许用户在首选的情况下在第一方应用中打开链接,充当代理。在设置此类对话框或跳板 Activity 之前,请设置您的应用,使其对与您应用的 Web Intent 过滤器匹配的第一方应用具有软件包可见性

测试应用链接

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

要测试现有的声明文件,您可以使用 声明列表生成器和测试工具

确认要验证的主机列表

测试时,您应该确认系统应为您的应用验证的关联主机列表。列出所有其相应 Intent 过滤器包含以下属性和元素的 URL

  • android:scheme 属性,值为 httphttps
  • android:host 属性,带有域 URL 模式
  • android.intent.action.VIEW 操作元素
  • android.intent.category.BROWSABLE 类别元素

使用此列表检查每个指定主机和子域是否提供了数字资产链接 JSON 文件。

确认数字资产链接文件

对于每个网站,使用数字资产链接 API 确认数字资产链接 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 - 显示此应用处理的 Web 链接的所有主机的完整列表,使用空格作为分隔符。
  • 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 应用链接,请检查以下常见错误。本节使用 example.com 作为占位符域名;执行这些检查时,请将 example.com 替换为您的服务器的实际域名。

Intent 过滤器设置不正确
检查您是否在 <intent-filter> 元素中包含了一个您的应用不拥有的 URL。
服务器配置不正确

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

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

服务器端重定向

如果您设置了以下重定向,系统将不会验证您的应用的任何 Android 应用链接

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

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

服务器健壮性

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

不可验证的链接

为了测试目的,您可能会故意添加不可验证的链接。请记住,在 Android 11 及更低版本上,这些链接会导致系统无法验证您的应用的所有 Android 应用链接。

assetlinks.json 中的签名不正确

验证您的签名是否正确并与用于签署您的应用的签名匹配。常见的错误包括

  • 使用调试证书签署应用,而 assetlinks.json 中只有发布签名。
  • assetlinks.json 中的签名是小写。签名应该是大写。
  • 如果您正在使用 Play 应用签名,请确保您使用的是 Google 用于签署您每个版本的签名。您可以通过遵循有关声明网站关联的说明来验证这些详细信息,包括完整的 JSON 片段。