如何通过Chrome Custom Tabs获取服务器响应并传递至Android应用?
解决Chrome Custom Tabs返回响应数据到应用的问题
Chrome Custom Tabs本质并非你的应用所属Activity,默认不会主动向调用方返回数据,这就是你用registerForActivityResult只能拿到0(RESULT_CANCELED)或null的原因。要实现将响应内容传回应用并关闭Tabs,可通过以下两种常用方案解决:
方案一:自定义URL Scheme拦截跳转
这种方式让服务器响应页面跳转到你定义的专属URL Scheme,应用拦截该跳转来获取数据。
步骤1:配置Manifest接收Scheme跳转
在AndroidManifest.xml中给主Activity(或专门处理跳转的Activity)添加Intent Filter:
<activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 自定义Scheme,示例为myapp://callback --> <data android:scheme="myapp" android:host="callback" /> </intent-filter> </activity>
步骤2:服务器页面添加跳转逻辑
在服务器返回的页面中,当需要传递数据给应用时触发跳转:
function sendDataToApp() { const data = { url: "需要传递的目标链接", extraInfo: "附加信息" }; // 转义数据后拼接到Scheme链接中 const encodedData = encodeURIComponent(JSON.stringify(data)); window.location.href = `myapp://callback?data=${encodedData}`; }
步骤3:应用中处理跳转并关闭Tabs
在Activity中拦截Scheme跳转,解析数据:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) intent.data?.let { uri -> if (uri.scheme == "myapp" && uri.host == "callback") { val encodedData = uri.getQueryParameter("data") encodedData?.let { val data = JSONObject(decodeURIComponent(it)) val targetUrl = data.getString("url") // 这里拿到传递回来的数据,执行后续业务逻辑 // Custom Tabs会在跳转时自动关闭 } } } } // 启动Chrome Custom Tabs的代码 val builder = CustomTabsIntent.Builder() .setInitialActivityHeightPx(500) .setCloseButtonPosition(CustomTabsIntent.CLOSE_BUTTON_POSITION_END) val customTabsIntent = builder.build() customTabsIntent.launchUrl(this, Uri.parse("你的服务器请求地址"))
方案二:使用Chrome Custom Tabs PostMessage API(Chrome 72+支持)
这种方式通过Chrome内置的消息通道直接在页面和应用间传递数据,无需跳转。
步骤1:启用消息通道并监听消息
val builder = CustomTabsIntent.Builder() .setInitialActivityHeightPx(500) .setCloseButtonPosition(CustomTabsIntent.CLOSE_BUTTON_POSITION_END) // 创建专属消息通道 val messageChannel = CustomTabsMessageChannel("app_data_channel") builder.setMessageChannel(messageChannel) val customTabsIntent = builder.build() // 监听页面发送的消息 messageChannel.setMessageCallback(object : CustomTabsMessageChannel.MessageCallback { override fun onMessageReceived(message: String) { // 解析页面传来的JSON数据 val data = JSONObject(message) val targetUrl = data.getString("url") // 处理数据后关闭Custom Tabs customTabsIntent.intent.putExtra(CustomTabsIntent.EXTRA_CLOSE_BUTTON_ICON, R.drawable.ic_close) // 也可通过finish相关逻辑关闭,或让页面主动触发关闭 } }) // 启动Custom Tabs customTabsIntent.launchUrl(this, Uri.parse("你的服务器请求地址"))
步骤2:服务器页面发送消息
在服务器返回的页面中,通过Chrome API发送数据:
// 等待消息通道就绪 window.addEventListener('customtabsconnect', function(event) { const port = event.ports[0]; // 向应用发送数据 port.postMessage(JSON.stringify({ url: "需要传递的目标链接" })); // 可选:主动关闭Tabs window.close(); });
注意事项
- 方案一兼容性更强,几乎所有支持Custom Tabs的版本都能使用;方案二需要Chrome 72及以上版本。
- 若传递数据量较大,优先选择方案二的PostMessage,避免URL长度限制问题。
内容的提问来源于stack exchange,提问作者Meridiane
相关产品推荐
相关产品推荐

