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; // 或者根据业务需求抛出异常 } }
验证步骤
- 替换修正后的Android代码,重新编译运行App
- 触发读卡流程,启动读卡器App完成操作后,系统会自动回调
onActivityResult - 此时之前保存的
pendingResult会把读卡器返回的结果传递回Flutter端
内容的提问来源于stack exchange,提问作者Benedek Körtvélyesi

