149 lines
4.2 KiB
Dart
149 lines
4.2 KiB
Dart
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||
import 'package:timezone/data/latest_all.dart' as tz;
|
||
import 'package:timezone/timezone.dart' as tz;
|
||
|
||
class NotifyService {
|
||
static final NotifyService _instance = NotifyService._internal();
|
||
|
||
factory NotifyService() => _instance;
|
||
|
||
NotifyService._internal();
|
||
|
||
late FlutterLocalNotificationsPlugin _notifications;
|
||
|
||
// 使用绝对时间(而不是相对时间),避免时区转换问题。
|
||
final dateInterpretation = UILocalNotificationDateInterpretation.absoluteTime;
|
||
|
||
// Android特殊模式,即使设备处于省电模式也能准时触发。
|
||
final scheduleMode = AndroidScheduleMode.exactAllowWhileIdle;
|
||
|
||
// 初始化通知服务
|
||
Future<void> initialize() async {
|
||
_notifications = FlutterLocalNotificationsPlugin();
|
||
|
||
// 初始化时区
|
||
tz.initializeTimeZones();
|
||
// String timeZoneName = await FlutterNativeTimezone.getLocalTimezone();
|
||
tz.setLocalLocation(tz.getLocation("Asia/Shanghai"));
|
||
|
||
// 设置Android平台的初始化配置 使用应用图标作为通知图标
|
||
const AndroidInitializationSettings androidSettings =
|
||
AndroidInitializationSettings('@mipmap/ic_launcher');
|
||
|
||
// 设置iOS平台的初始化配置
|
||
const DarwinInitializationSettings iosSettings =
|
||
DarwinInitializationSettings(
|
||
requestAlertPermission: true,
|
||
requestBadgePermission: true,
|
||
requestSoundPermission: true,
|
||
);
|
||
|
||
// 初始化设置
|
||
const InitializationSettings settings = InitializationSettings(
|
||
android: androidSettings,
|
||
iOS: iosSettings,
|
||
);
|
||
|
||
await _notifications.initialize(settings);
|
||
}
|
||
|
||
// 创建Android通知详情
|
||
AndroidNotificationDetails _androidNotificationDetails() {
|
||
const channelId = 'com.cxx.flisp_app';
|
||
const channelName = '闪灵';
|
||
const channelDescription = '闪灵通知';
|
||
return const AndroidNotificationDetails(
|
||
channelId,
|
||
channelName,
|
||
channelDescription: channelDescription,
|
||
importance: Importance.high,
|
||
priority: Priority.high,
|
||
playSound: true,
|
||
enableVibration: true,
|
||
);
|
||
}
|
||
|
||
// 创建iOS通知详情
|
||
DarwinNotificationDetails _iosNotificationDetails() {
|
||
return const DarwinNotificationDetails(
|
||
presentAlert: true,
|
||
presentBadge: true,
|
||
presentSound: true,
|
||
);
|
||
}
|
||
|
||
NotificationDetails get _details {
|
||
return NotificationDetails(
|
||
android: _androidNotificationDetails(),
|
||
iOS: _iosNotificationDetails(),
|
||
);
|
||
}
|
||
|
||
// 立即显示通知
|
||
Future<void> showInstantNotification({
|
||
required String title,
|
||
required String body,
|
||
int id = 0,
|
||
}) async {
|
||
await _notifications.show(id, title, body, _details);
|
||
}
|
||
|
||
// 安排定时通知
|
||
Future<void> scheduleNotification({
|
||
required int id,
|
||
required String title,
|
||
required String body,
|
||
required DateTime scheduledTime,
|
||
}) async {
|
||
await _notifications.zonedSchedule(
|
||
id,
|
||
title,
|
||
body,
|
||
tz.TZDateTime.from(scheduledTime, tz.local),
|
||
_details,
|
||
uiLocalNotificationDateInterpretation:
|
||
UILocalNotificationDateInterpretation.absoluteTime,
|
||
androidScheduleMode: AndroidScheduleMode.exactAllowWhileIdle,
|
||
);
|
||
}
|
||
|
||
// 取消特定通知
|
||
Future<void> cancelNotification(int id) async {
|
||
try {
|
||
await _notifications.cancel(id);
|
||
} catch(e) {
|
||
print('取消通知失败: $e');
|
||
}
|
||
}
|
||
|
||
// 取消所有通知
|
||
Future<void> cancelAllNotifications() async {
|
||
await _notifications.cancelAll();
|
||
}
|
||
|
||
// 检查通知权限
|
||
Future<bool> checkPermission() async {
|
||
final bool? result =
|
||
await _notifications
|
||
.resolvePlatformSpecificImplementation<
|
||
AndroidFlutterLocalNotificationsPlugin
|
||
>()
|
||
?.areNotificationsEnabled();
|
||
return result ?? false;
|
||
}
|
||
|
||
// 请求权限
|
||
Future<void> requestPermission() async {
|
||
await _notifications
|
||
.resolvePlatformSpecificImplementation<
|
||
IOSFlutterLocalNotificationsPlugin
|
||
>()
|
||
?.requestPermissions(alert: true, badge: true, sound: true);
|
||
}
|
||
|
||
// 获取所有待处理的通知
|
||
Future<List<PendingNotificationRequest>> getPendingNotifications() async {
|
||
return await _notifications.pendingNotificationRequests();
|
||
}
|
||
}
|