You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 22:08:36