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

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为例:

  1. 先按照官方文档完成插件的依赖添加与AndroidManifest配置
  2. 在后台任务里生成随机描述并发送通知:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:27:31