
本文介绍如何通过自定义 scheme + intent filter 实现外部浏览器操作完成后自动拉起 app 并接收回调,无需用户手动切换,彻底消除流程中断。
本文介绍如何通过自定义 scheme + intent filter 实现外部浏览器操作完成后自动拉起 app 并接收回调,无需用户手动切换,彻底消除流程中断。
在 Android 开发中,当应用跳转至外部浏览器(如 Chrome)完成授权、支付或 OAuth 流程后,常需通过回调 URL 返回 App 并继续后续逻辑。但若此时 App 处于后台,仅靠标准 Intent.ACTION_VIEW 启动浏览器,浏览器完成操作后无法自动切回 App——用户必须手动切换,体验割裂且易失败。
根本原因在于:普通 HTTP/HTTPS 回调(如 http://127.0.0.1:54321/callback)无法被系统精确路由到你的 App;而 Android 的 Deep Link 机制(基于自定义 Scheme)才是实现无缝唤起的标准方案。
✅ 正确做法:使用自定义 Scheme 深度链接
1. 配置 AndroidManifest.xml
为接收回调的 Activity 添加专属 intent-filter,声明自定义 Scheme(如 myapp),移除不安全的 android:host 和 http scheme:
<activity android:name=".CallbackActivity" android:exported="true"><intent-filter><action android:name="android.intent.action.VIEW"></action><category android:name="android.intent.category.DEFAULT"></category><category android:name="android.intent.category.BROWSABLE"></category><data android:scheme="myapp"></data></intent-filter></activity>
⚠️ 注意:android:exported="true" 在 Android 12+ 是强制要求; 中不要指定 host 或 path(除非业务强依赖),避免匹配失败;http/https Scheme 需额外验证(App Links),复杂度高且非必需。
Android Adb Skill下载Android 开发调试技能,通过系统 ADB 工具操作 Android 设备。以下场景必须触发此技能:(1) 直接 ADB 操作——安装 APK、查看设备列表、抓取 logcat 日志、查看已安装应用、清除应用数据、截图、重启设备、拉取/推送文件、查看 CPU/内存/电池信息、adb shell 操作;(2)...
2. 构造带回调地址的浏览器 Intent
启动浏览器时,将自定义回调 URL(如 myapp://callback?code=abc&state=xyz)作为参数传递(推荐使用 Intent.EXTRA_REFERRER 或直接拼入目标网页 URL):
String callbackUrl = "myapp://callback";
String targetUrl = exe + "?redirect_uri=" + Uri.encode(callbackUrl); // 假设服务端支持 redirect_uri 参数
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(targetUrl));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setPackage("com.android.chrome"); // 可选:指定 Chrome,避免弹出选择框
context.startActivity(intent);
✅ 关键点:确保服务端(或第三方平台)在操作完成后,重定向至 myapp://callback?... 而非 http://...。这是唤起成功的前提。
3. 在 Activity 中捕获回调
- 若 App 未运行:系统会启动 CallbackActivity,通过 getIntent().getData() 获取回调数据;
- 若 App 已在后台运行:需重写 onNewIntent() 接收新 Intent:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent); // 必须调用,否则后续 getIntent() 仍返回旧 Intent
handleCallback(intent);
}
private void handleCallback(Intent intent) {
Uri data = intent.getData();
if (data != null && "myapp".equals(data.getScheme())) {
String code = data.getQueryParameter("code");
String state = data.getQueryParameter("state");
// ✅ 安全校验 state 防 CSRF,解析 code 执行 token 交换等逻辑
processAuthResult(code, state);
}
}
4. 补充建议与注意事项
- 状态一致性:务必在跳转前保存 state 参数(如 UUID),回调时严格比对,防止重放攻击;
- 多进程兼容:若使用 FLAG_ACTIVITY_NEW_TASK,确保 CallbackActivity 的 launchMode 为 singleTask 或 singleTop,避免重复实例;
- 降级处理:Chrome 可能因策略限制拒绝打开自定义 Scheme,可添加备用方案(如监听前台 Activity 生命周期 + 服务轮询,但非推荐主路径);
- 测试验证:使用 adb shell am start -W -a android.intent.action.VIEW -d "myapp://callback?test=1" 模拟回调,快速验证配置是否生效。
通过以上方案,用户在浏览器完成操作后,系统将自动拉起你的 App 并触发回调逻辑,整个流程完全静默、无感知,真正实现“一键闭环”。











