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

Flutter实现定时推送随机本地文章提醒通知方案咨询

实现每日定时推送随机文章通知的具体方案

针对你的需求,结合flutter_local_notifications+flutter_workmanager(或Awesome_notifications+flutter_workmanager)可以实现稳定的每日定时推送,以下是分步实现细节:


一、核心依赖配置

首先在pubspec.yaml中添加所需依赖:

dependencies:
  flutter_local_notifications: ^16.1.0 # 替换为最新版本
  flutter_workmanager: ^0.5.1 # 用于后台定时任务调度
  # 你的本地存储包(如hive、sqflite,已实现文章存储可忽略)

如果偏好使用Awesome_notifications,替换flutter_local_notifications为:

awesome_notifications: ^0.7.5 # 替换为最新版本

二、基于flutter_local_notifications的实现步骤

1. 初始化通知插件

在App启动时完成插件初始化,同时配置点击通知后的跳转逻辑:

import 'package:flutter_local_notifications/flutter_local_notifications.dart';

final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin();

void initNotifications() async {
  // 安卓初始化配置
  const AndroidInitializationSettings androidSettings =
      AndroidInitializationSettings('@mipmap/ic_launcher');
  // iOS初始化配置
  const DarwinInitializationSettings iosSettings = DarwinInitializationSettings(
    requestAlertPermission: true,
    requestBadgePermission: true,
    requestSoundPermission: true,
  );
  const InitializationSettings initSettings = InitializationSettings(
    android: androidSettings,
    iOS: iosSettings,
  );

  // 初始化并绑定点击回调
  await _notificationsPlugin.initialize(initSettings,
      onDidReceiveNotificationResponse: (NotificationResponse response) {
    // 点击通知后跳转至文章详情页
    if (response.payload != null) {
      // 替换为你的路由跳转逻辑,例如:
      // Navigator.push(context, MaterialPageRoute(
      //   builder: (context) => ArticleDetailPage(id: response.payload!)
      // ));
    }
  });
}

2. 配置后台定时任务

使用flutter_workmanager注册每日8点、20点的周期性任务,确保App在后台也能触发通知:

import 'package:flutter_workmanager/flutter_workmanager.dart';
import 'dart:math';

void initWorkManager() {
  FlutterWorkmanager().initialize(
    _taskCallback, // 后台任务执行逻辑
    isInDebugMode: false,
  );

  // 注册每日定时任务
  FlutterWorkmanager().registerPeriodicTask(
    'daily_article_reminder',
    'fetch_random_article',
    frequency: const Duration(days: 1),
    initialDelay: _getInitialDelay(), // 计算首次触发的延迟时间
    constraints: const Constraints(networkType: NetworkType.not_required),
  );
}

// 计算距离下一个8点/20点的延迟时长
Duration _getInitialDelay() {
  final now = DateTime.now();
  final next8 = DateTime(now.year, now.month, now.day, 8);
  final next20 = DateTime(now.year, now.month, now.day, 20);

  if (now.isBefore(next8)) return next8.difference(now);
  if (now.isBefore(next20)) return next20.difference(now);
  // 当天已过20点,延迟至次日8点
  return next8.add(const Duration(days: 1)).difference(now);
}

// 后台任务逻辑:获取随机文章并推送通知
void _taskCallback() async {
  FlutterWorkmanager().executeTask((task, inputData) async {
    // 从本地存储获取文章列表(替换为你的实际获取逻辑)
    final articles = await _getLocalArticles();
    if (articles.isNotEmpty) {
      final randomArticle = articles[Random().nextInt(articles.length)];
      await _pushNotification(randomArticle);
    }
    return Future.value(true);
  });
}

// 发送通知的具体实现
Future<void> _pushNotification(Article article) async {
  const AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
    'article_reminder_channel',
    '文章提醒',
    channelDescription: '每日推送随机文章',
    importance: Importance.max,
    priority: Priority.high,
  );
  const DarwinNotificationDetails iosDetails = DarwinNotificationDetails();
  const NotificationDetails notificationDetails = NotificationDetails(
    android: androidDetails,
    iOS: iosDetails,
  );

  await _notificationsPlugin.show(
    0,
    '该读文章啦',
    article.title,
    notificationDetails,
    payload: article.id.toString(), // 携带文章ID用于跳转
  );
}

3. 系统权限配置

  • Android:在AndroidManifest.xml中添加权限与组件配置:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

<application ...>
  <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
  <receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
      <intent-filter>
          <action android:name="android.intent.action.BOOT_COMPLETED"/>
          <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
      </intent-filter>
  </receiver>
  <service android:name="com.dexterous.flutterlocalnotifications.ForegroundService" />
</application>
  • iOS:在Info.plist中添加后台模式与权限描述:
<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
    <string>processing</string>
</array>
<key>NSLocalNotificationUsageDescription</key>
<string>需要推送文章提醒通知</string>

可选:基于Awesome_notifications的实现

如果偏好使用Awesome_notifications,核心逻辑如下:

import 'package:awesome_notifications/awesome_notifications.dart';
import 'dart:math';

void initAwesomeNotifications() async {
  await AwesomeNotifications().initialize(
    'resource://drawable/ic_launcher',
    [
      NotificationChannel(
        channelKey: 'article_reminder',
        channelName: '文章提醒',
        channelDescription: '每日推送随机文章',
        importance: NotificationImportance.High,
      )
    ],
  );
  // 请求推送权限
  await AwesomeNotifications().requestPermissionToSendNotifications();

  // 绑定点击通知回调
  AwesomeNotifications().setListeners(
    onActionReceivedMethod: (ReceivedAction action) {
      if (action.payload?['articleId'] != null) {
        // 跳转至文章详情页
      }
    },
  );
}

// 后台任务中调用此方法发送通知
Future<void> _pushAwesomeNotification(Article article) async {
  await AwesomeNotifications().createNotification(
    content: NotificationContent(
      id: 1,
      channelKey: 'article_reminder',
      title: '该读文章啦',
      body: article.title,
      payload: {'articleId': article.id.toString()},
    ),
  );
}

注:无论使用哪个通知插件,后台定时触发的核心都依赖flutter_workmanager,单纯的通知插件无法在App完全退出后保持定时调度。


关键注意事项

  1. 本地文章列表的获取逻辑需确保在后台环境中可正常运行(例如Hive需提前初始化)。
  2. iOS后台定时任务受系统限制,无法保证精确触发;安卓需引导用户关闭App的电池优化,避免任务被杀死。
  3. 测试阶段可将任务频率改为Duration(minutes: 1),快速验证功能是否正常。

内容的提问来源于stack exchange,提问作者Elijah Loola

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:13:15