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

Flutter中如何用flutter_local_notifications实现隔N天定时推送本地通知

实现每隔N天固定时间推送本地通知(基于flutter_local_notifications)

flutter_local_notifications插件本身没有提供直接的「每隔N天固定时间」重复通知选项,但可以通过两种方式实现需求:


方法一:手动计算下一次通知时间,触发后重新调度

这种方式跨平台兼容,且能严格保证固定时间推送,是更可靠的方案。

实现步骤

  1. 初始化插件及时区支持
    先完成插件初始化并引入时区依赖,确保跨时区时间计算准确:

    import 'package:flutter_local_notifications/flutter_local_notifications.dart';
    import 'package:timezone/timezone.dart' as tz;
    import 'package:timezone/data/latest.dart' as tz;
    
    final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin();
    
    void initNotifications() async {
      // 初始化时区数据
      tz.initializeTimeZones();
      // 平台初始化配置(根据项目需求补充Android/iOS图标、权限等设置)
      const initSettings = InitializationSettings(
        android: AndroidInitializationSettings('@mipmap/ic_launcher'),
        iOS: IOSInitializationSettings(),
      );
      await _notificationsPlugin.initialize(initSettings,
        onSelectNotification: (payload) async {
          // 用户点击通知后,重新调度下一次通知
          _scheduleNextNotification(2, const TimeOfDay(hour: 20, minute: 0));
        },
      );
    }
    
  2. 编写时间计算逻辑
    精准计算下一次通知的触发时间:如果当前时间已过当日目标时间,则推至次日目标时间;否则直接使用当日目标时间,确保首次推送不延迟:

    tz.TZDateTime _calculateNextTriggerTime(int daysInterval, TimeOfDay targetTime) {
      final now = tz.TZDateTime.now(tz.local);
      var nextTrigger = tz.TZDateTime(
        tz.local,
        now.year,
        now.month,
        now.day,
        targetTime.hour,
        targetTime.minute,
      );
    
      // 当前时间已过当日目标时间,自动顺延至次日
      if (nextTrigger.isBefore(now)) {
        nextTrigger = nextTrigger.add(const Duration(days: 1));
      }
    
      return nextTrigger;
    }
    
  3. 调度通知及重复逻辑
    每次调度时计算好下一次的触发时间,覆盖之前的同ID通知,确保重复逻辑连贯。Android平台可额外通过广播监听通知触发事件,避免应用后台时无法自动重新调度:

    void _scheduleNextNotification(int daysInterval, TimeOfDay targetTime) async {
      final baseTime = _calculateNextTriggerTime(daysInterval, targetTime);
      // 叠加间隔天数,得到下一次的准确触发时间
      final nextScheduledTime = baseTime.add(Duration(days: daysInterval - 1));
    
      await _notificationsPlugin.zonedSchedule(
        0, // 固定通知ID,后续调度会覆盖之前的设置
        '定时提醒',
        '这是每隔${daysInterval}天的固定时间通知',
        nextScheduledTime,
        const NotificationDetails(
          android: AndroidNotificationDetails(
            'fixed_interval_channel',
            '固定间隔通知',
            channelDescription: '用于发送每隔N天的固定时间通知',
            importance: Importance.max,
            priority: Priority.high,
          ),
        ),
        androidAllowWhileIdle: true,
        uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,
        payload: 'repeat_notification',
      );
    }
    
    // 调用示例:开启每隔2天、20:00的推送
    void start2DayRepeatNotification() {
      _scheduleNextNotification(2, const TimeOfDay(hour: 20, minute: 0));
    }
    

方法二:Android平台自定义重复间隔(仅适合非严格固定时间场景)

Android平台支持直接设置自定义时间间隔的重复通知,但iOS不支持该方式(会导致时间偏移),且无法保证严格的固定时间(若通知延迟触发,后续时间会同步偏移)。

实现代码

void scheduleAndroidCustomIntervalNotification() async {
  final now = DateTime.now();
  var scheduledDate = DateTime(now.year, now.month, now.day, 20, 0);
  // 当前时间已过当日目标时间,顺延至次日
  if (scheduledDate.isBefore(now)) {
    scheduledDate = scheduledDate.add(const Duration(days: 1));
  }

  await _notificationsPlugin.schedule(
    0,
    '定时提醒',
    '每隔2天的通知',
    scheduledDate,
    const NotificationDetails(
      android: AndroidNotificationDetails(
        'custom_interval_channel',
        '自定义间隔通知',
        channelDescription: '用于发送自定义间隔的通知',
      ),
    ),
    repeatInterval: const Duration(days: 2), // 自定义2天间隔
    androidAllowWhileIdle: true,
  );
}

关键注意事项

  1. 后台存活问题:如果应用被完全杀死,手动调度逻辑会失效。Android可结合WorkManager定期检查并重新调度;iOS需开启「Background App Refresh」权限,在后台唤醒时恢复调度。
  2. 持久化设置:建议用shared_preferences保存用户的通知配置(间隔天数、目标时间),应用启动时自动恢复调度。
  3. iOS限制:iOS对后台任务有严格管控,长期后台可能无法保证通知准时触发,方法一是iOS唯一可靠的实现方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:24:57