Flutter实现每3天触发本地通知功能遇阻求助
问题分析与修复方案
你的代码存在以下核心问题导致通知无法正常工作:
- 未触发检查逻辑:
checkAndShowNotification方法从未被调用,初始化通知服务后没有执行任何检查或调度操作 - 仅前台检查无法满足后台推送:当前逻辑只有用户打开应用时才会检查时间,若用户3天不打开应用,通知不会触发
- Android通知渠道未创建:Android 8.0及以上系统需要显式创建通知渠道,否则通知无法显示
- 首次通知逻辑错误:首次打开应用时
lastNotificationTime为null,会立即弹出通知,不符合“3天后推送”的需求
修复后的代码
notify_service.dart
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:shared_preferences/shared_preferences.dart'; class NotificationService { final FlutterLocalNotificationsPlugin notificationsPlugin = FlutterLocalNotificationsPlugin(); // 标记是否已设置重复通知 Future<bool> _hasScheduledNotification() async { SharedPreferences prefs = await SharedPreferences.getInstance(); return prefs.getBool('hasScheduledNotification') ?? false; } Future<void> _setScheduledNotificationFlag(bool value) async { SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setBool('hasScheduledNotification', value); } // 创建Android通知渠道 Future<void> _createAndroidNotificationChannel() async { const AndroidNotificationChannel channel = AndroidNotificationChannel( 'repeat_notification_channel', // 渠道ID '重复提醒通知', // 渠道名称 description: '每3天推送一次的用户提醒', // 渠道描述 importance: Importance.max, ); await notificationsPlugin.resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>() ?.createNotificationChannel(channel); } Future<void> initNotification() async { // Android初始化 const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@drawable/sn_invent'); // iOS初始化 const DarwinInitializationSettings initializationSettingsIOS = DarwinInitializationSettings( requestAlertPermission: true, requestBadgePermission: true, requestSoundPermission: true, ); const InitializationSettings initializationSettings = InitializationSettings( android: initializationSettingsAndroid, iOS: initializationSettingsIOS, ); await notificationsPlugin.initialize(initializationSettings); // 创建Android通知渠道 await _createAndroidNotificationChannel(); // 检查并设置重复通知 await _setupRepeatingNotification(); } NotificationDetails _notificationDetails() { return const NotificationDetails( android: AndroidNotificationDetails( 'repeat_notification_channel', '重复提醒通知', channelDescription: '每3天推送一次的用户提醒', importance: Importance.max, priority: Priority.high, ), iOS: DarwinNotificationDetails(), ); } // 设置每3天重复的通知 Future<void> _setupRepeatingNotification() async { bool hasScheduled = await _hasScheduledNotification(); if (hasScheduled) return; // 首次通知时间:当前时间+3天 DateTime firstNotificationTime = DateTime.now().add(const Duration(days: 3)); // 调度重复通知 await notificationsPlugin.periodicallyShow( 0, // 通知ID '您的应用提醒', '该打开应用看看啦!', RepeatInterval.everyThreeDays, // 每3天重复 _notificationDetails(), androidAllowWhileIdle: true, // 允许设备空闲时触发 uiLocalNotificationDateInterpretation: UILocalNotificationDateInterpretation.absoluteTime, ); // 标记已设置重复通知 await _setScheduledNotificationFlag(true); } }
main.dart
import 'package:flutter/material.dart'; import 'package:flutter_goals_application/src/services/notify_service.dart'; import 'screens/homescreen.dart'; Future<void> main() async { WidgetsFlutterBinding.ensureInitialized(); NotificationService notificationService = NotificationService(); await notificationService.initNotification(); runApp(const MaterialApp( home: HomescreenWidget(), )); }
关键修改说明
- 使用系统级重复调度:通过
periodicallyShow方法让系统负责调度通知,即使应用关闭或在后台也能按时触发 - 添加通知渠道创建逻辑:适配Android 8.0+的通知渠道要求,确保通知能正常显示
- 避免重复调度:用SharedPreferences标记是否已设置重复通知,防止每次打开应用都重新创建调度任务
- 修正首次通知时间:首次通知设置为当前时间+3天,而不是立即触发
- 优化Android触发条件:设置
androidAllowWhileIdle: true,确保设备低功耗时也能触发通知
内容的提问来源于stack exchange,提问作者user19922759
相关产品推荐
相关产品推荐

