一、Android 应用链接简介
在Android中,可以通过设置 Android 应用链接,以便将用户直接转到链接指向的特定内容,从而绕过应用选择对话框。由于 Android 应用链接利用的是 HTTP 网址以及与网站的关联,因此,如果设备上未安装指定的应用,将会直接转到网站对应的内容。
1.1 深层链接和 Android 应用链接
1.1.1 深层链接
深层链接是指将用户直接转到应用中的特定内容的网址。在 Android 中,可以通过添加 intent 过滤器 以及从传入的 intent 中提取深层链接设置的数据,以便将用户引导到正确的 Activity。但是,如果设备上安装了其他应用也可以处理相同的 intent,则用户可能无法直接进入您的应用,而是弹出应用选择对话框让用户选择打开的应用。例如,点击银行发来的电子邮件中的网址可能会显示一个对话框,询问用户是使用浏览器还是银行自己的应用打开此链接。当然,可以通过自定义独独一无二的协议头,来规避应用选择对话框(因为深层链接的协议头是可以自定义的)。
1.1.2 Android 应用链接
Android 应用链接可以使得应用将自己指定为给定类型链接的默认处理程序,打开应用链接时,直接打开应用,从而避开应用选择对话框。如果用户不想使用某个应用作为默认处理程序,则可以从设备的系统设置中替换此行为。Android 应用链接其实也是深层链接的一种,需要 Android 6.0(API 级别 23)及更高版本中才能生效。
Android 应用链接有以下好处:
- 安全且具体:Android 应用链接使用的是链接到您自己的网站网域的 HTTP 网址,因此其他应用都无法使用您的链接。Android 应用链接的要求之一,就是要通过我们的某个网站关联方法验证您对网域的所有权。如果不进行所有权验证,那么您的 Android 应用链接就跟普通的深层链接没有差别了。
- 顺畅的用户体验:因为 Android 应用链接针对您的网站和应用中的相同内容使用单个 HTTP 网址,因此未安装应用的用户会直接转到您的网站,不会显示 404,也不会出现错误。
- 通过 Google 搜索吸引用户:用户可以通过在移动浏览器、Google 搜索应用、Android 中的屏幕搜索中或通过 Google 助理点击来自 Google 的网址,直接打开应用中的特定内容。
注意:Android 的应用链接必须是 HTTP 网址。
二、Android 应用链接的使用
当点击的链接或程序化请求调用网页 URI intent 时,Android 系统会按顺序尝试执行以下每项操作,直到请求成功为止:
- 如果用户指定了可以处理该 URI 的首选应用,则打开此应用。
- 打开唯一可以处理该 URI 的应用。
- 允许用户从对话框中选择应用。
创建 Android 应用链接的一般步骤如下:
- 创建指向应用中特定内容的深层链接:在
AndroidManifest.xml
中,为网站 URI 创建 intent 过滤器,并将应用配置为使用来自相关 intent 的数据,以便将用户引导至应用中的正确内容。如需了解详情,请参阅创建指向应用内容的深层链接。 - 为深层链接添加验证要求:将应用配置为要求验证应用链接。然后,在您的网站上发布 Digital Asset Links JSON 文件,以通过 Google Search Console 验证所有权。如需了解详情,请参阅 验证 Android 应用链接。
2.1 创建 Android 应用链
2.1.1 添加 Intent 过滤器
打开 AndroidManifest.xml
清单文件,在映射的 Activity 声明中,添加 Intent 过滤器(即添加 <intent-filter>
标签)
示例:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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"
android:host="www.owen.com"
android:path="/test" />
</intent-filter>
</activity>
应用链接的 Intent 过滤器,需要包含以下元素和属性值:
-
<action>
:指定为 android.intent.action.VIEW 操作,以便能够从外部访问此 intent 过滤器; -
<data>
:添加一个或多个<data>
标签,每个<data>
标签代表一种可解析到 Activity 的 URI 格式。<data>
标签至少需要包含android:scheme
(协议头)属性。标签内还可以添加更多属性,以进一步细化 Activity 接受的 URI 类型。 例如:anroid:host
(域名)、android:path
(固定路径,必须以“/”开头)、android:pathPrefix
(路径前缀,必须以“/”开头)、android:pathPattern
(路径正则,必须以“/”开头)。 -
<category>
:包含 android.intent.category.BROWSABLE 类别,如果要从网络浏览器中访问 intent 过滤器,则必须包含这个类别,否则在浏览器中点击链接便无法解析到应用。此外,还要包含 android.intent.category.DEFAULT" 类别,这样应用才可以响应隐式 intent。否则,需要在 intent 指定应用组件名称才能启动相应的 Activity。
示例:
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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"
android:host="www.owen.com"
android:path="/user"/>
</intent-filter>
<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="owenapp"
android:host="www.owen.com"
android:pathPrefix="/user"/>
</intent-filter>
</activity>
在上面的例子中,展示了如何在清单中为深层链接指定 intent 过滤器。URI owenapp://www.owen.com/user
和 https://www.owen.com/user
都可以解析为此 Activity。
注意事项:
1. 如果<data>
标签内包含了路径相关属性,例如:android:path
,则必须包含android:host
属性;
2.<data>
元素是两个 intent 过滤器的唯一区别,虽然同一过滤器可以包含多个<data>
元素,但如果想要声明唯一网址(例如特定的 scheme 和 host 组合),请务必创建单独的过滤器,因为同一 intent 中如果有<data>
元素,实际上会将这些属性分开进行组合,以涵盖所有的变体。
示例:
<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"
android:host="www.owen.com"/>
<data
android:scheme="owenapp"
android:host="www.owenpay.com"/>
</intent-filter>
在上面的示例中,表面上看 Intent 过滤器似乎只支持 owenapp://www.owenpay.com
和 https://www.owen.com
,但实际上它还支持https://www.owenpay.com
和 owenapp://www.owen.com
,如果添加更多的属性,还会分解成更多的变体。
2.1.2 读取传入 Intent 中的数据
通过应用链接打开应用,系统通过 Intent 启动对应的Activity,在 Activity 启动之后,可以在 Activity 中获取 Intent 传入的参数内容。在 Activity 中调用 getIntent()
API 获取传入的 Intent,使用 Intent.getAction()
和 Intent.getData()
API 可获取 Intent 中传入的数据。
示例:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val action = intent?.action
val data = intent?.data
}
}
注意:可以在 Activity 声明周期中的任何时间随时调用获取 Intent 数据的这些方法。
2.1.3 测试深层链接
到目前为止,应用配置的只能算是深层链接。要测试深层链接指定的 intent 过滤器 URI 是否可以解析为正确的应用 Activity,可以通过Android 调试桥与 Activity 管理器 (am) 工具结合使用,针对设备或模拟器运行 adb 命令。
使用 adb 测试 intent 过滤器 URI 的一般语法为:
$ adb shell am start -W -a android.intent.action.VIEW -d <URI> <PACKAGE>
-W
选项:等待 Activity 启动完成-a
选项:Action参数,启动的动作-d
选项: 目标参数,如 URI
说明:如果没有指定
<PACKAGE>
,有可能出现消除歧义对话框(即应用选择对话框),只要最终能跳转到指定的 Activity 就说明测试通过。另外,可以使用 Android Studio 中的 “Tools-》App Links Assistant -》Test App Links”也可以测试,不喜欢命令行的小伙伴可以使用这个工具进行测试。
2.2 验证 Android 应用链接
Android 应用链接是一种特殊类型的深层链接,可让您的网站网址直接在您的 Android 应用中打开相应内容(不会弹出应用选择弹窗)。要向应用添加 Android 应用链接,首先要定义使用 HTTP 网址打开应用内容的 intent 过滤器(如 创建 Android 应用链接中所述),并验证您是否为相关应用和网站网址的所有者。如果系统成功验证您是网址所有者,则会自动将这些网址 intent 路由到您的应用,不会出现消除歧义对话框。
要验证您对应用和网站的所有权,您需要执行以下步骤:
- 在清单中请求自动验证应用链接。这样即可向 Android 系统说明其应该验证您的应用是否属于 intent 过滤器中使用的网址网域。
- 通过在以下位置托管 Digital Asset Links JSON 文件,声明您的网站和 intent 过滤器之间的关系:
https://domain.name/.well-known/assetlinks.json
注意:Android 应用链接必须经过了验证之后才会有其特性,如果未经过验证或者验证失败,Android 系统只会当做普通的深层链接进行处理。
2.2.1 添加自动验证配置
在 AndroidManifest.xml
清单文件中,在定义 Intent 过滤器的 <intent-filter>
标签内添加 android:autoVerify="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" />
<data
android:scheme="https"
android:host="www.owen.com"
android:path="/user"/>
</intent-filter>
注意:自动验证配置需要 Android 6.0 (API Level 23)及以上系统才支持。
2.2.2 生成 Digital Asset Links JSON 文件
需要证明您和应用和网站网址的关系,需要生成 Digital Asset Links JSON 文件,文件的内容大致如下:
[
{
"relation": [
"delegate_permission/common.handle_all_urls"
],
"target": {
"namespace": "android_app",
"package_name": "com.owen.androiddeeplink",
"sha256_cert_fingerprints": [
"1E:55:68:C9:04:D1:E8:CC:4A:5D:CD:DB:CD:3A:4D:F1:57:A6:33:9E:B7:A0:74:A1:88:38:12:98:0B:59:A8:B1"
]
}
}
]
可以通过 Android Studio 的 “Tools-》Android Links Assistant-》Open Digital Asset Links File Generator” 生成 Digital Asset Links JSON 文件。如下图:
- 网站域名;
- 应用包名;
- 应用签名(用来获取证书的SHA 256指纹);
- 生成 Digital Asset Links JSON 文件;
- 保存文件。
当然,这个文件也是可以手动进行生成,根据签名提到的内容样例,替换对应的参数即可。
说明:Digital Asset Links JSON 文件的名称必须固定,如果需要添加多个应用或者多个签名证书,可以修改文件,在对应的 JSON 数组中添加相关内容。
2.2.3 发布 Digital Asset Links JSON 文件
将 Digital Asset Links JSON 文件放到 https://domain.name/.well-known/assetlinks.json
(dmain.name
是要验证的域名)
2.2.4 测试网址 Intent
发布之后,可以测试前面的配置是否有效,是否会自动校验(这一步需要Android 6.0 及以上系统的设备),可以使用 adb 进行测试。
使用 adb 测试 intent 过滤器 URI 的一般语法为:
adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d "http://domain.name:optional_port"
因为应用链接是 HTTP 网址,通常浏览器会打开这个链接,如果执行这条命令之后,在设备安装了应用的情况下,会直接打开应用,而不是弹出消除歧义对话框,就说明验证通过了。当然,你也可以通过 Android Studio 的 “Tools -》 App Links Assistant-》Test On Device or Emulator” 界面化工具进行校验
- 输入校验的网址;
- 运行测试;
- 校验结果,这里一般分两步,先校验是否有对应的 Intent 过滤器,然后检测自动验证是否通过。
要添加对 Android 应用链接的支持,请执行以下操作:
- 在清单中创建 Intent 过滤器。
- 将代码添加到应用的 Activity 中以处理传入链接。
- 使用 Digital Asset Links 将应用与网站相关联。
2.2.5 检查链接政策
测试网址 Intent 通过之后,你可以检查系统当前的链接处理设置。可以使用以下命令获取已连接设备上所有应用的现有链接处理政策列表:
adb shell dumpsys package domain-preferred-apps
// 以下命令有同样的效果
adb shell dumpsys package d
注意:安装应用之后,请确保设备联网并至少等待 20 秒,以让系统完成验证流程。
检查返回的内容中,会包含以下格式的内容:
Package: com.google.android.play.games
Domains: play.google.com
Status: always : 200000008
- Package:应用包名(应用标识,在清单中声明)
- Domains:该应用处理的网络链接的全部 Host 列表(多个使用空格作为分隔符)
- Status:显示此应用当前链接处理设置,已通过验证且清单中包含
android:autoVerify="true"
的应用会显示 always 状态。此状态后的十六进制数字与 Android 系统的用户应用链接偏好设置记录有关。此值并不表示验证是否成功。
说明:以上命令会返回设备上定义的每个用户或个人资料的清单,前面带有
App linkages for user 0:
标头
三、深层链接和应用链接的区别
前面提到,深层链接是一种 intent 过滤器,可让用户直接进入 Android 应用中的特定 Activity。点击此类链接可能会打开一个消除歧义对话框,该对话框可以让用户从多个能够处理给定网址的应用(包括您的应用)中选择一个。但是应用链接是经过系统验证,对于指定的链接会优先通过您的应用打开,不会出现消除歧义对话框,但是在设备未安装应用的情况下,会打开链接指向的网址。深层链接的协议头可以是自定义的,但是应用链接必须 HTTP 协议(http 或者 https)。退一步来说,应用链接是深层链接的一种,没有通过验证的应用链接系统只能当做深层链接处理。
深层链接和应用链接的区别:
深层链接 | 应用链接 | |
---|---|---|
intent 网址协议 | http、https 或自定义协议 | 需要 http 或 https |
intent 操作 | 任何操作 | 需要 android.intent.action.VIEW |
intent 类别 | 任何类别 | 需要 android.intent.category.BROWSABLE 和 android.intent.category.DEFAULT |
链接验证 | 无 | 需要通过 HTTPS 协议在您的网站上发布 Digital Asset Links 文件 |
用户体验 | 可能会显示一个消除歧义对话框,以供用户选择用于打开链接的应用(可以通过自定义唯一协议头来规避消除协议对话框) | 无对话框,您的应用会打开以处理您的网站链接 |
兼容性 | 所有 Android 版本 | Android 6.0 及更高版本 |
说明:如果配置了应用链接,在不兼容的系统中,就会当做普通的深层链接进行处理。