Flutter中创建不可停止通知咨询(FCM、Flutter Local Notification)
Flutter 实现不可停止的持续通知方案
以下是针对需求的具体实现步骤,涵盖通知持久化、防覆盖、持续响铃及应用启动停止逻辑:
一、核心依赖与权限配置
首先引入必要的Flutter插件,并配置平台权限:
- 依赖
flutter_local_notifications(处理通知)和audio_service(后台持续播放铃声) - Android 配置:
在AndroidManifest.xml中添加权限:<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> - iOS 配置:
在Info.plist中添加:<key>NSCriticalAlertUsageDescription</key> <string>紧急事项需要持续响铃提醒用户</string> <key>UIBackgroundModes</key> <array> <string>audio</string> <string>remote-notification</string> </array>
二、创建不可手动清除的高优先级通知
通过前台服务(Android)和关键通知(iOS)实现通知不可被用户手动清除,且优先级最高避免被覆盖:
final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin(); // 初始化通知插件 Future<void> initNotifications() async { const AndroidInitializationSettings androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const DarwinInitializationSettings iosInit = DarwinInitializationSettings( requestAlertPermission: true, requestSoundPermission: true, criticalAlertPermission: true, ); const InitializationSettings initSettings = InitializationSettings(android: androidInit, iOS: iosInit); await _notificationsPlugin.initialize(initSettings); } // 显示持久化通知 Future<void> showPersistentAlert() async { // Android 高优先级通道配置 const AndroidNotificationChannel channel = AndroidNotificationChannel( 'alert_channel', '紧急通知通道', description: '用于紧急事项的高优先级通知', importance: Importance.max, priority: Priority.high, sound: RawResourceAndroidNotificationSound('alert_loop'), enableVibration: true, ); await _notificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel(channel); // 通知详情配置 const AndroidNotificationDetails androidDetails = AndroidNotificationDetails( 'alert_channel', '紧急通知', channelDescription: '不可手动清除的紧急通知', importance: Importance.max, priority: Priority.high, ongoing: true, // 用户无法手动清除 autoCancel: false, foregroundServiceCompat: true, // 标记为前台服务通知 ); const DarwinNotificationDetails iosDetails = DarwinNotificationDetails( sound: 'alert_loop.wav', critical: true, // 忽略静音模式持续响铃 interruptionLevel: InterruptionLevel.critical, // 最高打断级别,防覆盖 ); const NotificationDetails details = NotificationDetails(android: androidDetails, iOS: iosDetails); // 显示通知并启动前台服务(Android) await _notificationsPlugin.show(1, '紧急提醒', '请立即打开应用处理', details); await _notificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.startForegroundService(1, details); }
三、实现持续响铃直到应用打开
结合 audio_service 实现后台循环播放铃声,直到用户打开应用:
// 初始化音频服务 Future<void> initAudioService() async { await AudioService.start( backgroundTaskEntrypoint: _audioBackgroundTask, androidNotificationChannelName: '提醒铃声', androidNotificationIcon: '@mipmap/ic_launcher', ); } // 后台音频任务 void _audioBackgroundTask() { AudioServiceBackground.run(() async { final player = AudioPlayer(); await player.setAsset('assets/sounds/alert_loop.wav'); player.setLoopMode(LoopMode.one); // 循环播放 await player.play(); // 监听任务移除(应用打开时停止) await for (final _ in AudioServiceBackground.onTaskRemoved) { await player.stop(); await AudioService.stop(); } return await Forever(); // 保持服务运行 }); }
四、应用启动时停止通知与铃声
在应用首页的初始化逻辑中,触发停止操作:
@override void initState() { super.initState(); _stopAlert(); } Future<void> _stopAlert() async { // 取消通知 await _notificationsPlugin.cancel(1); // 停止Android前台服务 await _notificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.stopForegroundService(); // 停止音频播放 await AudioService.stop(); }
关键注意事项
- Android 13+ 需要动态申请
POST_NOTIFICATIONS权限,可使用permission_handler插件实现。 - iOS 的关键通知(critical alert)需用户授权,且部分地区可能有系统限制。
- 持续响铃属于强干扰操作,仅建议用于真正的紧急场景,避免影响用户体验。
内容的提问来源于stack exchange,提问作者Brean
相关产品推荐
相关产品推荐

