You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter用awesome_notifications实现指定时间暂停恢复定时通知

指定时间段暂停/恢复定时通知的实现方案

你之前通过实时格式化当前时间做字符串匹配、再触发取消通知的逻辑无法生效,核心原因是这段判断代码只有在主动执行时才会运行,App在后台、进程挂起状态下不会持续轮询时间,一旦执行时机跳过15:00的时间点,就完全不会触发取消操作,根本做不到精准时间控制。

具体实现步骤

用awesome_notifications自带的日历调度+通知创建监听实现,不需要App常驻前台,系统级调度可以保证到点精准触发:

  • 第一步:固定所有通知的ID,不要用随机ID,避免取消通知时找不到目标、误删其他调度任务
// 固定ID常量
const int waterReminderId = 10001; // 喝水提醒通知ID
const int stopScheduleId = 10086; // 15:00停止通知的调度ID
const int resumeScheduleId = 10087; // 15:20恢复通知的调度ID
  • 第二步:注册两个固定时间点的静默调度任务,专门负责通知的启停
// 注册15:00自动停止提醒的调度
Future<void> registerStopTask() async {
  String localTimeZone = await AwesomeNotifications().getLocalTimeZoneIdentifier();
  await AwesomeNotifications().createNotification(
    content: NotificationContent(
      id: stopScheduleId,
      channelKey: 'scheduled_channel',
      // 设为静默通知,触发时不弹出提示
      silent: true,
      title: '',
      body: '',
    ),
    // 每天15:00:00精准触发
    schedule: NotificationCalendar(
      hour: 15,
      minute: 0,
      second: 0,
      timeZone: localTimeZone,
      repeats: true,
    ),
  );
}

// 注册15:20自动恢复提醒的调度
Future<void> registerResumeTask() async {
  String localTimeZone = await AwesomeNotifications().getLocalTimeZoneIdentifier();
  await AwesomeNotifications().createNotification(
    content: NotificationContent(
      id: resumeScheduleId,
      channelKey: 'scheduled_channel',
      silent: true,
      title: '',
      body: '',
    ),
    // 每天15:20:00精准触发
    schedule: NotificationCalendar(
      hour: 15,
      minute: 20,
      second: 0,
      timeZone: localTimeZone,
      repeats: true,
    ),
  );
}
  • 第三步:修改原有喝水提醒的创建代码,使用固定ID,修复时区取值bug
Future<void> createWaterReminderNotification() async {
  String localTimeZone = await AwesomeNotifications().getLocalTimeZoneIdentifier();
  // 修复原代码里utc时区取值错误的问题
  // String utcTimeZone = await AwesomeNotifications().getUtcTimeZoneIdentifier();

  await AwesomeNotifications().createNotification(
      content: NotificationContent(
          id: waterReminderId, // 使用固定ID
          channelKey: 'scheduled_channel',
          title: 'Notification at every single minute',
          body: 'This notification was schedule to repeat at every single minute.',
          notificationLayout: NotificationLayout.BigPicture,
          bigPicture: 'asset://assets/images/dariSDM-modified.png'),
      schedule: NotificationInterval(
          interval: 60, timeZone: localTimeZone, repeats: true));
}
  • 第四步:注册通知创建流监听,收到启停任务的调度信号时执行对应操作
    在App初始化通知的位置添加监听:
AwesomeNotifications().createdStream.listen((notification) {
  // 触发15点停止任务:只取消喝水提醒,不要删除两个启停调度
  if (notification.id == stopScheduleId) {
    AwesomeNotifications().cancel(waterReminderId);
  }
  // 触发15点20恢复任务:重新创建60秒间隔的提醒
  if (notification.id == resumeScheduleId) {
    createWaterReminderNotification();
  }
});
  • 第五步:初始化时注册所有调度
    App首次启动、用户重新开启通知权限时,依次调用registerStopTask()、registerResumeTask()、createWaterReminderNotification()即可,不需要额外做时间判断。

注意:不要调用cancelScheduledNotifications()或者cancelAll()类的全量取消方法,会把两个启停调度任务一起删掉,导致第二天的启停逻辑失效,所有取消操作都只针对固定ID的喝水提醒。

方案优势

  • 所有时间触发逻辑交给系统级通知调度实现,不需要App前台运行、不需要自行轮询时间,时间精度可达秒级
  • 不存在原字符串匹配方案的漏触发问题,只要调度注册完成,到点系统会自动唤醒App执行对应逻辑
  • 配置一次后长期生效,不需要每日重复注册

内容的提问来源于stack exchange,提问作者wahyu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:24:41