Flutter:FirebaseMessaging通知到达时自动打开App(无需用户操作)
解决通讯App来电通知自动打开指定页面的问题
核心问题分析
external_app_launcher无法在后台消息回调中生效,因为后台运行环境限制了插件的启动能力。实际上你代码里用到的AndroidfullScreenIntent就是专门处理来电这类需自动唤起App的场景,只需完善配置就能实现无需用户点击、直接打开通话页面的效果。
解决方案步骤
1. 完善Android端通知的FullScreenIntent配置
你当前代码已设置fullScreenIntent: true,但需要给这个Intent指定跳转的目标通话页面,而非默认启动页。修改通知展示代码,添加自定义PendingIntent:
// 创建指向通话页Activity的Intent(替换成你实际的Activity路径) final intent = Intent() ..setClassName("com.example.chat_app", "com.example.chat_app.CallActivity") ..putExtra("call_data", json.encode(message.data)); // 传递通话相关数据 // 生成PendingIntent,确保能唤起指定页面 final pendingIntent = PendingIntent.getActivity( context, Random().nextInt(1000000), intent, PendingIntentFlags.updateCurrent | PendingIntentFlags.immutable, ); // 更新通知配置,关联fullScreenIntent的PendingIntent flutterLocalNotificationsPlugin.show( Random().nextInt(1000000000), message.data['title'], message.data["body"], NotificationDetails( android: AndroidNotificationDetails( channel.id, channel.name, channelDescription: channel.description, importance: Importance.max, priority: Priority.high, playSound: true, sound: const RawResourceAndroidNotificationSound("ringtone1"), fullScreenIntent: true, fullScreenIntentPendingIntent: pendingIntent, // 新增该行配置 ), ), payload: json.encode(message.data));
2. 配置AndroidManifest.xml
确保通话页Activity能被外部Intent唤起,且支持锁屏状态下启动:
<activity android:name=".CallActivity" android:launchMode="singleTop" android:showOnLockScreen="true" android:turnScreenOn="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
showOnLockScreen+turnScreenOn:实现锁屏状态下自动点亮屏幕并展示通话页singleTop:避免重复创建Activity实例
3. Flutter端处理全场景页面跳转
覆盖App前台、后台、被杀死三种状态的跳转逻辑:
- 前台/后台状态:在
onSelectNotification或firebaseMessaging.onMessageOpenedApp中直接调用goToNextScreen跳转 - 被杀死状态:通过MethodChannel从Android原生层传递数据给Flutter,触发跳转:
// MainActivity.kt override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) intent?.extras?.let { extras -> val callData = extras.getString("call_data") callData?.let { val channel = MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, "call_channel") channel.invokeMethod("openCallPage", it) } } } override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) intent?.extras?.let { extras -> val callData = extras.getString("call_data") callData?.let { val channel = MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, "call_channel") channel.invokeMethod("openCallPage", it) } } }
Flutter侧监听MethodChannel:
final MethodChannel _callChannel = MethodChannel('call_channel'); @override void initState() { super.initState(); _callChannel.setMethodCallHandler((call) async { if (call.method == 'openCallPage') { String data = call.arguments as String; Map<String, dynamic> callData = json.decode(data); goToNextScreen(callData, true); } }); }
4. iOS端适配
在AppDelegate中处理通知唤起逻辑:
// AppDelegate.swift func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo if let callData = userInfo["call_data"] as? String { let channel = FlutterMethodChannel(name: "call_channel", binaryMessenger: window?.rootViewController as! FlutterBinaryMessenger) channel.invokeMethod("openCallPage", arguments: callData) } completionHandler() } func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.sound, .alert]) }
关键注意事项
- 确保Firebase后台发送的是数据消息,而非纯通知消息,这样后台消息回调才能稳定触发
- Android 12及以上需添加权限:
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
内容的提问来源于stack exchange,提问作者Mohamed Ayman
相关产品推荐
相关产品推荐

