,通过receivePort进行监听,写原生服务文件, 在app/src/main/androidmainifest引入 OverlayService文件: package com.xxx.chat
import android.content.BroadcastReceiver import android.content.Context import android.content.Intent import android.os.Handler import android.os.Looper
class OverlayReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { if (intent?.action == "com.xxxx.chat.OVERLAY_CLICK") { try { // 创建启动主 Activity 的 Intent val launchIntent = Intent(context, MainActivity::class.java).apply { // 这些标志确保应用被正确带到前台 addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP) addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
// 添加额外数据以标识来自悬浮窗
putExtra("from_overlay", true)
}
context?.startActivity(launchIntent)
// 给 Flutter 端一些时间来准备
Handler(Looper.getMainLooper()).postDelayed({
// Flutter 端会通过 IsolateNameServer 接收消息
}, 300)
} catch (e: Exception) {
e.printStackTrace()
}
}
}
} mainActivity.kt: package com.xxxx.chat
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel import android.content.Intent import androidx.annotation.NonNull import android.os.Bundle
class MainActivity : FlutterActivity(){ private val OVERLAY_CHANNEL = "com.xxxx.chat/overlay_channel"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
handleOverlayIntent(intent)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
handleOverlayIntent(intent)
}
private fun handleOverlayIntent(intent: Intent?) {
if (intent?.getBooleanExtra("from_overlay", false) == true) {
// 可选:从悬浮窗进入时做处理
}
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, OVERLAY_CHANNEL).setMethodCallHandler { call, result ->
when (call.method) {
"sendOverlayClickBroadcast" -> {
val intent = Intent("com.xxx.chat.OVERLAY_CLICK")
sendBroadcast(intent)
result.success(null)
}
"startOverlayService" -> {
val intent = Intent(this, OverlayService::class.java)
startForegroundService(intent)
result.success(null)
}
"stopOverlayService" -> {
val intent = Intent(this, OverlayService::class.java)
stopService(intent)
result.success(null)
}
"startMainActivity" -> {
try {
val launchIntent = packageManager.getLaunchIntentForPackage(packageName)
launchIntent?.apply {
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
}
if (launchIntent != null) startActivity(launchIntent)
result.success(null)
} catch (e: Exception) {
result.error("OPEN_ACTIVITY_ERROR", e.message, null)
}
}
else -> result.notImplemented()
}
}
}
}
main.dart文件主线程监听进行调用
final receivePort = ReceivePort();
IsolateNameServer.registerPortWithName( receivePort.sendPort, kOverlayClickPortName, );
receivePort.listen((message) async { try { debugPrint('收到浮窗消息: $message');
// 验证消息格式
if (message == 'clicked') {
const platform = MethodChannel('com.xxx.chat/overlay_channel');
await platform.invokeMethod('startMainActivity'); // 唤醒到前台
// 先关浮窗
await FlutterOverlayWindow.closeOverlay();
// 获取当前通话的 ID
final RtcController rtcController = Get.find<RtcController>();
final currentCallId = rtcController.onids.value.toString();
// 再做跳转
if (currentCallId != 0) {
// 再做跳转,使用实际的通话 ID
Get.toNamed(
AppRoutes.voiceCallPageprivate,
arguments: {
'id': currentCallId.toString(),
'mode': 'video',
'type': 'PRIVATE',
'jsz': false,
'fromOverlay': true, // 标记是从悬浮窗返回的
},
);
}
}
} catch (e) {
debugPrint('处理浮窗消息时出错: $e');
}
}); 悬浮窗组件的点击事件 try {
final SendPort? mainPort = IsolateNameServer.lookupPortByName(
kOverlayClickPortName,
);
if (mainPort != null) {
mainPort.send('clicked'); }这样就可以实现了