首页 / Android 入门教程 / 深层链接

Android 入门教程

深层链接

本教程共 100 篇 · 第 87 篇 · 更新于 2026-07-28 · 约 7 分钟阅读

AndroidAndroid 入门教程深层链接Deep LinkApp LinkURL scheme

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 不兼容。

第一步: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 已经在前台时再次收到链接触发。

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 是经过验证的 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,点击时:

  1. 系统查 intent-filter。
  2. 匹配到应用。
  3. 没配 autoVerify:弹「用哪个应用打开」选择框(应用 + 浏览器)。
  4. 配了 autoVerify 且验证通过:直接打开应用,不弹框。
  5. 应用没装:用浏览器打开网页。

常见坑

  1. pathPrefix 和 pathPattern 用混:pathPrefix 是前缀匹配,pathPattern 支持正则(.*)。
  2. autoVerify 验证失败没察觉:用 adb shell pm verify-app-links 查。
  3. 签名变了没更新 assetlinks.json:换签名后验证失败。
  4. 网站不支持 HTTPS:系统不验证 HTTP。
  5. 自定义 scheme 冲突:和其他应用用同一个 scheme,弹选择框。
  6. Navigation Compose 的 URI 模板写错{id} 参数名要和路由里的对上。

小结

深层链接让 URL 直接打开应用页面。普通 Deep Link 配 intent-filter,App Link 加 autoVerify + 网站验证文件(assetlinks.json),自定义 scheme 用 myapp://。Compose 项目用 Navigation Compose 的 navDeepLink 集成。测试用 adb shell am start 模拟点击。

下一章进入多媒体与传感器部分,先看怎么播放音频。