测试应用链接

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

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

以下部分介绍了如何手动测试您的应用链接验证。如果您愿意,也可以通过 Play 深层链接工具或 Android Studio App Links Assistant 测试验证。

确认需要验证的主机列表

测试时,您应该对系统需要针对您的应用验证的已关联主机列表进行确认。创建一个列表,在其中列出所有相关网址,此类网址对应的 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://<var>domain.name</var>:<var>optional_port</var>&amp;
   relation=delegate_permission/common.handle_all_urls

对于动态应用链接,您还可以检查关系扩展。

https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://www.example.com&relation=delegate_permission/common.handle_all_urls&return_relation_extensions=true

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

adb shell dumpsys package domain-preferred-apps

以下命令会执行相同的操作:

adb shell dumpsys package d

该命令会返回设备上定义的每个用户或个人资料的清单,前面带有以下格式的标头:

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 过滤器中指定的每个网站验证您的应用。以下示例展示了定义多个应用链接的清单配置:

<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 17 开始,您可以将 --debug-link 标志与 activity 管理器 (am start) 命令搭配使用,以诊断系统如何解析特定网址。此工具可详细分析与 intent 匹配的候选应用,以及在解析期间评估的应用清单和 assetlinks.json 文件(对于动态应用链接)中的具体规则。

如需测试特定网址的链接解析,请在终端窗口中运行以下命令:

adb shell am start --debug-link -a android.intent.action.VIEW -d "https://xyz.com/foo"

诊断输出会打印在 App Link Resolution Debug 标题下,包含以下部分,可帮助您了解问题解决过程:

  • 目标详情:通过软件包名称和目标 activity 标识每个匹配的候选应用。
  • Intent 过滤器匹配 (AndroidManifest.xml):显示清单 intent 过滤器中的哪些静态属性(例如 schemehostpathpathPrefixpathPattern)与 URI 相匹配。
  • 应用链接验证:显示当前的网域验证状态(例如 STATE_SUCCESS)。
  • 动态应用链接:如果应用在其 assetlinks.json 文件中使用动态应用链接匹配规则,此部分会列出针对 URI 评估的每条规则。每条规则都包含匹配的 URI 过滤条件(例如路径前缀或模式)和一个 allow 字段:
    • allow = 0允许/包含规则 (allow: true)。如果此规则匹配,则允许应用打开 URI。
    • allow = 1屏蔽/排除规则 (allow: false / exclude: true)。如果此规则匹配,则应用无法打开 URI。
    • 注意:空过滤字符串 (filter =) 表示空路径前缀,该前缀与网域下的所有路径匹配(充当通配符或全能匹配项)。

调试输出示例

假设某个应用 (com.example.xyzapp) 与网域 https://xyz.com 相关联,该应用在其 assetlinks.json 文件中定义了动态规则,以排除 /foo*,同时允许所有其他路径:

[
  {
    "relation": [
      "delegate_permission/common.handle_all_urls"
    ],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.xyzapp",
      "sha256_cert_fingerprints": ["..."]
    },
    "relation_extensions": {
      "delegate_permission/common.handle_all_urls": {
        "dynamic_app_link_components": [
          {"/": "/foo*", "exclude": true},
          {"/": "*"}
        ]
      }
    }
  }
]

使用 --debug-link 诊断网址 https://xyz.com/foo 时:

adb shell am start --debug-link -a android.intent.action.VIEW -d "https://xyz.com/foo"

该命令会输出以下诊断细分信息:

--- App Link Resolution Debug ---

URI: https://xyz.com/foo
Resolution: Ambiguous (Multiple apps or Browser fallback)
This usually happens when multiple apps can handle the link and no default is set.

All Matching Candidates:

Target:
  Package: com.example.xyzapp
  Activity: com.example.xyzapp.MainActivity

  Intent Filter Match (AndroidManifest.xml)
    Scheme: 'https' matched android:scheme="https"
    Host: 'xyz.com' matched android:host="xyz.com"

App Link Verification:
  Verification status: STATE_SUCCESS
  Dynamic App Links:
    -> Matched Rule 0: UriRelativeFilterGroup { allow = 1, uri_filters = {UriRelativeFilter { uriPart = PATH, patternType = PREFIX, filter = /foo }},  }
    -> Matched Rule 1: UriRelativeFilterGroup { allow = 0, uri_filters = {UriRelativeFilter { uriPart = PATH, patternType = PREFIX, filter =  }},  }

Target:
  Package: org.chromium.webview_shell
  Activity: org.chromium.webview_shell.WebViewBrowserActivity

  Intent Filter Match (AndroidManifest.xml)
    Scheme: 'https' matched android:scheme="https"

---------------------------------

Starting: Intent { act=android.intent.action.VIEW dat=https://xyz.com/foo }

在此示例中,系统评估了 assetlinks.json 中的两条动态应用链接规则:

  • 规则 0(allow = 1filter = /foo:此规则是从 {"/": "/foo*", "exclude": true} 生成的排除规则 (allow: false),用于屏蔽以 /foo 路径前缀开头的网址。
  • 规则 1(allow = 0filter =:此规则是从 {"/": "*"} 生成的,属于包含规则 (allow: true),具有空的路径前缀 (filter =),可匹配 xyz.com 下的所有路径(全盘匹配)。

此情形下的解决方式

  1. 规则 0 和规则 1 都与网址 https://xyz.com/foo 匹配。
  2. 系统会按从上到下的顺序依次评估动态应用链接规则(第一个匹配的规则胜出)。
  3. 由于规则 0 显示在语句列表中的最前面,并且是一条排除规则 (allow = 1),因此它优先于常规的允许规则(规则 1)。
  4. 因此,应用被排除在 https://xyz.com/foo 的处理范围之外,导致系统回退到浏览器或显示消除歧义对话框。