Flutter中如何通过滑动通知停止通知触发的闹钟播放音效
你当前的实现只完成了「收到Firebase推送触发闹钟播放」的逻辑,存在两个核心问题导致滑动通知无法停止闹钟:
- 没有监听系统通知的滑动删除事件,停止播放的逻辑没有触发入口
- 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
相关产品推荐
相关产品推荐

