You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
4.3 KiB
147 lines
4.3 KiB
import 'dart:io';
|
|
import 'package:get/get.dart';
|
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
import 'package:device_info_plus/device_info_plus.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
import '../providers/agent_provider.dart';
|
|
|
|
class NotificationService extends GetxService {
|
|
static NotificationService get to => Get.find();
|
|
|
|
final FlutterLocalNotificationsPlugin _notificationsPlugin = FlutterLocalNotificationsPlugin();
|
|
bool _notificationActive = false;
|
|
bool _isRequestingPermission = false;
|
|
|
|
String get _defaultAgentName {
|
|
final agent = AgentProvider.getAgentById('personal_assistant');
|
|
return agent?.name ?? 'Deep Voice';
|
|
}
|
|
|
|
Future<void> init() async {
|
|
const androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
|
|
const iosSettings = DarwinInitializationSettings(
|
|
requestAlertPermission: false, // 初始化时不请求权限
|
|
requestBadgePermission: false,
|
|
requestSoundPermission: false,
|
|
);
|
|
|
|
const initSettings = InitializationSettings(
|
|
android: androidSettings,
|
|
iOS: iosSettings,
|
|
);
|
|
|
|
await _notificationsPlugin.initialize(
|
|
initSettings,
|
|
onDidReceiveNotificationResponse: (details) {
|
|
if (Get.currentRoute != '/chat') {
|
|
Get.toNamed('/chat');
|
|
}
|
|
},
|
|
);
|
|
|
|
// 创建通知渠道
|
|
if (Platform.isAndroid) {
|
|
await _notificationsPlugin.resolvePlatformSpecificImplementation<
|
|
AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel(
|
|
const AndroidNotificationChannel(
|
|
'foreground_service', // id
|
|
'Foreground Service', // name
|
|
description: 'Used for the foreground service notification', // description
|
|
importance: Importance.min,
|
|
playSound: false,
|
|
enableVibration: false,
|
|
showBadge: false,
|
|
),
|
|
);
|
|
}
|
|
|
|
await _requestPermissionIfNeeded();
|
|
|
|
// 在初始化完成后显示前台服务通知
|
|
await showForegroundNotification();
|
|
}
|
|
|
|
Future<void> showForegroundNotification() async {
|
|
if (_notificationActive) return;
|
|
|
|
// 在显示通知前确保有权限
|
|
await _requestPermissionIfNeeded();
|
|
|
|
final androidDetails = AndroidNotificationDetails(
|
|
'foreground_service',
|
|
'Foreground Service',
|
|
channelDescription: 'Used for the foreground service notification',
|
|
importance: Importance.min,
|
|
priority: Priority.min,
|
|
ongoing: true,
|
|
autoCancel: false,
|
|
showWhen: false,
|
|
enableVibration: false,
|
|
playSound: false,
|
|
icon: '@mipmap/ic_launcher',
|
|
category: AndroidNotificationCategory.service,
|
|
actions: [
|
|
const AndroidNotificationAction(
|
|
'chat',
|
|
'开始对话',
|
|
showsUserInterface: true,
|
|
),
|
|
],
|
|
);
|
|
|
|
const iosDetails = DarwinNotificationDetails(
|
|
presentAlert: false,
|
|
presentBadge: false,
|
|
presentSound: false,
|
|
interruptionLevel: InterruptionLevel.passive,
|
|
);
|
|
|
|
final notificationDetails = NotificationDetails(
|
|
android: androidDetails,
|
|
iOS: iosDetails,
|
|
);
|
|
|
|
await _notificationsPlugin.show(
|
|
0,
|
|
_defaultAgentName,
|
|
'点击开始对话',
|
|
notificationDetails,
|
|
);
|
|
|
|
_notificationActive = true;
|
|
}
|
|
|
|
Future<void> cancelNotification() async {
|
|
if (!_notificationActive) return;
|
|
await _notificationsPlugin.cancel(0);
|
|
_notificationActive = false;
|
|
}
|
|
|
|
Future<void> _requestPermissionIfNeeded() async {
|
|
if (_isRequestingPermission) return;
|
|
_isRequestingPermission = true;
|
|
|
|
try {
|
|
if (Platform.isAndroid) {
|
|
final androidInfo = await DeviceInfoPlugin().androidInfo;
|
|
if (androidInfo.version.sdkInt >= 33) {
|
|
final status = await Permission.notification.status;
|
|
if (status.isDenied) {
|
|
await Permission.notification.request();
|
|
}
|
|
}
|
|
} else if (Platform.isIOS) {
|
|
await _notificationsPlugin
|
|
.resolvePlatformSpecificImplementation<
|
|
IOSFlutterLocalNotificationsPlugin>()
|
|
?.requestPermissions(
|
|
alert: true,
|
|
badge: true,
|
|
sound: true,
|
|
);
|
|
}
|
|
} finally {
|
|
_isRequestingPermission = false;
|
|
}
|
|
}
|
|
}
|