Flutter APP跳转Flutter APP 携带参数

我这边使用的是通过原生交互 进行跳转,

大概流程:发送端Flutter ->发送端原生->接收端原生->接收端Flutter

1.发送端Flutter

Dart 复制代码
 //建立发送端Flutter和发送端原生通道
  static const platform = MethodChannel('com.example.jhej_app/send_app_channel');
  Future<void> _launchAppWithParams() async {
    try {
      final Map<String, dynamic> result = await platform.invokeMethod(
        'jumpToJHEJApp',//通道方法名称
        {
          'targetPackage': 'com.example.jh_app', // 跳转的应用包名
          'targetActivity': 'com.example.jh_app.MainActivity',// 跳转的应用在跳转到对应的Activity名称
          'data': {//携带的参数
            'name': "66666",
            'timestamp': DateTime.now().millisecondsSinceEpoch.toString(),
            'source': '江湖二级'
          }
        },
      );
      print('跳转结果: $result');
    } on PlatformException catch (e) {
       showToast('${e.message}');
    }
  }

2.发送端原生 接收到发送端Flutter的数据

Dart 复制代码
class MainActivity : FlutterFragmentActivity() {
    private val SENDCHANNEL = "com.example.jhej_app/send_app_channel"//江湖二级发送到江湖APP的数值
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, SENDCHANNEL).setMethodCallHandler { call, result ->
            if(call.method == "jumpToJHEJApp"){//刚才设置的通道方法
                val targetPackage = call.argument<String>("targetPackage")//跳转的包名
                val targetActivity = call.argument<String>("targetActivity")//跳转的包名应用对应的页面
                val data = call.argument<Map<String, Any>>("data")//跳转携带的数据

                 try {
                    //判断是否安装了对应的APP
                    if(AppInstallChecker().isAppInstalled(this.applicationContext, targetPackage!!)){
                        val intent = Intent().apply {//设置跳转参数
                            setClassName(targetPackage!!, targetActivity!!)
                            data?.forEach { (key, value) ->
                                when (value) {
                                    is String -> putExtra(key, value)
                                    is Int -> putExtra(key, value)
                                    is Long -> putExtra(key, value)
                                    is Boolean -> putExtra(key, value)
                                }
                            }
                            // 添加标志确保在新任务中启动
                            addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                        }

                        startActivity(intent)//进行跳转
                        result.success("跳转成功")
                    }else{
                        result.error("APP_NOT_INSTALLED", "请先安装APP", null)
                    }
                } catch (e: Exception) {
                    result.error("JUMP_ERROR", "跳转失败: ${e.message}", null)
                }
            }else{
                result.notImplemented()
            }
        }
    }
}

2.2判断app是否安装

Dart 复制代码
class AppInstallChecker {
    /**
     * 通过包名检测应用是否安装
     * @param context 上下文
     * @param packageName 目标应用包名
     * @return true表示已安装,false表示未安装
     */
    fun isAppInstalled(context: Context, packageName: String): Boolean {
        return try {
            val info = context.packageManager.getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES)
            true
        } catch (e: PackageManager.NameNotFoundException) {
            false
        }
    }

    /**
     * 通过Intent检测应用是否安装(支持隐式意图)
     * @param context 上下文
     * @param intent 目标Intent
     * @return true表示可处理该Intent的应用存在,false表示不存在
     */
    fun isIntentAvailable(context: Context, intent: android.content.Intent): Boolean {
        return context.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY).size > 0
    }
}

3.接收端原生

Dart 复制代码
class MainActivity : FlutterActivity(){
    private val ACCEPTCHANNEL = "com.example.jh_app/accept_app_channel"//创建和接收端Flutter通道
    private lateinit var methodChannel: MethodChannel
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        methodChannel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, ACCEPTCHANNEL)
        methodChannel.setMethodCallHandler { call, result ->
            when (call.method) {//自定义设置每次跳转都监听方法
                "setupIntentListener" -> {
                    // 设置监听成功
                    result.success("监听设置成功")
                }
                else -> result.notImplemented()
            }
        }
        // 立即处理当前Intent数据
        processCurrentIntent()
    }
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        processCurrentIntent()
    }
    private fun processCurrentIntent() {
        try {
            val currentIntent = intent
            val extras = currentIntent?.extras

            if (extras != null && !extras.isEmpty) {
                // 构建要传递给Flutter的数据
                val dataJson = JSONObject()
                dataJson.put("name", extras.getString("name", ""))
                dataJson.put("timestamp", extras.getString("timestamp", ""))
                dataJson.put("source", extras.getString("source", ""))

                // 将数据作为参数传递给Flutter
                methodChannel.invokeMethod("getNewReceivedData", dataJson.toString())//传递数据到接收端Flutter
            }

        } catch (e: Exception) {
            e.printStackTrace()
            methodChannel.invokeMethod("getNewReceivedData", e.toString())
        }
    }
}

4.接收端Flutter

Dart 复制代码
  @override
  void initState() {
    super.initState();
    _setupIntentListener();

  }

  static const platform = MethodChannel('com.example.jh_app/accept_app_channel');//这里和接收原生端保持一致
  Map<dynamic, dynamic> _receivedData = {};
  Future<void> _setupIntentListener() async {
    try {
      // 设置原生端监听
      await platform.invokeMethod('setupIntentListener');
      // 监听来自原生端的数据更新通知
      platform.setMethodCallHandler((call) async {
        if (call.method == "getNewReceivedData") {//和接收原生端保持一致
          showToast("66666");
          setState(() {
            _receivedData = jsonDecode(call.arguments.toString());
          });
          if (_receivedData.isNotEmpty) {
            _showReceivedDataDialog();
          }
        }
        return null;
      });
    } on PlatformException catch (e) {
      print("设置监听失败: ${e.message}");
    }
  }
  void _showReceivedDataDialog() {
    _receivedData.clear();
    if(_receivedData["name"]==null){
      showToast("数据为空");
      return;
    }
    showToast(_receivedData["name"]);
  }
相关推荐
脾气有点小暴2 小时前
前端页面跳转的核心区别与实战指南
开发语言·前端·javascript
帅气马战的账号12 小时前
开源鸿蒙Flutter轻量化组件手册:8类高频工具模块,极速适配多终端
flutter
lxh01132 小时前
最长递增子序列
前端·数据结构·算法
Youyzq3 小时前
前端项目发布到cdn上css被编译失效问题rgba失效和rgb失效
前端·css·算法·cdn
Fantastic_sj3 小时前
Vue3相比Vue2的改进之处
前端·javascript·vue.js
vipbic3 小时前
解决npm publish的404/403和配置警告全记录
前端·npm·node.js
Bigger4 小时前
🚀 “踩坑日记”:shadcn + Vite 在 Monorepo 中配置报错
前端·react.js·vite
冬男zdn5 小时前
优雅处理数组的几个实用方法
前端·javascript
克喵的水银蛇5 小时前
Flutter 通用标签选择组件:TagSelector 支持单选 / 多选
javascript·windows·flutter