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

Flutter中Awesome Notification iOS问题:前台重复通知,后台仅显示一次

解决iOS后台重复通知问题的方案

问题根源

  • iOS后台对Timer有严格限制,App进入后台后Timer会被系统暂停,无法按周期触发。
  • 每次创建通知都使用同一个id,iOS会直接覆盖已有通知,不会重复弹出提醒。
  • 未申请对应后台权限,无法维持后台定时能力。

具体修复步骤

1. 配置iOS后台权限

在项目的Info.plist中添加后台模式权限,闹钟类App建议同时开启音频和后台处理权限:

<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
    <string>processing</string>
</array>

2. 确保通知ID唯一

每次创建通知时生成唯一ID,避免被系统覆盖,可在原subId基础上拼接时间戳:

int uniqueId = subId! + DateTime.now().millisecondsSinceEpoch ~/ 1000;

3. 用系统级调度替代Timer

不要依赖后台Timer,改用AwesomeNotifications自带的调度功能,直接创建重复通知:

await AwesomeNotifications().createNotification(
  content: NotificationContent(
    criticalAlert: true,
    displayOnBackground: true,
    displayOnForeground: true,
    fullScreenIntent: true,
    id: uniqueId, // 使用生成的唯一ID
    channelKey: "alarm_Category",
    title: 'Alarm Reminder',
    body: 'Your alarm is still active!',
    autoDismissible: false,
    payload: receivedNotification.payload,
  ),
  schedule: NotificationInterval(
    interval: 7, // 重复间隔7秒
    timeZone: await AwesomeNotifications().getLocalTimeZoneIdentifier(),
    repeats: true, // 开启重复
  ),
);

4. 用户点击后终止重复

在onActionReceivedMethod中取消对应闹钟的重复调度,避免用户处理后仍继续发送通知:

static Future<void> onActionReceivedMethod(ReceivedAction receivedAction) async {
  String? subIdStr = receivedAction.payload?['subId'];
  if (subIdStr != null) {
    // 取消该闹钟的所有重复调度
    await AwesomeNotifications().cancelSchedulesByKey(subIdStr);
    // 同时清除已显示的通知
    await AwesomeNotifications().cancel(int.parse(subIdStr));
  }
}

关键注意事项

  • iOS后台资源限制严格,即使配置权限,系统也可能在资源紧张时终止App,建议保留criticalAlert和fullScreenIntent提升通知优先级。
  • 务必使用唯一通知ID,否则后台通知会被直接覆盖,无法重复弹出。
  • 优先使用系统级调度功能,而非手动维护Timer,更适配iOS后台运行规则。

内容的提问来源于stack exchange,提问作者Thomas lee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 12:07:13