仅通过包名打开Flutter应用传数据时Bundle为空的问题排查
问题描述
我尝试从一个Flutter应用仅通过包名打开已安装的目标Flutter应用,同时传递数据并在目标应用中接收。以下是相关代码:
发起端原生代码:
var intent = context.packageManager.getLaunchIntentForPackage(packageName) if (intent == null) { intent = Intent(Intent.ACTION_VIEW) intent.data = Uri.parse("market://details?id=$packageName") val bundle = Bundle() bundle.putString("user_id", "1111") intent.putExtra("data", bundle) intent.setType("text/plain") } intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent)
Flutter端调用代码:
class _MyHomePageState extends State<MyHomePage> { static const methodChannel = MethodChannel("samples.flutter.dev/battery"); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( children: <Widget>[ ElevatedButton( onPressed: () async { openApp(); }, child: Text("Please work this time")) ], ), ), ); } static Future<bool?> openApp() async { return await methodChannel.invokeMethod<bool>("getOpenApp"); } }
接收端MainActivity代码:
class MainActivity : FlutterActivity() { //private var sharedText: String? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val intent = intent val action = intent.action val type = intent.type if (Intent.ACTION_SEND == action && type != null) { if ("text/plain" == type) { // handleSendText(intent) // Handle text being sent } } } private val CHANNEL = "samples.flutter.dev/battery" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) .setMethodCallHandler { call: MethodCall, result: MethodChannel.Result -> if (call.method.contentEquals("getOpenApp")) { var userId = "No data received" val bundle: Bundle? = intent.getBundleExtra("data"); //val bundle = intent.getBundleExtra("data"); if (bundle!=null){ userId = bundle.getString("user_id").toString() Log.d("userid","is equals to: $userId") System.out.print("userid ki value : $userId") }else{ Log.d("empty","is equals to: empty hai ") } result.success(200) //sharedText = null } } } }
目前接收端始终获取到空Bundle,请问我哪里操作出错了?
问题分析与修复方案
1. 发起端核心逻辑错误
你仅在应用未安装、跳转到应用市场的分支里添加了数据Bundle,但实际应用已安装时,getLaunchIntentForPackage返回的原始Intent并没有附加任何数据。这是导致接收端拿不到数据的主要原因。
修正后的发起端代码:
var intent = context.packageManager.getLaunchIntentForPackage(packageName) if (intent == null) { // 应用未安装,跳转应用市场 intent = Intent(Intent.ACTION_VIEW) intent.data = Uri.parse("market://details?id=$packageName") } else { // 应用已安装,添加需要传递的数据 val bundle = Bundle() bundle.putString("user_id", "1111") intent.putExtra("data", bundle) } intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(intent)
2. 接收端Intent复用问题
如果目标应用已经在后台运行,使用FLAG_ACTIVITY_NEW_TASK启动时不会重新创建Activity,而是调用onNewIntent方法,此时Activity持有的旧Intent不会自动更新为新传递的Intent,导致拿不到新数据。
修正后的接收端代码:
class MainActivity : FlutterActivity() { private val CHANNEL = "samples.flutter.dev/battery" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 初始化时处理一次数据 processReceivedData(intent) } override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) // 更新为最新的Intent setIntent(intent) processReceivedData(intent) } private fun processReceivedData(intent: Intent?) { intent?.let { val bundle = it.getBundleExtra("data") bundle?.getString("user_id")?.let { userId -> Log.d("userid", "Received user_id: $userId") } ?: run { Log.d("empty", "No data received") } } } override fun configureFlutterEngine(flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL) .setMethodCallHandler { call, result -> if (call.method == "getOpenApp") { var userId = "No data received" val bundle = intent.getBundleExtra("data") if (bundle != null) { userId = bundle.getString("user_id").toString() Log.d("userid", "is equals to: $userId") } else { Log.d("empty", "is equals to: empty hai ") } // 建议返回实际数据给Flutter,而不是固定200 result.success(userId) } else { result.notImplemented() } } } }
3. 多余的ACTION_SEND判断
接收端onCreate中的ACTION_SEND判断完全无效,因为发起端打开应用的Intent是默认启动Intent,并非ACTION_SEND类型,可直接移除该段代码。
内容的提问来源于stack exchange,提问作者Devraj
相关产品推荐
相关产品推荐

