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

如何用flutter_local_notification实现每日20:00本地通知(支持后台/被杀状态)

实现每日定时本地通知(后台/终止状态仍生效)

针对你的需求,以下是两种可行的实现方案,覆盖本地通知和Firebase推送两种场景,确保APP在后台甚至被终止时仍能触发通知:


方案一:使用flutter_local_notifications + android_alarm_manager_plus(本地定时)

该方案适用于无网络依赖的场景,Android端可实现类似闹钟的持久触发,iOS端受系统限制需做适配。

1. 依赖配置

在pubspec.yaml中添加依赖:

dependencies:
  flutter_local_notifications: ^16.1.0
  android_alarm_manager_plus: ^4.0.1

执行flutter pub get安装依赖。

2. 平台配置

Android

在android/app/src/main/AndroidManifest.xml中添加权限和配置:

<!-- 允许接收开机广播,重启后恢复定时任务 -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- 允许唤醒设备触发通知 -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<!-- 允许在设备休眠时触发任务 -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>

<application ...>
  <!-- 注册闹钟广播接收器(用于开机重启任务) -->
  <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
    <intent-filter>
      <action android:name="android.intent.action.BOOT_COMPLETED"/>
      <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
    </intent-filter>
  </receiver>
</application>

iOS

在ios/Runner/Info.plist中添加后台权限配置:

<key>UIBackgroundModes</key>
<array>
  <string>fetch</string>
  <string>remote-notification</string>
</array>
<key>NSNotificationSettingsUsageDescription</key>
<string>需要发送每日定时通知</string>

3. 代码实现

初始化通知插件

import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:android_alarm_manager_plus/android_alarm_manager_plus.dart';

final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin();

Future<void> initNotifications() async {
  // Android初始化配置
  const AndroidInitializationSettings androidInit = AndroidInitializationSettings('@mipmap/ic_launcher');
  // iOS初始化配置
  final DarwinInitializationSettings iosInit = DarwinInitializationSettings(
    requestAlertPermission: true,
    requestBadgePermission: true,
    requestSoundPermission: true,
  );
  // 统一初始化
  await _notificationsPlugin.initialize(
    InitializationSettings(android: androidInit, iOS: iosInit),
  );
}

设置每日8点定时任务

// 计算下一个8点的时间
DateTime _getNextEightPM() {
  final now = DateTime.now();
  var nextTime = DateTime(now.year, now.month, now.day, 20, 0, 0);
  if (nextTime.isBefore(now)) {
    nextTime = nextTime.add(const Duration(days: 1));
  }
  return nextTime;
}

// Android端:用AlarmManager实现后台/终止状态触发
Future<void> setupDailyAlarm() async {
  await AndroidAlarmManager.initialize();
  // 每日重复触发,精确到时间
  await AndroidAlarmManager.periodic(
    const Duration(days: 1),
    1001, // 唯一任务ID
    _triggerNotification,
    startAt: _getNextEightPM(),
    exact: true,
    wakeup: true,
    allowWhileIdle: true, // 设备休眠时仍触发
  );
}

// 通知触发逻辑(必须加@pragma注解,确保APP终止时仍能被调用)
@pragma('vm:entry-point')
static void _triggerNotification() async {
  const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'daily_notification_channel',
    '每日通知',
    channelDescription: '每日晚8点推送的定时通知',
    importance: Importance.max,
    priority: Priority.high,
    sound: RawResourceAndroidNotificationSound('notification'),
  );
  await _notificationsPlugin.show(
    0,
    '每日提醒',
    '现在是晚上8点啦',
    const NotificationDetails(android: androidDetails),
  );
}

// iOS端:用插件自带的zonedSchedule实现定时
Future<void> setupDailyIOSNotification() async {
  await _notificationsPlugin.zonedSchedule(
    0,
    '每日提醒',
    '现在是晚上8点啦',
    _getNextEightPM(),
    const NotificationDetails(
      iOS: DarwinNotificationDetails(sound: 'notification.wav'),
    ),
    androidAllowWhileIdle: true,
    uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime,
    matchDateTimeComponents: DateTimeComponents.time, // 按时间每日重复
  );
}

方案二:使用Firebase Cloud Messaging(FCM)计划推送

该方案依赖网络,无需处理本地定时逻辑,跨平台兼容性更好,APP终止时仍能通过系统推送通道触发通知。

1. 集成FCM

在pubspec.yaml中添加依赖:

dependencies:
  firebase_core: ^2.15.0
  firebase_messaging: ^14.6.5
  flutter_local_notifications: ^16.1.0

完成Firebase项目配置(Android和iOS的密钥、证书等)。

2. 后台消息处理

import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';

// 后台消息处理回调(APP终止时仍会触发)
@pragma('vm:entry-point')
Future<void> _firebaseBackgroundHandler(RemoteMessage message) async {
  await Firebase.initializeApp();
  // 显示本地通知
  const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'fcm_daily_channel',
    'FCM每日通知',
    channelDescription: '通过FCM推送的每日定时通知',
    importance: Importance.max,
    priority: Priority.high,
  );
  await _notificationsPlugin.show(
    message.messageId.hashCode,
    message.notification?.title ?? '每日提醒',
    message.notification?.body ?? '现在是晚上8点啦',
    const NotificationDetails(android: androidDetails),
  );
}

// 初始化FCM
Future<void> initFCM() async {
  await Firebase.initializeApp();
  // 请求通知权限
  await FirebaseMessaging.instance.requestPermission(
    alert: true,
    badge: true,
    sound: true,
  );
  // 注册后台消息处理器
  FirebaseMessaging.onBackgroundMessage(_firebaseBackgroundHandler);
}

3. 设置计划推送

在Firebase控制台创建计划消息:

  1. 进入云消息传递 -> 发送消息
  2. 填写通知标题、内容,选择计划 -> 定期发送
  3. 设置触发时间为每日晚8点(注意时区配置)
  4. 选择目标设备或主题,完成发送

关键注意事项

  • Android:必须手动开启应用的「自启动权限」,否则APP被终止后AlarmManager无法触发;需确保SCHEDULE_EXACT_ALARM权限已获取。
  • iOS:本地定时通知在APP被彻底杀死后可能被系统延迟或忽略,这是iOS的系统限制;FCM推送需确保设备联网且APNs配置正确。
  • 两种方案都需请求用户的通知权限,否则通知无法显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 00:44:56