Flutter(Dart)中如何实现满足条件的周期性本地通知?
可行:实现带前置条件的周期性本地通知
你的需求完全可以实现,核心思路是将“定时发通知”拆解为“定时触发条件校验任务,满足条件再推送通知”,无需依赖外部推送服务,仅通过本地工具即可完成。
具体实现方案
结合flutter_local_notifications和本地后台任务调度库(比如workmanager,纯本地实现,无外部依赖),步骤如下:
调度周期性后台任务
用后台任务库每天固定时间(比如清晨)触发一个校验任务,而非直接调度通知。这个任务会在后台执行,无需用户打开App。任务内执行条件校验
在后台任务中完成业务逻辑校验(比如调用天气API查询当日是否有雨,或读取本地缓存的天气数据)。满足条件时推送通知
如果校验通过,直接调用flutter_local_notifications的show方法推送提醒;不满足则跳过,等待下一次任务触发。
代码示例
import 'package:flutter/material.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:workmanager/workmanager.dart'; // 后台任务回调 void callbackDispatcher() { Workmanager().executeTask((task, inputData) async { // 1. 执行条件校验:示例为查询当日是否有雨 bool hasRain = await _checkTodayHasRain(); if (hasRain) { // 2. 满足条件,推送通知 final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); await flutterLocalNotificationsPlugin.show( 0, "带伞提醒", "今日有雨,记得带伞出门!", const NotificationDetails( android: AndroidNotificationDetails( 'weather_reminder_channel', '天气提醒', importance: Importance.max, priority: Priority.high, ), ), ); } return Future.value(true); }); } // 自定义天气校验方法(示例) Future<bool> _checkTodayHasRain() async { // 替换为实际的天气查询逻辑:调用API或读取本地缓存 return Future.value(true); // 示例模拟有雨 } void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化本地通知插件 final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); const androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const initSettings = InitializationSettings(android: androidInit); await flutterLocalNotificationsPlugin.initialize(initSettings); // 初始化后台任务 Workmanager().initialize(callbackDispatcher, isInDebugMode: false); // 注册每日清晨7点的周期性任务 await Workmanager().registerPeriodicTask( 'daily_weather_check', 'weather_reminder_task', frequency: const Duration(days: 1), // 计算距离下一个7点的延迟,确保首次触发时间正确 initialDelay: Duration( hours: 7 - DateTime.now().hour, minutes: -DateTime.now().minute, seconds: -DateTime.now().second, ), // 如需联网查天气,添加网络约束 constraints: const Constraints(networkType: NetworkType.connected), ); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold(appBar: AppBar(title: const Text("带伞提醒Demo"))), ); } }
注意事项
- 安卓权限配置:需要在
AndroidManifest.xml中添加RECEIVE_BOOT_COMPLETED权限,确保设备重启后任务仍能执行;同时配置后台任务的权限声明。 - iOS后台限制:iOS对后台任务的限制较严格,需要在
Info.plist中开启Background fetch模式,且后台任务的执行时间和频率可能受系统管控。 - 数据获取优化:如果需要联网查询数据,建议提前缓存结果(比如前一天晚上),避免后台任务因网络问题失败。
内容的提问来源于stack exchange,提问作者Omer
相关产品推荐
相关产品推荐

