Flutter本地通知重复触发时内容不更新问题求解
解决Flutter定时通知内容自动更新的问题
问题根源在于periodicallyShow方法会在调用时固定通知的标题和内容,后续重复触发时不会重新执行代码生成新的随机字符串。要实现每次通知自动获取新内容,需要改用后台定时任务结合普通通知展示的方式,具体步骤如下:
1. 替换原有的重复通知方法
修改NotificationService类,移除periodicallyShow,改用普通的show方法展示单条通知:
class NotificationService { final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // 初始化通知插件(必须添加) Future<void> init() async { const AndroidInitializationSettings androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher'); const DarwinInitializationSettings iosSettings = DarwinInitializationSettings(); const InitializationSettings initSettings = InitializationSettings( android: androidSettings, ios: iosSettings, ); await flutterLocalNotificationsPlugin.initialize(initSettings); } Future<void> showNotification(int id, String title, String body) async { await flutterLocalNotificationsPlugin.show( id, title, body, const NotificationDetails( android: AndroidNotificationDetails('main_channel', 'Main Channel', channelDescription: "ashwin", importance: Importance.max, priority: Priority.max), iOS: DarwinNotificationDetails( sound: 'default.wav', presentAlert: true, presentBadge: true, presentSound: true, ), ), androidAllowWhileIdle: true, ); } }
2. 引入后台任务插件
在pubspec.yaml中添加flutter_workmanager依赖(用于跨平台执行定时后台任务):
dependencies: flutter: sdk: flutter flutter_local_notifications: ^16.1.0 # 替换为最新版本 flutter_workmanager: ^0.5.1 # 替换为最新版本
3. 配置后台任务回调
在main.dart中初始化WorkManager,并定义任务回调(每次触发时生成随机内容并展示通知):
import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_workmanager/flutter_workmanager.dart'; import 'notification_service.dart'; // 引入你的NotificationService类 // 后台任务回调函数 void callbackDispatcher() { Workmanager().executeTask((task, inputData) async { // 从传入参数中获取名称列表和用户内容 final List<String> names = List<String>.from(inputData!['names']); final String userPost = inputData['userPost']; // 生成随机名称 final random = Random(); final String randomName = names[random.nextInt(names.length)]; // 初始化通知服务并展示通知 final notificationService = NotificationService(); await notificationService.init(); await notificationService.showNotification( 1, '$randomName$userPost', randomName, ); return Future.value(true); }); } void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化WorkManager await Workmanager().initialize( callbackDispatcher, isInDebugMode: false, // 发布版设为false ); runApp(const MyApp()); }
4. 修改按钮点击逻辑
将原有的showNotification调用替换为注册后台定时任务:
onPressed: () { setState(() { showToast(); // 注册每分钟执行一次的定时任务 Workmanager().registerPeriodicTask( 'random_notification_task', // 任务唯一标识 'random_notification', // 任务名称 frequency: const Duration(minutes: 1), // 重复间隔 inputData: { 'names': names, // 传递名称列表到后台 'userPost': widget.userPost, // 传递用户内容 }, existingWorkPolicy: ExistingWorkPolicy.replace, // 替换已有同名任务 ); }); },
5. 平台权限配置
Android端
在android/app/src/main/AndroidManifest.xml中添加权限和服务配置:
<!-- 添加权限 --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> <application ...> <!-- 禁用WorkManager自动初始化 --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="androidx.work.WorkManagerInitializer" android:value="androidx.startup" tools:node="remove"/> </provider> <!-- 注册WorkManager服务 --> <service android:name="be.tramckrijte.workmanager.BackgroundWorker" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="false"/> </application>
iOS端
在ios/Runner/Info.plist中添加后台模式权限:
<key>UIBackgroundModes</key> <array> <string>fetch</string> <string>remote-notification</string> </array>
原理说明
原方法中periodicallyShow是将通知内容预先传给系统,系统按固定间隔重复发送相同内容;而改用后台任务后,每次间隔到期时,系统会唤醒Dart代码执行回调,动态生成新的随机内容再展示通知,从而实现每次通知内容自动更新。
内容的提问来源于stack exchange,提问作者Marian
相关产品推荐
相关产品推荐

