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

Flutter 每周重复本地通知仅当日生效 代码异常问题求助

Flutter 每周重复本地通知异常修复方案

你的代码存在两个核心问题导致非当日通知无法触发:

  1. 时间计算逻辑存在边界漏洞:_scheduleWeekly方法依赖_scheduleDaily的返回值做累加,当指定的通知时间在今日已过、且目标weekday早于当前weekday时,循环累加的方式在部分时区场景下会出现偏移误差。
  2. 未校验weekday取值规范:Dart内置DateTime.weekday属性的取值规则为周一=1、周日=7,如果你的业务侧传入的weekday是按周日=1、周六=7的规则计算,会导致匹配失败,永远找不到符合条件的触发日期。

修复后完整代码

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:timezone/data/latest_all.dart' as tz;

// 应用启动时必须先初始化时区,不要漏掉这步
void initTimeZone() {
  tz.initializeTimeZones();
  tz.setLocalLocation(tz.getLocation('Asia/Shanghai')); // 替换为对应地区时区
}

static Future showWeeklyNotification({
  required int id,
  String? title,
  String? body,
  String? payload,
  required int weekday, // 必须符合Dart规范:1=周一, 7=周日
  required Time scheduleTime,
}) async => _notifications.zonedSchedule(
  id,
  title,
  body,
  _scheduleWeekly(scheduleTime, weekday),
  await _notificationDetails(),
  androidAllowWhileIdle: true,
  uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,
  matchDateTimeComponents: DateTimeComponents.dayOfWeekAndTime,
);

static tz.TZDateTime _scheduleDaily(Time time) {
  final now = tz.TZDateTime.now(tz.local);
  final scheduleDate = tz.TZDateTime(tz.local, now.year, now.month, now.day, time.hour, time.minute, time.second);
  return scheduleDate.isBefore(now) ? scheduleDate.add(const Duration(days: 1)) : scheduleDate;
}

// 优化后的周时间计算逻辑,用取模运算替代循环累加,避免边界误差
static tz.TZDateTime _scheduleWeekly(Time time, int weekday) {
  var scheduleDate = _scheduleDaily(time);
  int daysToAdd = (weekday - scheduleDate.weekday + 7) % 7;
  scheduleDate = scheduleDate.add(Duration(days: daysToAdd));
  return scheduleDate;
}

注意事项

  • 每个不同的通知必须分配唯一ID,比如周一的3个不同时间的通知需要对应3个不同ID,否则新通知会覆盖同ID的旧通知。
  • 安卓端需要确保通知权限、后台弹出通知权限、自启动权限已开启,部分国产系统限制严格,未开权限会导致息屏/后台状态收不到通知。
  • 如果你的业务逻辑里周日是一周第一天,传入的weekday为1代表周日,需要提前做转换再传参:int dartWeekday = businessWeekday == 1 ? 7 : businessWeekday -1;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 00:06:01