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

Flutter中如何通过滑动通知停止通知触发的闹钟播放音效

你当前的实现只完成了「收到Firebase推送触发闹钟播放」的逻辑,存在两个核心问题导致滑动通知无法停止闹钟:

  1. 没有监听系统通知的滑动删除事件,停止播放的逻辑没有触发入口
  2. Firebase的后台消息回调运行在独立Isolate,和主应用Isolate内存不共享,缺少跨Isolate的事件通信机制

解决方案

可以通过flutter_local_notifications插件自定义通知,监听通知的删除事件来触发停止逻辑,步骤如下:

  • 第一步:添加相关依赖到pubspec.yaml
dependencies:
  flutter_local_notifications: ^16.1.0
  flutter_ringtone_player: ^3.2.0
  firebase_messaging: ^14.7.10
  • 第二步:配置本地通知初始化与回调逻辑
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();

Future<void> initLocalNotification() async {
  const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher');
  const InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid);
  // 配置通知回调,包括点击、删除、操作按钮点击
  await flutterLocalNotificationsPlugin.initialize(
    initializationSettings,
    onDidReceiveNotificationResponse: (NotificationResponse response) async {
      if (response.notificationResponseType == NotificationResponseType.dismissed) {
        // 用户滑动删除通知,停止闹钟
        await FlutterRingtonePlayer.stop();
      }
    },
    onDidReceiveBackgroundNotificationResponse: backgroundNotificationHandler,
  );
  // 安卓端创建高优先级通知渠道
  const AndroidNotificationChannel channel = AndroidNotificationChannel(
    'alarm_channel',
    '闹钟通知',
    description: '收到通知时触发闹钟的专属渠道',
    importance: Importance.max,
    playSound: false, // 因为我们自己播闹钟声音,不需要系统通知音
  );
  await flutterLocalNotificationsPlugin
      .resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
      ?.createNotificationChannel(channel);
}

// 后台通知回调,必须是顶层函数
@pragma('vm:entry-point')
void backgroundNotificationHandler(NotificationResponse response) {
  if (response.notificationResponseType == NotificationResponseType.dismissed) {
    FlutterRingtonePlayer.stop();
  }
}
  • 第三步:调整Firebase后台消息处理逻辑
Future<void> _messageHandler(RemoteMessage message) async {
  debugPrint('Incoming notification is ${message.notification!.body}');
  // 后台Isolate要单独初始化本地通知插件
  await initLocalNotification();
  // 播放闹钟
  await FlutterRingtonePlayer.playAlarm(asAlarm: false);
  // 发送自定义本地通知
  const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'alarm_channel',
    '闹钟通知',
    priority: Priority.max,
    ongoing: false, // 允许滑动删除
  );
  const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails);
  await flutterLocalNotificationsPlugin.show(
    10086, // 固定通知ID,也可以用消息的唯一ID动态赋值
    message.notification?.title ?? '闹钟提醒',
    message.notification?.body ?? '收到新通知',
    notificationDetails,
  );
}

void main() async{
  HttpOverrides.global = MyHttpOverrides();
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  // 主Isolate初始化本地通知
  await initLocalNotification();
  FirebaseMessaging.onBackgroundMessage(_messageHandler);
  runApp(const MyApp());
}

注意事项

  • 安卓端需提前适配权限:安卓13及以上需动态申请POST_NOTIFICATIONS权限,播放闹钟需按系统版本申请SCHEDULE_EXACT_ALARM或USE_FULL_SCREEN_INTENT权限,所有权限需在AndroidManifest.xml中提前声明。
  • 如果需要在通知上增加「立即停止」的快捷按钮,可配置flutter_local_notifications的通知Action,在Action回调中调用停止逻辑即可。
  • 若要避免应用后台被系统查杀导致闹钟异常停止,可在播放闹钟时启动前台服务,绑定当前通知,停止闹钟时销毁前台服务。

内容的提问来源于stack exchange,提问作者androloper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 15:54:03