You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter安卓平台每日定时通知无法触发问题求助

Flutter安卓平台每日定时通知无法触发问题求助

我太懂这种闹心的感觉了——即时通知秒弹,但定时的明明日志显示时间算对了,却死活不出来!结合我自己踩过的flutter_local_notifications坑,给你梳理几个优先级最高的排查点和修复方案:

1. 先改调度模式:从「不精确」转「精确后台允许」

你当前用的AndroidScheduleMode.inexactAllowWhileIdle是给非紧急任务设计的,系统会批量延迟触发(比如攒一堆任务一起跑),测试短时间内的定时任务肯定踩坑!

直接换成精确模式,测试和生产都更靠谱:

await _notificationsPlugin.zonedSchedule(
  id,
  title,
  body,
  scheduledDate,
  NotificationDetails(
    android: AndroidNotificationDetails(
      'daily_reminders_v2',
      'Daily Reminders',
      channelDescription: 'Reminds you when the daily puzzle resets',
      importance: Importance.max,
      priority: Priority.high,
      icon: 'launcher_icon',
      enableVibration: true, // 加个振动确保能感知到
      playSound: true,
    ),
    iOS: DarwinNotificationDetails(),
  ),
  androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle, // 替换成这个精确模式
  uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, // 明确时间解析规则
  // 注意:测试单次触发就注释掉下面一行;要每日重复必须打开
  // matchDateTimeComponents: DateTimeComponents.time,
);

2. 补全重复触发的核心参数(每日重复必备)

你代码里把matchDateTimeComponents: DateTimeComponents.time注释掉了——这是每日重复定时的关键!如果要让通知每天同一时间触发,这个参数必须加上,不然只会触发一次就没了。

如果是测试单次触发就去掉这个参数,日常用每日重复就加上:

matchDateTimeComponents: DateTimeComponents.time, // 每日重复必备

3. 修复分钟溢出的边界问题

你的测试代码用了now.minute + 2,如果当前是59分,加2会变成61,tz.TZDateTime构造函数不会自动处理这种溢出,会生成无效时间(比如11:61),系统直接忽略这个定时任务!

_scheduleDaily加个小修复:

Future<void> _scheduleDaily({
  required int id,
  required String title,
  required String body,
  required int hour,
  required int minute,
}) async {
  final now = tz.TZDateTime.now(tz.local);
  
  // 处理小时/分钟溢出
  int targetHour = hour;
  int targetMinute = minute;
  if (targetMinute >= 60) {
    targetHour += targetMinute ~/ 60;
    targetMinute = targetMinute % 60;
  }
  if (targetHour >= 24) {
    targetHour = targetHour % 24;
  }

  var scheduledDate = tz.TZDateTime(
    tz.local,
    now.year,
    now.month,
    now.day,
    targetHour,
    targetMinute,
  );

  // 原有的时间判断:如果已过当前时间,设为明天
  if (scheduledDate.isBefore(now)) {
    scheduledDate = scheduledDate.add(const Duration(days: 1));
  }

  log.i(" Scheduling Notification for: $scheduledDate");
  // ... 后面的zonedSchedule代码不变
}

4. 排查国产安卓的「后台杀进程」噩梦

如果是小米、华为、OPPO这类国产手机,光加权限没用!系统默认会把非白名单应用的后台任务全杀了,包括定时通知:

  • 把应用加入「后台保护」/「自启动管理」白名单
  • 关闭应用的「电池优化」(设置→电池→电池优化→找到你的应用→设为「不允许」)

5. 确认通知权限和通道状态

  • 去系统设置→应用→你的应用→通知,检查:
    1. 整体通知权限是否开启
    2. 你创建的daily_reminders_v2通道是否开启了声音、振动等
  • 如果之前改过通道参数,建议卸载重装应用(安卓通道创建后无法修改,只能卸载重建)

6. 测试时的小技巧

  • 不要用模拟器的「快速跳过时间」功能,很多模拟器的时间跳跃会导致定时任务失效,手动等时间到最靠谱
  • 测试时不要强制关闭应用,正常退到后台就行(强制关闭会清空所有pending的定时任务)

先把前两个修复点改了试试,应该能解决大部分情况!如果还是不行,你可以告诉我你的flutter_local_notifications版本和手机型号,我再帮你排查更细节的点~

火山引擎 最新活动