深层链接
本教程共 100 篇 · 第 87 篇 · 更新于 2026-07-28 · 约 7 分钟阅读
87. 深层链接
本节目标:理解 Deep Link 和 App Link 的区别,学会在 manifest 配置 intent-filter、用 Navigation Compose 处理链接、用 URL scheme 自定义跳转,让外部链接直达应用内页面。
深层链接(Deep Link)是一种 URL,点击后能直接打开应用里的特定页面。比如邮件里的「https://app.com/product/123」点开直接跳到商品详情页,不用先打开应用再手动找。
三种链接
1. Deep Link(普通深层链接)
http:// 或 https:// 开头,配 intent-filter。点击时系统弹「用哪个应用打开」选择框。
2. App Link(应用链接)
特殊的 Deep Link,配 autoVerify。系统验证你的网站确实声明了「这个链接归这个应用管」,通过后点击不再弹选择框,直接打开应用。
3. Custom URL Scheme(自定义协议)
myapp:// 这种自定义协议,应用专属。点击直接打开应用,不弹选择框,但和真实 URL 不兼容。
Deep Link 基础
第一步:manifest 配置
在能响应链接的 Activity 上加 intent-filter:
<activity android:name=".MainActivity">
<intent-filter android:autoVerify="false">
<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="myapp.com"
android:pathPrefix="/product" />
</intent-filter>
</activity>
要点:
action.VIEW+category.DEFAULT+category.BROWSABLE三件套。scheme协议、host域名、pathPrefix/pathPattern/path路径。- 匹配规则:scheme 和 host 必须完全匹配,路径用前缀或者正则。
第二步:处理 Intent
Activity 里拿到 Intent 解析参数:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
intent?.let { handleDeepLink(it) }
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
handleDeepLink(intent)
}
private fun handleDeepLink(intent: Intent) {
val uri = intent.data ?: return
val productId = uri.lastPathSegment // /product/123 -> "123"
// 跳到详情页
}
}
onNewIntent 是 Activity 已经在前台时再次收到链接触发。
Navigation Compose 集成
Compose 项目用 Navigation Compose 处理深层链接更优雅:
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = "home"
) {
composable(
route = "product/{id}",
deepLinks = listOf(navDeepLink {
uriPattern = "https://myapp.com/product/{id}"
})
) { backStackEntry ->
val id = backStackEntry.arguments?.getString("id")
ProductScreen(id)
}
}
然后从 Intent 提取 URI 交给 NavController:
LaunchedEffect(Unit) {
val intent = (context as Activity).intent
intent.data?.let { uri ->
navController.handleDeepLink(intent)
}
}
Navigation Compose 自动匹配 URI 模板,把 {id} 提取成参数。
App Link
App Link 是经过验证的 Deep Link,点击不弹选择框直接打开应用。验证流程:
第一步:manifest 加 autoVerify
<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="myapp.com" />
</intent-filter>
autoVerify="true" 告诉系统去验证网站。
第二步:网站放验证文件
在 https://myapp.com/.well-known/assetlinks.json 放一个 JSON 文件,声明哪个应用能管这个域名:
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example.myapp",
"sha256_cert_fingerprints": [
"AB:CD:EF:..."
]
}
}
]
sha256_cert_fingerprints 是应用签名证书的 SHA256 指纹,用 keytool 命令查:
keytool -list -v -keystore my-release-key.jks
第三步:系统验证
应用安装时,系统会去访问那个 JSON 文件验证。验证通过后,https://myapp.com/... 链接点击直接打开应用,不弹选择框。
Warning验证失败的原因:JSON 文件路径错(必须是
/.well-known/assetlinks.json)、域名 HTTPS 证书无效、签名指纹不对、服务器返回非 200。用adb shell pm verify-app-links命令查看验证状态。
自定义 Scheme
不用 http/https,自定义协议:
<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="myapp" />
</intent-filter>
myapp://product/123 这种链接直接打开应用。
val uri = intent.data // myapp://product/123
val id = uri?.lastPathSegment
自定义 scheme 的优缺点:
- 优点:不用配域名验证,简单。
- 缺点:不和真实 URL 兼容(用户没装应用点击没反应),多个应用可能用同一个 scheme 冲突。
Note新应用优先用 App Link,自定义 scheme 留给特殊场景(如 OAuth 登录回调)。
测试深层链接
用 adb 模拟点击链接:
adb shell am start -W -a android.intent.action.VIEW -d "https://myapp.com/product/123" com.example.myapp
-W 显示启动时间,-d 指定 URL。
测试 App Link 验证:
adb shell pm verify-app-links --revoke com.example.myapp
adb shell pm verify-app-links com.example.myapp
Pending Intent 和通知
通知的点击跳转本质也是深层链接,通过 PendingIntent 启动 Activity,Intent 里带 URI:
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("myapp://product/123"))
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_IMMUTABLE)
浏览器跳转
用户在浏览器看到 https://myapp.com/product/123,点击时:
- 系统查 intent-filter。
- 匹配到应用。
- 没配 autoVerify:弹「用哪个应用打开」选择框(应用 + 浏览器)。
- 配了 autoVerify 且验证通过:直接打开应用,不弹框。
- 应用没装:用浏览器打开网页。
常见坑
- pathPrefix 和 pathPattern 用混:pathPrefix 是前缀匹配,pathPattern 支持正则(
.*)。 - autoVerify 验证失败没察觉:用
adb shell pm verify-app-links查。 - 签名变了没更新 assetlinks.json:换签名后验证失败。
- 网站不支持 HTTPS:系统不验证 HTTP。
- 自定义 scheme 冲突:和其他应用用同一个 scheme,弹选择框。
- Navigation Compose 的 URI 模板写错:
{id}参数名要和路由里的对上。
小结
深层链接让 URL 直接打开应用页面。普通 Deep Link 配 intent-filter,App Link 加 autoVerify + 网站验证文件(assetlinks.json),自定义 scheme 用 myapp://。Compose 项目用 Navigation Compose 的 navDeepLink 集成。测试用 adb shell am start 模拟点击。
下一章进入多媒体与传感器部分,先看怎么播放音频。