在实现应用链接功能时,您应该测试链接功能,以确保系统能够将您的应用和网站相关联,并按预期方式处理网址请求。
如需测试现有语句文件,您可以使用语句列表生成器和测试器工具。
以下部分介绍了如何手动测试您的应用链接验证。如果您愿意,也可以通过 Play 深层链接工具或 Android Studio App Links Assistant 测试验证。
确认需要验证的主机列表
测试时,您应该对系统需要针对您的应用验证的已关联主机列表进行确认。创建一个列表,在其中列出所有相关网址,此类网址对应的 intent 过滤器包含以下属性和元素:
android:scheme属性,值为http或https- 具有网域网址格式的
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>&
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)
如需详细了解语句列表,请参阅创建语句列表。
使用 debug-link 标志诊断链接解析
从 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 过滤器中的哪些静态属性(例如scheme、host、path、pathPrefix或pathPattern)与 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 = 1、filter = /foo):此规则是从{"/": "/foo*", "exclude": true}生成的排除规则 (allow: false),用于屏蔽以/foo路径前缀开头的网址。 - 规则 1(
allow = 0、filter =):此规则是从{"/": "*"}生成的,属于包含规则 (allow: true),具有空的路径前缀 (filter =),可匹配xyz.com下的所有路径(全盘匹配)。
此情形下的解决方式:
- 规则 0 和规则 1 都与网址
https://xyz.com/foo匹配。 - 系统会按从上到下的顺序依次评估动态应用链接规则(第一个匹配的规则胜出)。
- 由于规则 0 显示在语句列表中的最前面,并且是一条排除规则 (
allow = 1),因此它优先于常规的允许规则(规则 1)。 - 因此,应用被排除在
https://xyz.com/foo的处理范围之外,导致系统回退到浏览器或显示消除歧义对话框。