如何用Flutter实现特定时段内每2小时发送提醒通知?
实现喝水提醒通知的可行方案
不管用flutter_local_notifications还是awesome_notifications,都能实现你要的时间段内定时提醒功能,以下是具体实现思路和代码示例:
方案一:使用flutter_local_notifications
这个插件依赖系统原生通知调度,稳定性较好,适合基础定时需求。
步骤1:初始化插件
先完成插件的初始化和基础配置(iOS需在Info.plist添加通知权限描述,Android无需额外权限):
final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin(); Future<void> initNotifications() async { const AndroidInitializationSettings androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher'); const DarwinInitializationSettings iosSettings = DarwinInitializationSettings(); const InitializationSettings initSettings = InitializationSettings( android: androidSettings, iOS: iosSettings, ); await _notificationsPlugin.initialize(initSettings); }
步骤2:安排每日重复通知
核心思路是生成时间段内所有触发时间点,为每个时间点创建每日重复的单次通知:
Future<void> setupWaterReminders(TimeOfDay startTime, TimeOfDay endTime, int intervalHours) async { // 先清除旧的通知,避免重复 await _notificationsPlugin.cancelAll(); final today = DateTime.now(); final startDateTime = DateTime(today.year, today.month, today.day, startTime.hour, startTime.minute); final endDateTime = DateTime(today.year, today.month, today.day, endTime.hour, endTime.minute); // 生成当天所有触发时间 List<DateTime> triggerTimes = []; DateTime current = startDateTime; while (current.isBefore(endDateTime) || current.isAtSameMomentAs(endDateTime)) { triggerTimes.add(current); current = current.add(Duration(hours: intervalHours)); } // 配置通知样式 const AndroidNotificationDetails androidDetails = AndroidNotificationDetails( 'water_reminder', '喝水提醒', channelDescription: '定时提醒补充水分', importance: Importance.high, priority: Priority.high, ); const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails); // 为每个时间点安排每日重复通知 for (int i = 0; i < triggerTimes.length; i++) { await _notificationsPlugin.showDailyAtTime( i, // 每个通知唯一ID '该喝水啦!', '起身喝一杯水,保持身体水分充足', Time(triggerTimes[i].hour, triggerTimes[i].minute), notificationDetails, ); } }
方案二:使用awesome_notifications
这个插件提供更灵活的调度规则,支持复杂场景的时间配置。
步骤1:初始化插件并请求权限
import 'package:awesome_notifications/awesome_notifications.dart'; Future<void> initAwesomeNotifications() async { await AwesomeNotifications().initialize( '@mipmap/ic_launcher', // 通知图标路径 [ NotificationChannel( channelKey: 'water_reminder_channel', channelName: '喝水提醒', channelDescription: '定时提醒喝水', importance: NotificationImportance.High, ) ], ); // 请求通知权限(必须步骤) await AwesomeNotifications().requestPermissionToSendNotifications(); }
步骤2:创建每日重复通知
先清除旧通知,再生成时间段内的触发点,配置每日重复:
Future<void> setupWaterReminders(TimeOfDay startTime, TimeOfDay endTime, int intervalHours) async { // 清除所有旧通知 await AwesomeNotifications().cancelAllNotifications(); final today = DateTime.now(); final startDateTime = DateTime(today.year, today.month, today.day, startTime.hour, startTime.minute); final endDateTime = DateTime(today.year, today.month, today.day, endTime.hour, endTime.minute); DateTime current = startDateTime; while (current.isBefore(endDateTime) || current.isAtSameMomentAs(endDateTime)) { await AwesomeNotifications().createNotification( content: NotificationContent( id: current.hour * 60 + current.minute, // 用时间作为唯一ID channelKey: 'water_reminder_channel', title: '该喝水啦!', body: '记得补充水分哦', ), schedule: NotificationCalendar( hour: current.hour, minute: current.minute, repeats: true, // 每日重复 ), ); current = current.add(Duration(hours: intervalHours)); } }
关键注意事项
- 权限与后台限制:iOS需在
Info.plist添加NSUserNotificationUsageDescription和NSForegroundUsageDescription;Android部分厂商的后台省电策略会影响通知触发,建议引导用户关闭对应应用的省电模式。 - 更新时间段:用户修改起止时间后,必须先清除旧通知,再重新安排新通知,避免重复提醒。
- 通知ID唯一性:每个通知的ID必须唯一,否则会覆盖之前的通知。
内容的提问来源于stack exchange,提问作者Thanongsak
相关产品推荐
相关产品推荐

