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'; import 'package:flutter/foundation.dart'; class NotificationService extends GetxService { static NotificationService get to => Get.find(); FlutterLocalNotificationsPlugin? _flutterLocalNotificationsPlugin; bool _notificationActive = false; bool _isRequestingPermission = false; String get _defaultAgentName { final agent = AgentProvider.getAgentById('personal_assistant'); return agent?.name ?? 'Deep Voice'; } Future init() async { if (Platform.isIOS || Platform.isAndroid || Platform.isMacOS) { _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); const initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher'); final initializationSettingsDarwin = DarwinInitializationSettings( requestSoundPermission: false, requestBadgePermission: false, requestAlertPermission: false, ); final initializationSettings = InitializationSettings( android: initializationSettingsAndroid, iOS: initializationSettingsDarwin, macOS: initializationSettingsDarwin, ); await _flutterLocalNotificationsPlugin?.initialize( initializationSettings, onDidReceiveNotificationResponse: (details) { if (Get.currentRoute != '/chat') { Get.toNamed('/chat'); } }, ); } // 创建通知渠道 if (Platform.isAndroid) { await _flutterLocalNotificationsPlugin?.resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel( const AndroidNotificationChannel( 'foreground_service', 'Foreground Service', description: 'Used for the foreground service notification', importance: Importance.min, playSound: false, enableVibration: false, showBadge: false, ), ); } await _requestPermissionIfNeeded(); // 在初始化完成后显示前台服务通知 if (Platform.isAndroid) { await showForegroundNotification(); } } Future 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 _flutterLocalNotificationsPlugin?.show( 0, _defaultAgentName, '点击开始对话', notificationDetails, ); _notificationActive = true; } Future cancelNotification() async { if (!_notificationActive) return; await _flutterLocalNotificationsPlugin?.cancel(0); _notificationActive = false; } Future _requestPermissionIfNeeded() async { if (Platform.isMacOS) { // On macOS, we don't need to request notification permissions through permission_handler // Instead, we'll use the flutter_local_notifications plugin directly final bool? granted = await _flutterLocalNotificationsPlugin ?.resolvePlatformSpecificImplementation() ?.requestPermissions( alert: true, badge: true, sound: true, ); if (granted != true) { debugPrint('MacOS Notifications: Permission request was denied'); } return; } // For other platforms, use permission_handler as before if (await Permission.notification.status != PermissionStatus.granted) { await Permission.notification.request(); } } Future showNotification({ required String title, required String body, }) async { if (_flutterLocalNotificationsPlugin == null) return; const androidDetails = AndroidNotificationDetails( 'chat_channel', '聊天消息', channelDescription: '接收新的聊天消息', importance: Importance.high, priority: Priority.high, ); const iosDetails = DarwinNotificationDetails( presentAlert: true, presentBadge: true, presentSound: true, ); const notificationDetails = NotificationDetails( android: androidDetails, iOS: iosDetails, ); await _flutterLocalNotificationsPlugin?.show( 0, title, body, notificationDetails, ); } }