在 Android 开发中,有一种场景几乎每个开发者都会遇到:App 需要跳转到外部浏览器让用户完成 OAuth 登录、支付授权或第三方认证,等用户在网页上点完“确认”后,再自动返回 App 并把结果带回来。听起来很基础是吧?但如果你只是用 Intent.ACTION_VIEW 打开一个网页,系统可
在 Android 开发中,有一种场景几乎每个开发者都会遇到:App 需要跳转到外部浏览器让用户完成 OAuth 登录、支付授权或第三方认证,等用户在网页上点完“确认”后,再自动返回 App 并把结果带回来。听起来很基础是吧?但如果你只是用 Intent.ACTION_VIEW 打开一个网页,系统可不会“自觉”地唤醒你的 App——用户得自己手动切回来,流程就这么断了,体验瞬间割裂。
其实解决方案早就摆在那儿了——利用 Android 的 Intent 深度链接(Deep Link)机制,配合自定义 Scheme(也就是不用 http:// 或 https://,而是类似 myapp:// 这样的协议),让浏览器在回调时触发系统拉起你的 App,同时把数据带回来。这套方案不需要 WebSocket、后台服务或者通知栏提醒,轻量、标准,而且兼容性很好(Android 4.1 以上都支持)。
长期稳定更新的攒劲资源: >>>点此立即查看<<<

首先,在 AndroidManifest.xml 里为要接收回调的 Activity 添加一个 。这里有个很容易踩的坑:千万不要加上 android:host 或 android:path 这类冗余属性,否则浏览器很可能认不出你的回调地址,匹配失败就白费功夫了。
几个关键提醒:
- scheme 必须全小写,而且别跟
http、https、file这类通用协议撞车;- 不要画蛇添足加
android:host(比如127.0.0.1),加了你反而会限制匹配范围,浏览器回调时往往不带 host,结果就匹配不上了;- 这个 Activity 的
launchMode推荐用singleTask或singleTop,这样才能复用已有实例,并且正确收到onNewIntent()回调。
启动浏览器之前,需要构造一个携带 referrer 的 Intent。为什么?有些 Web SDK(比如 OAuth 2.0 的授权服务器)会读取 Referer 或 redirect_uri,所以前后端得保持一致。当然,更关键的是要让网页知道“完成后该跳到哪里”。
String callbackUrl = "myapp://callback";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(exe)); // exe 是目标网页 URL
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setPackage("com.android.chrome"); // 可选:指定 Chrome(需用户已安装)
intent.putExtra(Intent.EXTRA_REFERRER, Uri.parse(callbackUrl)); // 关键:声明 referrer
try {
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
// Chrome 未安装时降级使用系统浏览器
intent.setPackage(null);
context.startActivity(intent);
}
补充说明:
Intent.EXTRA_REFERRER并不是强制生效的。真正决定能不能唤起的,是网页端自己发起的window.location.href = "myapp://callbackcode=abc"或者一个链接。所以,一定要和前端同学沟通清楚:服务端或 JS 代码里的重定向 URL 必须用你声明的myapp://协议,否则一切都是白搭。
当浏览器跳转到 myapp://callbackparam=value 时,系统会尝试拉起你的 Activity。如果 App 已经在后台,就会调用 onNewIntent();如果没启动,则走 onCreate()。所以两个入口都得覆盖,一个都不能少。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handleIntent(getIntent()); // 处理首次启动
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent); // 必须更新 intent,否则 getIntent() 仍返回旧值
handleIntent(intent);
}
private void handleIntent(Intent intent) {
Uri data = intent.getData();
if (data != null && "myapp".equals(data.getScheme())) {
String code = data.getQueryParameter("code");
String state = data.getQueryParameter("state");
// 解析回调参数,执行登录/支付验证等逻辑
processCallback(code, state);
}
}
state 参数,存到本地(比如 SharedPreferences),回调时比对一下,防止 CSRF 攻击;onNewIntent() 不会跨进程触发,这种情况下可以考虑改用 BroadcastReceiver 或 LocalBroadcastManager 中转信号;AndroidManifest.xml 里显式声明 :走完这三步——声明 Scheme、携带回调跳转、捕获并解析 Intent——就能彻底砍掉用户手动切回 App 的步骤,实现真正的“后台自动唤起 + 数据回传”。体验流畅了,流程闭环率自然也就上去了。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述