Flutter实现自定义重复本地通知:按周几、时段、间隔触发
Flutter 本地通知:按指定星期、时段与间隔触发
需求说明
- 支持选择通知触发的星期(如周日、周一)
- 可设置通知触发的时间范围(如下午4-5点)
- 自定义通知触发间隔(如每5分钟)
- 仅在选定星期的指定时段内,按设置间隔触发通知
实现代码
void generateAndScheduleNotifications() { // 从Hive获取用户设置的通知间隔分钟数 hiveController.retrieveCustomMinute(); // 将用户设置的开始时间转换为UTC时间 DateTime start = convertTimeOfDayToDateTime(startTime).toUtc(); // 结束时间设置为30天后的同一时段(可根据需求调整时长) DateTime end = convertTimeOfDayToDateTime(endTime).toUtc().add(const Duration(days: 30)); print('为以下星期生成通知: $selectedDayNames'); // 生成符合选定星期的每日起始时间规则 final rule = RecurrenceRule( frequency: Frequency.daily, until: end, byWeekDays: selectedDayNames, ); // 获取所有符合规则的起始时间点 final instances = rule .getInstances( start: DateTime.utc(start.year, start.month, start.day, start.hour, start.minute, start.second)) .toList(); // 转换为本地时区(这里使用尼泊尔时区,可根据需求修改) final dates = instances .map((instance) => tz.TZDateTime.from(instance, tz.getLocation('Asia/Kathmandu'))) .toList(); print('待调度的每日起始时间: $dates'); _scheduleDailyAndMinutelyNotifications(dates); } Future<void> _scheduleDailyAndMinutelyNotifications( List<tz.TZDateTime> dailyDates) async { // 获取用户设置的结束时间 DateTime end = convertTimeOfDayToDateTime(endTime); for (final dailyDate in dailyDates) { // 构造当日的通知结束时间(UTC) DateTime endDate = DateTime(dailyDate.year, dailyDate.month, dailyDate.day, end.hour, end.minute, end.second) .toUtc(); // 调度当日的起始通知(可选,若不需要可移除) await _scheduleDailyNotification(dailyDate); // 调度当日时段内的间隔通知 await generateAndScheduleMinutelyNotifications(dailyDate, endDate); } print('所有通知调度完成'); } Future<void> _scheduleDailyNotification(tz.TZDateTime dailyDate) async { await flutterLocalNotificationsPlugin.zonedSchedule( dailyDate.hashCode, // 用时间哈希作为唯一通知ID '定时通知', '每日通知: ${DateFormat('yyyy-MM-dd EEEE HH:mm').format(dailyDate)}', dailyDate, const NotificationDetails( android: AndroidNotificationDetails('daily_channel', '每日通知频道'), ), androidAllowWhileIdle: true, // 允许在设备休眠时触发 uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, matchDateTimeComponents: DateTimeComponents.dateAndTime, ); print('每日通知已调度: $dailyDate'); } Future<void> generateAndScheduleMinutelyNotifications( tz.TZDateTime dailyDate, DateTime endDate) async { DateTime start = dailyDate.toUtc(); print('生成从 $start 到 $endDate 的间隔通知'); // 生成按用户设置间隔触发的时间规则 final rule = RecurrenceRule( frequency: Frequency.minutely, until: DateTime.utc(endDate.year, endDate.month, endDate.day, endDate.hour, endDate.minute, endDate.second), interval: hiveController.customMinute ?? 5, // 使用用户设置的间隔,默认5分钟 ); // 获取所有符合间隔规则的时间点 final instances = rule .getInstances( start: DateTime.utc(start.year, start.month, start.day, start.hour, start.minute, start.second)) .toList(); // 转换为本地时区 final dates = instances .map((instance) => tz.TZDateTime.from(instance, tz.getLocation('Asia/Kathmandu'))) .toList(); print('待调度的间隔通知时间点: $dates'); await _scheduleNotifications(dates); } Future<void> _scheduleNotifications(List<tz.TZDateTime> dates) async { for (final date in dates) { await flutterLocalNotificationsPlugin.zonedSchedule( date.hashCode, // 唯一ID '定时通知', '间隔通知: ${DateFormat('yyyy-MM-dd EEEE HH:mm').format(date)}', date, const NotificationDetails( android: AndroidNotificationDetails( 'interval_channel', '间隔通知频道')), androidAllowWhileIdle: true, uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, matchDateTimeComponents: DateTimeComponents.time, ); } print('所有间隔通知调度完成'); }
关键说明
- 依赖库:需在
pubspec.yaml中添加以下依赖:flutter_local_notifications: ^16.1.0 timezone: ^0.9.2 hive: ^2.2.3 hive_flutter: ^1.1.0 - 时区配置:代码中使用
Asia/Kathmandu时区,可根据用户所在地区修改为对应时区(如Asia/Shanghai)。 - 通知ID:使用时间的哈希值作为唯一ID,避免重复调度同一通知。
- 用户配置:
selectedDayNames(选定星期)、startTime/endTime(时间范围)、customMinute(间隔分钟数)需从用户界面获取并存储到Hive中。
内容的提问来源于stack exchange,提问作者coder lover
相关产品推荐
相关产品推荐

