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

Flutter Wear OS:如何正确等待Activity返回结果至Platform Channel

问题描述

在Wear OS端对接Flutter Platform Channel时,需要实现唤起原生输入Activity获取用户输入文本,再将结果回传给Flutter端的功能。当前实现存在问题:调用startActivityForResult后不会等待Activity返回结果就直接执行后续逻辑,Flutter端会立即收到null返回值。

当前错误实现代码:

override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    MethodChannel(
        flutterEngine.dartExecutor.binaryMessenger,
        channel
    ).setMethodCallHandler { call, result ->
        myResult = result
        getInputText()
    }
}

private fun getInputText() {
    val inputText: String

    val remoteInputs: List<RemoteInput> = listOf(RemoteInput.Builder("quick_reply").setLabel("Quick reply").build())
    val intent: Intent = createActionRemoteInputIntent()
    putRemoteInputsExtra(intent, remoteInputs)
    startActivityForResult(intent, 0)
    inputText = RemoteInput.getResultsFromIntent(intent).toString()

    myResult?.success(inputText)
}
问题根因

两个核心错误导致拿不到正确结果:

  1. startActivityForResult是异步非阻塞方法,唤起输入Activity后当前函数会立刻向下执行,不会阻塞等待用户完成输入操作,代码中在启动Activity后立刻调用myResult?.success(),此时用户还没完成输入,自然拿不到有效值
  2. 代码尝试从自己创建的、用于启动Activity的intent对象中解析RemoteInput结果,但用户输入的内容是存在于Activity结束后系统回传的Intent中,原启动Intent不可能携带输入结果。
正确实现代码

首先定义必要的成员变量,避免魔法值和重复调用问题:

// 替换成你自己的Channel名称
private const val CHANNEL_NAME = "your_wear_input_channel"
// 定义输入请求的请求码
private const val REQUEST_CODE_REMOTE_INPUT = 1001
// 暂存Flutter端的方法回调,结果回传后置空
private var pendingMethodResult: MethodChannel.Result? = null

在configureFlutterEngine中注册方法回调,只负责暂存Result对象、唤起输入页:

override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_NAME)
        .setMethodCallHandler { call, result ->
            when (call.method) {
                "getInputText" -> {
                    // 防止重复发起请求
                    if (pendingMethodResult != null) {
                        result.error("REQUEST_BUSY", "当前已有输入请求进行中", null)
                        return@setMethodCallHandler
                    }
                    pendingMethodResult = result
                    launchRemoteInputActivity()
                }
                else -> result.notImplemented()
            }
        }
}

将原getInputText方法拆分为只负责启动输入页的逻辑,不要在这里处理结果:

private fun launchRemoteInputActivity() {
    val remoteInputs = listOf(
        RemoteInput.Builder("quick_reply")
            .setLabel("Quick reply")
            .build()
    )
    val intent = createActionRemoteInputIntent()
    putRemoteInputsExtra(intent, remoteInputs)
    startActivityForResult(intent, REQUEST_CODE_REMOTE_INPUT)
}

重写onActivityResult生命周期方法,在回调中解析输入结果、回传给Flutter:

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode != REQUEST_CODE_REMOTE_INPUT) return

    // 取出暂存的回调后立刻置空,避免重复调用
    val result = pendingMethodResult
    pendingMethodResult = null
    if (result == null) return

    when (resultCode) {
        RESULT_OK -> {
            val inputResult = RemoteInput.getResultsFromIntent(data)
            val inputText = inputResult?.getCharSequence("quick_reply")?.toString() ?: ""
            result.success(inputText)
        }
        // 用户取消输入的场景,可根据业务需求返回空字符串或者错误
        else -> result.success("")
    }
}

注意事项

  • 如果你已经适配AndroidX,可以使用官方推荐的Activity Result API替代已废弃的startActivityForResult,核心逻辑不变:在Activity返回结果的回调中,再调用Platform Channel的Result对象回传值
  • 禁止对同一个MethodChannel.Result对象多次调用success/error/notImplemented,否则会抛出运行时异常
  • 解析RemoteInput时必须使用onActivityResult返回的data参数,不要使用启动时自行构建的Intent对象

内容的提问来源于stack exchange,提问作者SuxoiKorm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:09:36