Intent Filter
本教程共 100 篇 · 第 30 篇 · 更新于 2026-07-28 · 约 8 分钟阅读
30. Intent Filter
本节目标:理解 Intent Filter 的作用、掌握 action/category/data 的匹配规则、会为自己的 Activity 声明 Intent Filter 响应隐式 Intent 和深层链接。
Intent Filter 是什么
Intent Filter(意图过滤器)是 Manifest 里声明的「我能处理什么样的 Intent」。系统根据它来判断某个组件能不能响应隐式 Intent。
比如你声明「我的 Activity 能处理 ACTION_VIEW 的 https 数据」,那别人发隐式 Intent 想打开网页时,你的 Activity 就会出现在候选列表里。
<activity android:name=".WebViewActivity" android:exported="true">
<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="example.com" />
</intent-filter>
</activity>
没声明 Intent Filter 的组件只能被显式 Intent 启动。
三大匹配要素
Intent Filter 用 <intent-filter> 标签声明,里面有三种子元素:
1. action
声明能响应的动作。一个 filter 能有多个 action,Intent 的 action 匹配其中任一个即可。
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.EDIT" />
</intent-filter>
匹配规则:Intent 的 action 必须等于 filter 里某一个 action。Intent 没指定 action 则不匹配。
2. category
声明组件类别。Intent 的所有 category 必须都在 filter 里能找到对应。
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
关键点:
startActivity/startActivityForResult用的隐式 Intent,系统自动加上CATEGORY_DEFAULT。所以想让 Activity 能被隐式 Intent 启动,filter 里必须声明DEFAULT。- 入口 Activity 的 filter 要有
LAUNCHER类别。 BROWSABLE类别让 Activity 能从网页(点击链接)被调起。
3. data
声明能处理的数据类型,用 URI 的几个部分描述:
<data
android:scheme="https"
android:host="example.com"
android:port="8080"
android:path="/path"
android:pathPrefix="/articles/"
android:pathPattern=".*\\.pdf"
android:mimeType="image/*" />
| 属性 | 含义 | 例子 |
|---|---|---|
scheme | URI scheme | https、content、file、tel |
host | 主机名 | example.com |
port | 端口 | 8080 |
path | 完整路径 | /path |
pathPrefix | 路径前缀 | /articles/ |
pathPattern | 路径模式 | .*\\.pdf |
mimeType | MIME 类型 | image/*、text/plain |
匹配规则:
- Intent 有 URI 时,filter 的 scheme/host/path 要匹配。
- Intent 有 type 时,filter 的 mimeType 要匹配(支持
*通配)。 - 一个 filter 能有多个
<data>,任一匹配即可。
匹配的综合规则
系统找匹配组件时,要同时满足 action、category、data 三个条件:
- Action:Intent 的 action 在 filter 的 action 列表里。
- Category:Intent 的每个 category 都在 filter 的 category 列表里(
DEFAULT自动加,filter 必须有)。 - Data:Intent 的 data(URI + type)匹配 filter 的 data 声明。
三个都满足才算匹配。多个组件匹配时,系统弹选择框(除非用 createChooser)。
入口 Activity 的 Filter
桌面启动入口:
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
ACTION_MAIN:应用主入口。CATEGORY_LAUNCHER:在桌面显示图标。
这个组合是固定的,入口 Activity 必须有。
让 Activity 响应深层链接
http/https 深层链接
让你的 Activity 能被「点击网页链接」调起:
<activity android:name=".ProductActivity" android:exported="true">
<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="shop.example.com" android:pathPrefix="/product/" />
</intent-filter>
</activity>
用户在浏览器点 https://shop.example.com/product/123,会弹选择「用浏览器打开还是用你的应用打开」。
class ProductActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val productId = intent.data?.lastPathSegment // "123"
// 根据 productId 加载商品详情
}
}
App Link(Android 6+)
App Link 让你的应用直接打开链接,不弹选择框(成为默认处理者)。需要:
-
Intent Filter 加
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="shop.example.com" /> </intent-filter> -
在网站
https://shop.example.com/.well-known/assetlinks.json部署数字资产链接 JSON,验证应用身份。
装了应用后,系统会去这个网址验证,验证通过就默认用你的应用打开链接。第 87 章细讲。
自定义 scheme
用 myapp:// 这种自定义 scheme:
<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://open?data=xxx 能调起你的应用。
Warning
- 自定义 scheme 不推荐用于深层链接,容易被其他应用劫持(scheme 冲突)。优先用 https + App Link。自定义 scheme 适合回调场景(如 OAuth 登录回调)。
让 Activity 处理特定 MIME 类型
比如让 Activity 能打开 PDF:
<activity android:name=".PdfViewerActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/pdf" />
</intent-filter>
</activity>
用户在文件管理器点 PDF,能选择用你的应用打开。
Compose 与 Intent Filter
Compose 项目里,Intent Filter 仍声明在 Manifest(针对那个宿主 Activity)。深层链接的处理交给 Navigation Compose:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val navController = rememberNavController()
NavHost(navController, startDestination = "home") {
composable("home") { HomeScreen() }
composable(
route = "product/{id}",
deepLinks = listOf(navDeepLink { uriPattern = "https://shop.example.com/product/{id}" })
) { backStackEntry ->
ProductScreen(backStackEntry.arguments?.getString("id"))
}
}
}
}
}
Manifest 里给 MainActivity 声明对应的 Intent Filter,Navigation 的 deepLinks 会自动处理。
调试 Intent Filter
验证匹配
用 adb 命令模拟隐式 Intent:
adb shell am start -a android.intent.action.VIEW -d "https://shop.example.com/product/123"
看哪个应用被启动。
查看应用的 Intent Filter
adb shell dumpsys package com.example.app
输出里能看到所有声明的 Intent Filter。
小结
Intent Filter 声明组件能处理什么 Intent,三大要素:action(动作)、category(类别,隐式 Intent 必须有 DEFAULT)、data(URI scheme/host/path + mimeType)。匹配要三者都满足。入口 Activity 用 MAIN + LAUNCHER。深层链接用 https + BROWSABLE,App Link 加 autoVerify 实现默认打开。下一节看常用系统 Intent。