Flutter应用关闭后,如何无Firebase获取API数据并展示在本地通知?
实现Flutter应用关闭后展示API数据本地通知(无Firebase依赖)
核心方案
直接通过flutter_workmanager实现后台定时拉取API数据,搭配flutter_local_notifications发送本地通知,两者无需依赖Firebase即可完成集成。
具体实现步骤
1. 添加依赖
在pubspec.yaml中引入两个插件:
dependencies: flutter_workmanager: ^0.5.1 # 可替换为最新稳定版本 flutter_local_notifications: ^16.1.0
执行flutter pub get完成依赖安装。
2. 原生端配置
Android端
打开android/app/src/main/AndroidManifest.xml,添加权限与WorkManager配置:
<!-- 必要权限 --> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.INTERNET"/> <!-- 在application标签内添加 --> <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> <service android:name="be.tramckrijte.workmanager.ForegroundService" android:foregroundServiceType="dataSync"/>
确保项目已启用AndroidX(Flutter新项目默认配置)。
iOS端
打开ios/Runner/Info.plist,添加后台模式权限:
<key>UIBackgroundModes</key> <array> <string>fetch</string> <string>processing</string> </array>
注意:iOS对后台任务限制严格,执行频率由系统调度,无法像Android那样精确控制。
3. 代码实现
在main.dart中完成插件初始化与业务逻辑编写:
import 'package:flutter/material.dart'; import 'package:flutter_workmanager/flutter_workmanager.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:http/http.dart' as http; import 'dart:convert'; FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); // 后台任务回调 void callbackDispatcher() { Workmanager().executeTask((task, inputData) async { try { // 拉取API数据 final response = await http.get(Uri.parse('你的API接口地址')); if (response.statusCode == 200) { final data = jsonDecode(response.body); String notifyContent = data['content']; // 根据API结构调整字段 // 发送本地通知 await _showNotification("API更新提醒", notifyContent); } return Future.value(true); } catch (e) { return Future.value(false); } }); } // 发送本地通知方法 Future<void> _showNotification(String title, String body) async { const AndroidNotificationDetails androidDetails = AndroidNotificationDetails( 'api_notify_channel', 'API更新通知', channelDescription: '展示API拉取的最新数据', importance: Importance.high, priority: Priority.high); const NotificationDetails notificationDetails = NotificationDetails(android: androidDetails); await flutterLocalNotificationsPlugin.show( 0, title, body, notificationDetails); } void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化本地通知 const AndroidInitializationSettings androidInit = AndroidInitializationSettings('@mipmap/ic_launcher'); const InitializationSettings initSettings = InitializationSettings(android: androidInit); await flutterLocalNotificationsPlugin.initialize(initSettings); // 初始化WorkManager await Workmanager().initialize( callbackDispatcher, isInDebugMode: false, // 发布版本设为false ); // 注册定期后台任务(Android最小间隔15分钟) await Workmanager().registerPeriodicTask( 'api_fetch_task', 'fetch_api', frequency: const Duration(minutes: 15), initialDelay: const Duration(minutes: 1), constraints: Constraints( networkType: NetworkType.connected, // 仅联网时执行 ), ); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: '后台通知示例', home: Scaffold( appBar: AppBar(title: const Text('后台通知示例')), body: const Center(child: Text('应用关闭后仍会拉取API并推送通知')), ), ); } }
4. 关键注意事项
- Android端:系统限制后台定期任务最小间隔为15分钟,若需更频繁执行,需使用前台服务(会显示持续通知)。
- iOS端:应用完全关闭(后台划掉)后,后台任务可能被系统终止,无法保证稳定执行。
- API请求需做好异常捕获,避免后台任务崩溃。
- Android 8.0及以上必须配置通知渠道,否则无法显示通知。
内容的提问来源于stack exchange,提问作者Ravi Kant Gupta
相关产品推荐
相关产品推荐

