Flutter中APP被杀死时监听FCM通知并弹窗的实现方法
解决方案
1. 基础配置确认
确保已完成FCM后台消息的基础配置,并且Android端已申请SYSTEM_ALERT_WINDOW权限,Manifest中声明了允许后台唤醒的相关配置,保障应用被杀死后能被FCM消息唤醒处理。
2. 利用FCM后台消息回调处理杀死状态逻辑
APP被完全杀死时,只有FCM的后台消息回调(FirebaseMessaging.onBackgroundMessage)会被系统唤醒执行;前台/后台运行时则走FirebaseMessaging.onMessage回调。我们只需要在后台回调中判断APP状态,再触发弹窗:
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(); // 判断APP是否处于杀死状态 bool isAppKilled = await _checkAppKilledStatus(); if (isAppKilled) { // 调用system_alert_window显示弹窗 await SystemAlertWindow.showSystemWindow( height: 220, width: 320, title: "来电提醒", content: message.notification?.body ?? "未知来电", // 其他弹窗样式、交互配置... ); } }
3. 实现APP杀死状态判断
推荐两种可靠的判断方式:
- 方式一:借助第三方包检测运行状态
使用package:device_apps包直接检测应用是否在运行(含后台进程),返回false则说明APP已被杀死:
Future<bool> _checkAppKilledStatus() async { bool isRunning = await DeviceApps.isAppRunning("com.your.app.package"); return !isRunning; }
- 方式二:通过生命周期标记状态
在APP主进程中监听生命周期,用SharedPreferences记录运行状态:
// 主APP中监听生命周期 class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> with WidgetsBindingObserver { @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); // 启动时标记为运行中 _updateAppStatus(true); } @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.detached) { // APP被杀死时标记为停止 _updateAppStatus(false); } else if (state == AppLifecycleState.resumed) { _updateAppStatus(true); } } Future<void> _updateAppStatus(bool isRunning) async { SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.setBool("app_is_running", isRunning); } } // 后台回调中读取状态 Future<bool> _checkAppKilledStatus() async { SharedPreferences prefs = await SharedPreferences.getInstance(); bool? isRunning = prefs.getBool("app_is_running"); return isRunning == false || isRunning == null; }
4. 规避前台/后台触发弹窗
在FirebaseMessaging.onMessage(前台消息回调)中不执行弹窗逻辑;后台运行时(APP未被杀死但处于后台),通过状态判断跳过弹窗,仅在APP杀死状态下触发。
关键注意事项
- Android 10及以上需额外申请
USE_FULL_SCREEN_INTENT权限,确保后台弹窗能正常显示。 - 测试时需完全杀死APP(划掉进程),再发送FCM消息验证效果。
- FCM后台回调运行在隔离区,无法直接访问主APP内存状态,必须依赖外部存储或第三方包判断状态。
内容的提问来源于stack exchange,提问作者Shebin PR
相关产品推荐
相关产品推荐

