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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:40:41