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

如何在Flutter中设置指定时间的周期性通知?

Flutter 实现指定时间的周期性通知

你当前使用periodicallyShow方法只能在函数调用的即时触发通知,且无法指定固定的重复时间点,同时因为应用可能随时关闭,不想依赖本地时间追踪。以下是两种可行的解决方案:

方案一:使用zonedSchedule结合规则设置

flutter_local_notifications的zonedSchedule方法支持指定具体触发时间,且能设置重复规则,即使应用关闭也可由系统调度触发。

示例代码(以每天早上8点触发为例):

Future<void> scheduleDailyNotification({
  required int id,
  required String title,
  required String body,
  required String payload,
}) async {
  // 配置通知渠道
  const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'daily_notif_channel',
    '每日通知',
    channelDescription: '用于发送每日固定时间的通知',
    icon: '@mipmap/ic_launcher',
    importance: Importance.max,
    priority: Priority.high,
  );
  const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails);

  // 设置首次触发时间为当天8点,若当前时间已过则设为第二天8点
  final now = DateTime.now();
  DateTime scheduledTime = DateTime(now.year, now.month, now.day, 8, 0);
  if (scheduledTime.isBefore(now)) {
    scheduledTime = scheduledTime.add(const Duration(days: 1));
  }

  // 转换为时区时间
  final scheduledZoneTime = tz.TZDateTime.from(scheduledTime, tz.local);

  // 调度每日重复通知
  await _flutterLocalNotificationsPlugin.zonedSchedule(
    id,
    title,
    body,
    scheduledZoneTime,
    notificationDetails,
    androidAllowWhileIdle: true, // 允许设备休眠时触发
    uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,
    matchDateTimeComponents: DateTimeComponents.time, // 按时间重复,每天同一时间触发
  );
}

注意:使用该方法需先导入timezone包并配置时区数据,确保时间计算准确。

方案二:后端用Node.js Cron处理通知任务

将通知调度逻辑移至后端,通过Node.js的cron包配置定时任务,触发时调用推送服务(如FCM)将通知推送到Flutter应用,完全不依赖应用是否处于运行状态。

步骤说明:

  • 后端:用node-cron包配置定时任务(例如每天8点执行),任务触发时调用推送服务API,将通知发送到指定设备。
  • Flutter端:集成推送服务SDK,处理收到的推送通知,即使应用在后台或关闭状态也能收到系统级通知。

该方案适合需要统一管理通知规则、或通知内容需动态生成的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:13:22