Flutter Local Notifications如何跳过当日通知并重新安排至次日?
解决方案
核心思路是:当用户完成当日事项时,先取消已调度的当日通知,再重新调度次日同一时间的每日通知,利用matchDateTimeComponents: DateTimeComponents.time实现后续每日自动触发。
步骤1:给每日通知分配唯一ID
用固定ID(比如100)标识每日提醒通知,方便后续精准取消。
步骤2:用户完成事项时的处理逻辑
当用户标记当日事项完成后,执行以下操作:
- 取消当前已调度的每日通知
- 计算次日的提醒时间点
- 重新调度从次日开始的每日通知
代码示例
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:timezone/timezone.dart' as tz; // 假设你已经初始化了flutterLocalNotificationsPlugin实例 Future<void> rescheduleNotificationToNextDay(int hour, int minute) async { // 1. 取消当前的每日提醒通知 await flutterLocalNotificationsPlugin.cancel(100); // 2. 计算次日同一时间的触发时间 final now = tz.TZDateTime.now(tz.local); var nextTriggerTime = tz.TZDateTime( tz.local, now.year, now.month, now.day + 1, // 直接设置为次日 hour, minute, 0, ); // 3. 重新调度每日通知 await flutterLocalNotificationsPlugin.zonedSchedule( 100, '每日事项提醒', '记得完成今日任务', nextTriggerTime, const NotificationDetails( android: AndroidNotificationDetails( 'daily_reminder_channel', '每日提醒频道', channelDescription: '用于每日事项提醒的通知频道', importance: Importance.high, ), ), androidAllowWhileIdle: true, // 确保后台低电量时也能触发 uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, matchDateTimeComponents: DateTimeComponents.time, // 保持每日同一时间触发 ); }
关键说明
- 取消原有通知是核心:如果不取消,之前调度的当日通知仍会触发,所以必须先调用
cancel(通知ID)。 - 直接设置次日日期:通过
now.day +1确保起始触发时间是次日,结合matchDateTimeComponents: DateTimeComponents.time,后续会自动每日同一时间触发,自然跳过当日。 - 避免WorkManager的后台问题:Flutter Local Notifications在Android上已适配
AlarmManager(低版本)和JobScheduler(高版本),加上androidAllowWhileIdle: true,大部分设备后台可正常运行,无需额外依赖WorkManager。
额外注意事项
- 适配Android 13+:需要申请
POST_NOTIFICATIONS权限,否则通知无法弹出。 - 跨月跨年处理:
tz.TZDateTime会自动处理月末、年末的日期跳转(比如12月31日加1天会变成次年1月1日),无需手动判断。 - 测试技巧:可以临时把提醒时间设为当前时间后5分钟,完成事项后观察当日是否不再弹出通知,次日同一时间是否正常触发。
内容的提问来源于stack exchange,提问作者Ashrith Kanakanala
相关产品推荐
相关产品推荐

