You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 03:07:37