我这边使用的是通过原生交互 进行跳转,
大概流程:发送端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"]);
}