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

Flutter调用Android Intent startActivityForResult无返回结果问题排查求助

问题排查与解决方案

咱们先拆解下你的Android代码里的几个核心错误,这就是导致拿不到返回结果的根源:

1. 错误手动调用onActivityResult

你在调用startActivityForResult(intent, REQ_CODE)之后立刻手动调用了onActivityResult(REQ_CODE,RES_CODE, intent);——这完全违背了Android的生命周期逻辑!onActivityResult是系统在被启动的Activity结束后自动回调的方法,你手动调用它的时候,读卡器App还没完成读卡操作,自然拿不到真实结果,而且你传入的RES_CODE是硬编码的-1,根本不是实际的返回状态码。

2. onActivityResult方法定义位置错误

你把onActivityResult放在了setMethodCallHandler的lambda内部,这会导致这个方法根本不会被Android系统识别和触发。正确的做法是把它作为MainActivity的成员方法,和configureFlutterEngine同级。

3. 未保存MethodChannel的Result对象

startActivityForResult是异步操作,当系统回调onActivityResult时,原来MethodCallHandler里的result对象已经超出作用域了。必须把它作为MainActivity的成员变量保存下来,等待回调时使用。

4. 请求码REQ_CODE的作用域问题

你在MethodCallHandler里定义的REQ_CODE是局部变量,在onActivityResult里无法访问,应该把它提升为MainActivity的成员常量。


修正后的完整代码

Android端MainActivity.kt

import android.app.Activity
import android.content.ComponentName
import android.content.Intent
import android.util.Log
import androidx.annotation.NonNull
import org.json.JSONObject
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private val CHANNEL = "reader"
    private val REQ_CODE_READER = 1 // 成员常量,全局可访问
    private var pendingResult: MethodChannel.Result? = null // 保存等待回调的Result对象

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            if (call.method == "StartReading") {
                pendingResult = result // 保存Result,等待异步回调
                try {
                    val json = JSONObject().apply {
                        put("Amount", call.argument<Double>("Amount"))
                        put("Operation", call.argument<String>("Operation"))
                        put("TransactionID", call.argument<String>("TransactionID"))
                    }
                    val intent = Intent().apply {
                        component = ComponentName("co.reader.posterminal", "co.reader.posterminal.MainActivity")
                        putExtra("POS_EMULATOR_EXTRA", json.toString())
                    }
                    startActivityForResult(intent, REQ_CODE_READER)
                } catch (e: Exception) {
                    pendingResult?.error("ERROR", "Failed to prepare intent: ${e.message}", null)
                    pendingResult = null // 清空,避免内存泄漏
                }
            } else {
                result.notImplemented()
            }
        }
    }

    // 正确的onActivityResult位置:作为MainActivity的成员方法
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQ_CODE_READER) {
            pendingResult?.let { result ->
                when (resultCode) {
                    Activity.RESULT_OK -> {
                        try {
                            val resultStr = data?.getStringExtra("POS_EMULATOR_RESULT")
                            if (resultStr != null) {
                                // 这里可以根据需要解析JSONObject后返回,或者直接返回字符串
                                result.success(resultStr)
                            } else {
                                result.error("EMPTY_RESULT", "No result data received", null)
                            }
                        } catch (e: Exception) {
                            result.error("PARSE_ERROR", "Failed to parse result: ${e.message}", null)
                            Log.e("ReaderError", e.toString())
                        }
                    }
                    Activity.RESULT_CANCELED -> {
                        result.error("CANCELED", "User canceled the operation", null)
                    }
                    else -> {
                        result.error("UNKNOWN_ERROR", "Unknown result code: $resultCode", null)
                    }
                }
                pendingResult = null // 处理完成后清空,避免内存泄漏
            }
        }
    }
}

Flutter端代码小优化(类型匹配修正)

你的Flutter方法定义返回List<String>?,但实际调用返回的是String?,可以修正类型匹配让代码更严谨:

Future<String?> startActivityForResult(double amount, String operation) async {
  const platform = MethodChannel('reader');
  try {
    return await platform.invokeMethod('StartReading', { 
      "Amount": amount, 
      "Operation": operation, 
      "TransactionID": Uuid().v1() 
    });
  } on PlatformException catch (e) {
    print('Error: ${e.message}');
    return null; // 或者根据业务需求抛出异常
  }
}

验证步骤

  1. 替换修正后的Android代码,重新编译运行App
  2. 触发读卡流程,启动读卡器App完成操作后,系统会自动回调onActivityResult
  3. 此时之前保存的pendingResult会把读卡器返回的结果传递回Flutter端

内容的提问来源于stack exchange,提问作者Benedek Körtvélyesi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 15:58:12