Flutter应用终止/锁屏时FCM触发全屏通知页面的实现
解决Flutter应用终止/锁屏时FCM全屏页面跳转问题
核心思路
应用终止或锁屏状态下,FCM消息会由Android系统的FirebaseMessagingService处理,需通过自定义服务解析isfullscreen字段,结合flutter_local_notifications的全屏Intent配置,配合路由跳转实现需求。
1. 自定义Android端FCM消息处理服务
创建MyFirebaseMessagingService继承FirebaseMessagingService,在onMessageReceived中解析payload字段并分发处理逻辑:
package com.your.package.name import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin import com.dexterous.flutterlocalnotifications.AndroidNotificationDetails import android.app.PendingIntent import android.content.Intent import android.content.pm.PackageManager class MyFirebaseMessagingService : FirebaseMessagingService() { override fun onMessageReceived(remoteMessage: RemoteMessage) { super.onMessageReceived(remoteMessage) // 解析payload中的isfullscreen字段 val isFullScreen = remoteMessage.data["isfullscreen"]?.toBoolean() ?: false if (isFullScreen) { showFullScreenNotification(remoteMessage) } else { showNormalNotification(remoteMessage) } } private fun showFullScreenNotification(remoteMessage: RemoteMessage) { val notificationPlugin = FlutterLocalNotificationsPlugin() val title = remoteMessage.data["title"] ?: "全屏通知" val body = remoteMessage.data["body"] ?: "紧急通知内容" // 配置全屏通知参数 val androidDetails = AndroidNotificationDetails( "fullscreen_notif_channel", "全屏通知频道", channelDescription = "用于触发全屏页面的通知频道", priority = AndroidNotificationDetails.Priority.HIGH, importance = AndroidNotificationDetails.Importance.HIGH, fullScreenIntent = true, enableLights = true, enableVibration = true ) // 创建跳转至Flutter页面的PendingIntent val launchIntent = packageManager.getLaunchIntentForPackage(packageName)?.apply { // 添加路由参数,用于Flutter端跳转指定页面 putExtra("route", "/full-screen-notification") flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } val pendingIntent = PendingIntent.getActivity( this, 0, launchIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE ) androidDetails.setContentIntent(pendingIntent) // 展示全屏通知 notificationPlugin.show( System.currentTimeMillis().toInt(), title, body, com.dexterous.flutterlocalnotifications.NotificationDetails(androidDetails, null) ) } private fun showNormalNotification(remoteMessage: RemoteMessage) { // 普通通知的常规实现,使用flutter_local_notifications默认逻辑即可 val notificationPlugin = FlutterLocalNotificationsPlugin() val androidDetails = AndroidNotificationDetails( "normal_notif_channel", "普通通知频道", priority = AndroidNotificationDetails.Priority.DEFAULT, importance = AndroidNotificationDetails.Importance.DEFAULT ) notificationPlugin.show( System.currentTimeMillis().toInt(), remoteMessage.data["title"], remoteMessage.data["body"], com.dexterous.flutterlocalnotifications.NotificationDetails(androidDetails, null) ) } }
在AndroidManifest.xml中注册该服务:
<service android:name=".MyFirebaseMessagingService" android:exported="false"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service>
2. Flutter端路由跳转配置
在MaterialApp的onGenerateRoute中监听路由参数,跳转至FullScreenNotificationPage:
import 'package:flutter/material.dart'; import 'full_screen_notification_page.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'FCM Demo', onGenerateRoute: (settings) { // 处理从Android端传递的路由参数 if (settings.name == '/full-screen-notification') { return MaterialPageRoute( builder: (context) => const FullScreenNotificationPage(), ); } return MaterialPageRoute(builder: (context) => const HomePage()); }, home: const HomePage(), ); } }
3. 权限配置与申请
AndroidManifest.xml添加权限
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
Flutter端动态申请权限
使用permission_handler插件申请必要权限:
import 'package:permission_handler/permission_handler.dart'; Future<void> requestNotificationPermissions() async { // 申请通知权限 if (await Permission.notification.isDenied) { await Permission.notification.request(); } // Android 12+ 需申请全屏Intent权限 if (await Permission.fullScreenIntent.isDenied) { await Permission.fullScreenIntent.request(); } } // 在应用初始化时调用 @override void initState() { super.initState(); requestNotificationPermissions(); }
4. 关键注意事项
- FCM消息类型:必须发送数据消息(或通知+数据混合消息),纯通知消息在应用终止时会由系统直接展示,无法触发自定义服务逻辑。示例payload:
{ "data": { "isfullscreen": "true", "title": "紧急全屏通知", "body": "请查看详细内容" }, "to": "设备FCM Token" } - 通知频道优先级:全屏通知对应的频道必须设置为
HIGH或MAX级别,确保锁屏状态下能正常触发全屏Intent。 - Android版本兼容:Android 12及以上需动态申请
USE_FULL_SCREEN_INTENT权限,否则全屏Intent无法生效。
内容的提问来源于stack exchange,提问作者hluuy
相关产品推荐
相关产品推荐

