Flutter中如何实现每日定时自动发送提醒通知?
实现每日重复本地通知及时间修改方案
一、每日自动推送实现
你当前使用的zoneSchedule方法本身支持重复调度,只需在调用时指定repeatInterval参数为RepeatInterval.daily,同时使用固定的通知ID(避免重复创建多个调度任务)。另外要注意时区匹配,建议使用用户设备的本地时区,或与Firebase返回的时间时区保持一致。
示例代码:
// 假设从Firebase获取的目标时间为targetTime(Time对象,如Time(hour: 9, minute: 0)) await flutterLocalNotificationsPlugin.zonedSchedule( 0, // 固定通知ID,用于后续修改/取消调度 '每日提醒', '该完成今日任务了', _calculateNextTriggerTime(targetTime), // 计算下一次触发的时间(今日或次日) NotificationDetails( android: AndroidNotificationDetails( 'daily_reminder_channel', '每日提醒频道', importance: Importance.max, ), ), androidAllowWhileIdle: true, // 确保设备休眠时也能触发通知 uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, matchDateTimeComponents: DateTimeComponents.time, // 按每日固定时间重复 repeatInterval: RepeatInterval.daily, // 开启每日重复调度 ); // 辅助函数:计算下一次触发的时间 TZDateTime _calculateNextTriggerTime(Time time) { final now = TZDateTime.now(LocalTimeZone()); var scheduledDate = TZDateTime( LocalTimeZone(), now.year, now.month, now.day, time.hour, time.minute, ); // 如果当前时间已过今日指定时间,则将触发时间设为次日同一时间 if (scheduledDate.isBefore(now)) { scheduledDate = scheduledDate.add(const Duration(days: 1)); } return scheduledDate; }
二、调度时机选择
- 首次设置时间时:用户选择时间或从Firebase同步时间后,立即执行上述调度代码。
- 应用启动时:本地通知调度在系统重启、应用被强制杀死后可能丢失,因此在
main函数或首页的initState中,读取本地保存的时间,重新执行调度逻辑。 - 网络同步后:有网络时拉取Firebase最新时间,对比本地保存的时间,若不一致则更新本地存储并重新调度。
三、支持用户修改指定时间
修改时间的核心逻辑是先取消旧调度,再根据新时间创建新的重复调度,同时更新本地存储的时间:
- 取消旧调度:
await flutterLocalNotificationsPlugin.cancel(0); // 传入之前使用的通知ID
- 保存新时间到本地(使用
shared_preferences):
final prefs = await SharedPreferences.getInstance(); await prefs.setInt('reminder_hour', newTime.hour); await prefs.setInt('reminder_minute', newTime.minute);
- 用新时间重新调用
zonedSchedule方法(参考第一部分的代码,替换targetTime为用户设置的新时间)。
四、无网络场景下的保障
- 持久化本地时间:首次从Firebase获取时间后,立即保存到本地存储(如
shared_preferences),后续所有调度逻辑优先读取本地时间,不再依赖网络。 - 离线调度恢复:应用启动时,无论网络状态如何,都从本地读取保存的时间,重新执行调度逻辑,确保通知能正常触发。
- 网络重连同步:网络恢复时,自动拉取Firebase最新时间,对比本地存储,若有更新则重复「取消旧调度→保存新时间→创建新调度」的流程。
注意事项:
- Android端需确保开启通知权限,同时将
androidAllowWhileIdle设为true,避免设备休眠时通知不触发。 - iOS端需在
Info.plist中配置通知权限相关项,确保后台通知能正常工作。
内容的提问来源于stack exchange,提问作者Ritik Kumar
相关产品推荐
相关产品推荐

