intent中的setData用处,还有教程好像在视频中讲到了在activity中设置<data android:scheme>这是干嘛de
setData() 干的只有一件事:
把一条 Uri 塞进 Intent,告诉系统“我要操作的这个‘东西’在哪儿”。
没有它,隐式 Intent 就只剩“动作”(action)和“类别”(category),系统无法精确匹配到组件;有了它,才能跟清单里的 <data> 标签“对暗号”。
1. setData() 到底有什么用
val intent = Intent(Intent.ACTION_VIEW) // 动作:查看
intent.setData(Uri.parse("https://www.example.com")) // 数据:具体看哪个
startActivity(intent)
- 系统会把
action=VIEW+data=https://www.example.com拿去跟所有 exported=true 且声明了<intent-filter>的 Activity 匹配。 - 只有那些过滤器里 scheme、host、path 都吻合 的 Activity 才会被弹出来(或被你启动)。
2. 清单里的 <data android:scheme="..."> 是干嘛的
它就是在 声明自己愿意接受什么样的 Uri。
没有 <data> 的过滤器等于“我什么 Uri 都不接”,带 setData() 的 Intent 根本匹配不到。
示例:
<activity android:name=".DeepLinkActivity" 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"/>
<!-- 只接 https 且 host 是 example.com 的 Uri -->
<data android:scheme="https"
android:host="example.com"
android:pathPattern="/item/.*"/>
</intent-filter>
</activity>
- 外部浏览器点击
https://example.com/item/123就会唤起你的DeepLinkActivity。 - 如果 scheme 写成
myapp,那只有myapp://detail/123才能唤起,浏览器再也进不来。
3. 常见 scheme 对照表
| scheme | 典型用途 |
|---|---|
http / https | 网页、DeepLink |
file | 本地文件(Android 7+ 需 FileProvider) |
content | 通过 ContentProvider 暴露的 URI(最安全) |
market | 跳 Google Play |
myapp | 自定义 DeepLink / 多进程通信 |
4. setData() 与 setType() 同时用?
- 不能直接
setData()后又setType(),后者会清掉前者。 - 要同时指定 Uri 和 MIME,用 合体 API:
intent.setDataAndType(uri, "image/jpeg")
✅ 一句话总结
setData() 给 Intent 塞 Uri;清单里的
<data>声明组件能接什么 Uri。
两者合起来才完成“动作 + 数据”的精确匹配,是隐式 Intent 的基石。
那么uri是会交给浏览器处理还是activity中处理
比如我传入了一个链接,是会在浏览器中打开网页还是该activity中打开
看 谁抢先 + 谁匹配——Uri 不会“自动”进浏览器,而是系统把 所有符合条件的 Activity 拉个列表(也叫 disambiguation dialog),让用户挑;如果只有 一个 匹配,就直接进那一个,浏览器还是你自己的 Activity 都有可能。
1. 匹配规则(简化版)
系统按 优先级顺序 过滤:
- scheme
- host(仅当 scheme 是 http/https 且声明了 host)
- path/pathPrefix/pathPattern
- mimeType(若有
setType())
2. 场景实测
| 你传的 Uri | 设备已安装 | 结果 |
|---|---|---|
https://example.com/item/123 | 只有浏览器 声明了 https | 直接进 浏览器 |
| 同上 | 浏览器 + 你的 Activity 都声明 https + host=example.com | 弹出 选择框(含浏览器和你) |
| 同上 | 只有你的 Activity 声明了 https + host=example.com | 直接进 你的 Activity,浏览器 不会出现 |
myapp://detail/123 | 只有你的 Activity 声明 myapp 方案 | 直接进 你的 Activity;浏览器根本收不到 |
3. 如何确保 一定进自己的 Activity
- 用 自定义 scheme(不与浏览器冲突)
<data android:scheme="myapp" />
- 强制指定包名,绕过选择框:
val intent = Intent(Intent.ACTION_VIEW,
Uri.parse("myapp://detail/123"))
intent.setPackage("com.example.yourapp") // 直接锁定自己
startActivity(intent)
- 利用 Android 12 的 App-link(需数字证书 + 服务器验证)
声明android:autoVerify="true"且上传assetlinks.json,可把https链接 默认 导向你的 Activity,不出现选择框(用户可手动改)。
✅ 一句话结论
Uri 交给谁,不由“浏览器”说了算,而由“谁的
<intent-filter>匹配 + 用户/系统选择”决定;
想独占链接,就用自定义 scheme 或 verified app-link,再或者 setPackage 直接点名。