Flutter中应用被杀死/终止时如何通过后台事件启动应用
Flutter 应用被杀死后接收Firebase后台消息自动唤醒并播放音频实现方案
1. 前置依赖配置
在pubspec.yaml中添加所需依赖:
dependencies: flutter: sdk: flutter firebase_core: ^2.24.2 # 替换为最新稳定版 firebase_messaging: ^14.7.10 # 替换为最新稳定版 flutter_local_notifications: ^16.3.2 # 替换为最新稳定版 audioplayers: ^5.2.1 # 替换为最新稳定版 android_intent_plus: ^4.0.1 # 替换为最新稳定版 permission_handler: ^11.1.0 # 替换为最新稳定版
2. 端侧原生配置
2.1 Android 端配置
修改android/app/src/main/AndroidManifest.xml,添加所需权限和Activity配置:
<!-- 基础权限 --> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <activity android:name=".MainActivity" android:launchMode="singleTop" android:showWhenLocked="true" android:turnScreenOn="true" android:exported="true"> <!-- 保留原有intent-filter配置 --> </activity>
2.2 iOS 端配置
修改ios/Runner/Info.plist添加后台权限配置:
<key>UIBackgroundModes</key> <array> <string>audio</string> <string>fetch</string> <string>remote-notification</string> </array> <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
同时在Xcode中为项目开启Background Modes、Push Notifications能力。
3. Flutter 代码实现
首先声明顶层后台消息回调,必须为顶层函数,不能是类的实例方法:
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:audioplayers/audioplayers.dart'; import 'package:android_intent_plus/android_intent.dart'; import 'package:permission_handler/permission_handler.dart'; import 'dart:io'; // 必须添加该注解,避免Release打包时代码被混淆导致回调失效 @pragma('vm:entry-point') Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(); // 播放音频,本地资源用AssetSource,网络音频用UrlSource final audioPlayer = AudioPlayer(); await audioPlayer.play(AssetSource('your_alarm_audio.mp3')); // Android端唤起应用到前台 if (Platform.isAndroid) { AndroidIntent intent = AndroidIntent( action: 'android.intent.action.MAIN', category: 'android.intent.category.LAUNCHER', componentName: 'com.your.package.name.MainActivity', // 替换为你的应用包名+MainActivity路径 flags: [Flag.FLAG_ACTIVITY_NEW_TASK, Flag.FLAG_ACTIVITY_CLEAR_TOP], ); await intent.launch(); } // iOS端配置好后台模式后,收到通知会自动触发唤醒,无需额外唤起逻辑 }
主函数初始化相关服务:
void main() async { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp(); // 注册后台消息回调 FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); // 初始化本地通知服务 final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); const AndroidInitializationSettings initAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initSettings = InitializationSettings(android: initAndroid); await flutterLocalNotificationsPlugin.initialize(initSettings); runApp(const MyApp()); }
在应用首页初始化时申请必要权限:
@override void initState() { super.initState(); _requestPermissions(); } Future<void> _requestPermissions() async { if (Platform.isAndroid) { // 申请悬浮窗权限,Android 10+后台唤醒界面必须 if (await Permission.systemAlertWindow.isDenied) { await Permission.systemAlertWindow.request(); } await Permission.notification.request(); } if (Platform.isIOS) { await FirebaseMessaging.instance.requestPermission( alert: true, badge: true, sound: true, ); } // 获取FCM推送Token用于测试 String? fcmToken = await FirebaseMessaging.instance.getToken(); debugPrint('FCM Token: $fcmToken'); }
4. 注意事项
- 国内安卓定制系统(小米、华为、OPPO、vivo等)有额外的后台权限限制,需要引导用户手动开启「自启动」「后台弹出界面」「允许后台活动」等权限,否则应用被杀死后无法正常唤起
- iOS端如果是用户手动上滑杀死应用,普通FCM通知无法触发回调,仅静默通知可有限触发,且受苹果系统后台刷新策略限制,无法保证100%触发
- 音频资源需要提前打包到应用assets目录,或提前下载到本地存储,避免后台环境下无法联网加载音频
内容的提问来源于stack exchange,提问作者Nikunj Pithadiya
相关产品推荐
相关产品推荐

