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

仅通过包名打开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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 18:01:15