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

使用flutter_local_notifications插件Flutter定时通知无法触发求助

Flutter定时通知不触发问题排查与解决(Android 10)

问题描述

使用flutter_local_notifications开发定时通知功能时,即时通知可正常触发,但定时通知未按预期显示,调试控制台无任何报错或警告。

环境信息

  • flutter_local_notifications版本:^19.0.0
  • 运行平台:Android 10

实现代码

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

class NotificationService {
  final notificationsPlugin = FlutterLocalNotificationsPlugin();

  bool _isInitialized = false;

  bool get isInitialized => _isInitialized;

  // Initialize
  Future<void> initNotification() async {
    if (_isInitialized) return;

    // Initialize timezone
    tz.initializeTimeZones();
    final String currentTimeZone = await FlutterTimezone.getLocalTimezone();
    tz.setLocalLocation(tz.getLocation(currentTimeZone));

    print("Device Timezone: $currentTimeZone");

    const initSettingsAndroid =
        AndroidInitializationSettings('@mipmap/ic_launcher');

    const initSettings = InitializationSettings(android: initSettingsAndroid);

    await notificationsPlugin.initialize(initSettings);
    _isInitialized = true;
  }

  // Notification Detail
  NotificationDetails notificationDetails() {
    return NotificationDetails(
      android: AndroidNotificationDetails(
        'daily_channel_id',
        'Daily Notifications',
        channelDescription: 'Daily notifications for the app',
        importance: Importance.max,
        priority: Priority.high,
      ),
    );
  }

  // Show Notifications
  Future<void> showNotifications({
    int id = 0,
    String? title,
    String? body,
  }) async {
    return notificationsPlugin.show(
      id,
      title,
      body,
      notificationDetails(),
    );
  }

  // Schedule a notification at a specified time (hour: 0-23, min: 0-59)
Future<void> scheduleNotification({
  int id = 1,
  required String title,
  required String body,
  required int hour,
  required int minute,
}) async {
  // Get the current date/time in device's local timezone
  final now = tz.TZDateTime.now(tz.local);
  print("Current Time (TZ): $now");

  // Create a date time for today at the specified hour and minute
  var scheduledDate = tz.TZDateTime(
    tz.local,
    now.year,
    now.month,
    now.day,
    hour,
    minute,
  );

  print("Scheduled Time (Before Adjustment): $scheduledDate");

  // Ensure scheduled time is in the future
  if (scheduledDate.isBefore(now)) {
    scheduledDate = scheduledDate.add(Duration(days: 1));
    print("Scheduled Time Adjusted to Next Day: $scheduledDate");
  }

  // Schedule the notification
  await notificationsPlugin.zonedSchedule(
    id,
    title,
    body,
    scheduledDate,
    notificationDetails(),
    androidScheduleMode: AndroidScheduleMode.inexactAllowWhileIdle,
    matchDateTimeComponents: DateTimeComponents.dateAndTime,
   
  );

  print("Final Scheduled Time: $scheduledDate");
}

  // Cancel all notifications
  Future<void> cancelAllNotifications() async {
    await notificationsPlugin.cancelAll();
  }
}

已完成排查

  • 调用showNotifications方法触发即时通知功能正常
  • 调用scheduleNotification方法后,控制台打印的定时时间计算正确,但通知未按时出现
  • 已通过flutter_timezone和timezone包正确识别并设置设备时区
  • 应用已具备通知权限(Android 10无需额外精确闹钟权限)
  • 应用未被电池优化限制后台进程

针对性解决方案

1. 调整定时精度模式

当前使用的AndroidScheduleMode.inexactAllowWhileIdle模式下,系统可能会合并延迟通知以节省电量。如果需要精确触发,改为AndroidScheduleMode.exactAllowWhileIdle,该模式支持设备在低电模式下仍精确触发通知:

androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,

2. 修正重复触发参数(按需选择)

  • 如果需求是每天固定时间重复触发,将matchDateTimeComponents改为DateTimeComponents.time(原代码的dateAndTime仅会触发一次指定日期时间)
  • 如果是单次定时触发,保持DateTimeComponents.dateAndTime即可

3. 添加必填时间解释参数

在zonedSchedule中补充uiLocalNotificationDateInterpretation参数,明确时间解析方式:

uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,

4. 主动创建通知渠道(可选)

虽然代码中定义了渠道,但部分场景下渠道可能未自动创建,可在初始化时主动创建:

// 在initNotification方法中添加
await notificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()
    ?.createNotificationChannel(AndroidNotificationChannel(
        'daily_channel_id',
        'Daily Notifications',
        description: 'Daily notifications for the app',
        importance: Importance.max,
      ));

修改后的scheduleNotification方法示例

Future<void> scheduleNotification({
  int id = 1,
  required String title,
  required String body,
  required int hour,
  required int minute,
}) async {
  final now = tz.TZDateTime.now(tz.local);
  var scheduledDate = tz.TZDateTime(
    tz.local,
    now.year,
    now.month,
    now.day,
    hour,
    minute,
  );

  if (scheduledDate.isBefore(now)) {
    scheduledDate = scheduledDate.add(const Duration(days: 1));
  }

  await notificationsPlugin.zonedSchedule(
    id,
    title,
    body,
    scheduledDate,
    notificationDetails(),
    androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
    matchDateTimeComponents: DateTimeComponents.time, // 每天重复触发用这个,单次用dateAndTime
    uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 14:25:20