Flutter每日随机描述通知异常:重复显示同文本问题求助
解决Flutter周期通知随机描述重复的问题 + 通知背景图实现
嘿,我来帮你搞定这两个问题!先说说为啥你的随机描述会重复,再给你可行的解决方案,最后聊聊通知背景图怎么加。
问题根源:periodicallyShow的“一次性生成”特性
你在initState里调用periodicallyShow时,随机描述是当时执行代码时生成的那唯一一次——flutter_local_notifications插件会把你传入的标题、描述等参数缓存起来,之后每次周期触发通知,只会直接复用这个缓存好的内容,不会重新跑一遍生成随机描述的逻辑。这就是为啥每次通知都一模一样。
解决方案:每次触发都重新生成内容
这里给你两种方案,根据你的需求选:
方案1:前台定时(适合APP在前台/后台但未被杀死时)
放弃periodicallyShow,改用Timer.periodic + 普通的show方法。这样每次定时器触发时,都会重新生成随机描述,再发送新的通知。
代码示例:
import 'dart:async'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; class YourPage extends StatefulWidget { @override State<YourPage> createState() => _YourPageState(); } class _YourPageState extends State<YourPage> { FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); Timer? _notificationTimer; // 你的随机描述生成方法 String getRandomDescription() { List<String> descriptions = [ "今天也要元气满满!", "记得多喝水哦~", "休息一下,活动活动肩膀吧!" ]; return descriptions[DateTime.now().millisecondsSinceEpoch % descriptions.length]; } @override void initState() { super.initState(); // 初始化通知插件(你的原有初始化代码) _initNotifications(); // 启动每分钟一次的定时器 _notificationTimer = Timer.periodic(const Duration(minutes: 1), (timer) async { String randomDesc = getRandomDescription(); await flutterLocalNotificationsPlugin.show( 0, // 通知ID,如果每次要替换旧通知可以用同一个ID,不然用不同ID "固定标题", randomDesc, const NotificationDetails( // 这里可以配置通知样式,后面说背景图 ), ); }); } @override void dispose() { // 页面销毁时取消定时器,避免内存泄漏 _notificationTimer?.cancel(); super.dispose(); } void _initNotifications() async { // 你的通知初始化逻辑(比如请求权限、配置渠道等) const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); const IOSInitializationSettings initializationSettingsIOS = IOSInitializationSettings(); const InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsIOS); await flutterLocalNotificationsPlugin.initialize(initializationSettings); } @override Widget build(BuildContext context) { return Scaffold(/* 你的页面UI */); } }
方案2:后台定时(适合APP被杀死后仍要触发)
如果需要APP完全退出后还能发送通知,Timer就不够用了,得用后台任务插件,比如workmanager(Android)或background_fetch(跨平台)。以workmanager为例:
- 先按照官方文档完成插件的依赖添加与AndroidManifest配置
- 在后台任务里生成随机描述并发送通知:
import 'package:workmanager/workmanager.dart'; void callbackDispatcher() { Workmanager().executeTask((task, inputData) async { FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // 后台环境需要重新初始化通知插件 const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid); await flutterLocalNotificationsPlugin.initialize(initializationSettings); // 生成随机描述 String randomDesc = getRandomDescription(); await flutterLocalNotificationsPlugin.show( 0, "固定标题", randomDesc, const NotificationDetails(), ); return Future.value(true); }); } // 在APP启动时初始化WorkManager void main() { Workmanager().initialize( callbackDispatcher, isInDebugMode: true, ); // 注册每分钟一次的后台任务 Workmanager().registerPeriodicTask( "notification-task", "notification-task-tag", frequency: const Duration(minutes: 1), ); runApp(const MyApp()); }
通知背景图实现
flutter_local_notifications支持给通知加背景图,Android和iOS的配置略有不同:
Android:用BigPictureStyle
AndroidNotificationDetails androidDetails = AndroidNotificationDetails( 'your_channel_id', 'your_channel_name', channelDescription: 'your_channel_desc', styleInformation: BigPictureStyleInformation( // 本地资源用AssetAndroidBitmap,网络图片需先下载到本地再用FilePathAndroidBitmap AssetAndroidBitmap('assets/notification_bg.png'), largeIcon: AssetAndroidBitmap('@mipmap/ic_launcher'), contentTitle: '固定标题', summaryText: randomDesc, ), ); NotificationDetails notificationDetails = NotificationDetails(android: androidDetails); await flutterLocalNotificationsPlugin.show(0, "固定标题", randomDesc, notificationDetails);
iOS:用Attachment
IOSNotificationDetails iosDetails = IOSNotificationDetails( attachments: [ IOSNotificationAttachment('assets/notification_bg.png'), // 本地资源路径,网络图片需下载到沙盒 ], ); NotificationDetails notificationDetails = NotificationDetails(iOS: iosDetails); await flutterLocalNotificationsPlugin.show(0, "固定标题", randomDesc, notificationDetails);
注意:如果使用网络图片,需要先下载到本地存储目录,再传入文件路径,不能直接传网络URL哦。
内容的提问来源于stack exchange,提问作者2Math0
相关产品推荐
相关产品推荐

