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

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;
}
}
}