前言
相比于workmanager,firebase_messaging更成熟,用的更多,不过 workmanager 实现简单一点,适合快速开发的小任务。
workmanager 的使用
先设置好 callbackDispatcher 和 Workmanager().executeTask 来执行任务,在具体位置调用 Workmanager().registerOneOffTask 来触发事件。
流程
通过 Workmanager().initialize() 启动,使用 Workmanager().registerOneOffTask() 或 Workmanager().registerPeriodicTask() 注册任务。
方法
本地推送可使用 workmanager,但可能由于系统限制导致功能不稳定,比如在 ios 系统用 workmanager 就不稳定。firebase_messaging更成熟,用的人多,更稳定。也可以修改平台原生代码,以 ios 为例,修改 flutter 项目中的 swift 文件。
代码示例
// 注册后台任务。这个函数用在触发通知的位置。
void triggerErrorMessage(String dn) {
if (Platform.isAndroid) {
if (kDebugMode) {
print("是安卓系统");
}
Workmanager().registerOneOffTask(
"notification_task", // taskId
"notification_task", // taskName
inputData: {
'channelName': '后台通知', // 通知的渠道名称
'id': '0', // 唯一ID
'title': '后台通知', // 通知标题
'body': '后台通知的内容', // 通知内容
},
);
} else if (Platform.isIOS) {
if (kDebugMode) {
print("是ios系统");
}
Workmanager().registerOneOffTask(
"notification_task", // 这里是taskName,与安卓系统的有区别,下面一行的参数意义还不确定
"notification_task",
inputData: {
'channelName': '后台通知',
'id': '1',
'title': '后台通知',
'body': '后台通知的内容',
},
);
}
}
// 在应用启动的 main() 中要初始化插件 workmanager
Workmanager().initialize(
callbackDispatcher, // 后台任务回调函数
isInDebugMode: true, // 调试模式。为 true 的话会默认创建一个通知渠道(安卓系统)
);
// 执行后台任务。
@pragma('vm:entry-point')
void callbackDispatcher() {
Workmanager().executeTask((taskName, inputData) async {
try {
switch (taskName) {
case 'notification_task':
final String title = inputData?['title'];
final String body = inputData?['body'];
final String channelName = inputData?['channelName'];
final String id = inputData?['id'];
if (Platform.isIOS) {
await _handleIOSNotification(title, body, id);
} else if (Platform.isAndroid) {
await _handleAndroidNotification(title, body, id);
}
break;
default:
if (kDebugMode) {
print('未知任务: $taskName');
}
}
} catch (e, s) {
if (kDebugMode) {
print('在执行后台任务时发生异常: $e');
print('堆栈跟踪: $s');
}
// 返回 false 表示任务失败
return Future.value(false);
}
return Future.value(true);
});
}
// IOS 通知处理
Future<void> _handleIOSNotification(
String title, String body, int id) async {
try {
// iOS需要在主isolate中初始化,这里尝试重新初始化
const DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false,
);
// 创建插件实例
final FlutterLocalNotificationsPlugin notificationsPlugin =
FlutterLocalNotificationsPlugin();
// iOS 通知详情
const DarwinNotificationDetails iOSPlatformChannelSpecifics =
DarwinNotificationDetails(
presentAlert: true,
presentBadge: true,
presentSound: true,
);
// 创建通知详情
const NotificationDetails platformDetails = NotificationDetails(
iOS: iOSPlatformChannelSpecifics,
);
// 显示通知
await notificationsPlugin.show(
id,
title,
body,
platformDetails,
payload: "message"
);
} catch (e) {
if (kDebugMode) {
print('iOS 通知发送失败: $e');
}
}
}
// Android 通知处理
Future<void> _handleAndroidNotification(
String title, String body, int id) async {
try {
// 直接在这个隔离里初始化通知插件
const AndroidInitializationSettings
initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
const InitializationSettings initializationSettings =
InitializationSettings(
android: initializationSettingsAndroid);
final FlutterLocalNotificationsPlugin notificationsPlugin =
FlutterLocalNotificationsPlugin();
// 初始化通道
await notificationsPlugin.initialize(initializationSettings);
// 创建通知详情
const AndroidNotificationDetails androidDetails =
AndroidNotificationDetails(
'后台通知', // channelId
'后台通知', // channelName
importance: Importance.max,
priority: Priority.max,
fullScreenIntent: true,
);
const NotificationDetails platformDetails =
NotificationDetails(android: androidDetails);
// 使用当前隔离初始化的插件显示通知
await notificationsPlugin.show(
id,
title,
body,
platformDetails,
payload: "message",
);
} catch (e) {
if (kDebugMode) {
print('iOS 通知发送失败: $e');
}
}
}
928

被折叠的 条评论
为什么被折叠?



