import 'dart:async'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import '../../data/models/appconfig.dart'; import 'package:get/get.dart'; import 'package:ble_service/ble_service.dart'; import '../../core/utils/logger.dart'; import 'package:get_storage/get_storage.dart'; import 'dart:convert'; import 'package:agent_service/agent_service.dart'; import 'bluetooth_manager.dart'; // 重新导出BLE连接状态常量,让外部可以通过BleManager访问 export 'package:ble_service/ble_service.dart' show BleConnectionState; /// 命令类型常量(与原生层保持一致) class BleCommands { static const int GET_VERSION = 0x01; static const int GET_PRODUCT_ID = 0x02; static const int GET_PRODUCT_COLOR = 0x03; static const int GET_BATTERY_INFO = 0x04; static const int CONTROL_CODEC = 0x05; } /// 蓝牙设备信息缓存模型 class DeviceInfo { final String address; final String name; // 整体电池电量 final int batteryLevel; // 详细电池信息 final int leftEarBattery; final int rightEarBattery; final int caseBattery; // 充电状态 final bool leftEarCharging; final bool rightEarCharging; final bool caseCharging; final String firmwareVersion; final String firmwareProductId; final String firmwareProductColor; final DateTime lastUpdated; DeviceInfo({ required this.address, required this.name, this.batteryLevel = 0, this.leftEarBattery = 0, this.rightEarBattery = 0, this.caseBattery = 0, this.leftEarCharging = false, this.rightEarCharging = false, this.caseCharging = false, this.firmwareVersion = '', this.firmwareProductId = '', this.firmwareProductColor = '', DateTime? lastUpdated, }) : lastUpdated = lastUpdated ?? DateTime.now(); /// 创建更新后的设备信息副本 DeviceInfo copyWith({ String? address, String? name, int? batteryLevel, int? leftEarBattery, int? rightEarBattery, int? caseBattery, bool? leftEarCharging, bool? rightEarCharging, bool? caseCharging, String? firmwareVersion, String? firmwareProductId, String? firmwareProductColor, }) { return DeviceInfo( address: address ?? this.address, name: name ?? this.name, batteryLevel: batteryLevel ?? this.batteryLevel, leftEarBattery: leftEarBattery ?? this.leftEarBattery, rightEarBattery: rightEarBattery ?? this.rightEarBattery, caseBattery: caseBattery ?? this.caseBattery, leftEarCharging: leftEarCharging ?? this.leftEarCharging, rightEarCharging: rightEarCharging ?? this.rightEarCharging, caseCharging: caseCharging ?? this.caseCharging, firmwareVersion: firmwareVersion ?? this.firmwareVersion, firmwareProductId: firmwareProductId ?? this.firmwareProductId, firmwareProductColor: firmwareProductColor ?? this.firmwareProductColor, lastUpdated: DateTime.now(), ); } @override String toString() { return 'DeviceInfo(address: $address, name: $name, ' 'battery: $batteryLevel%, L: $leftEarBattery%, R: $rightEarBattery%, Case: $caseBattery%, ' 'charging: L:$leftEarCharging, R:$rightEarCharging, C:$caseCharging, ' 'version: $firmwareVersion)'; } } /// BLE管理器 - 专门处理BLE设备连接和信息管理 class BleManager extends GetxService { static BleManager get to => Get.find(); // BLE服务实例 final BleService _bleService = BleService(); // 经典蓝牙实例 // 当前连接的设备信息 String? _currentDeviceAddress; String? _currentDeviceName; // BLE连接状态 final _connectionState = BleConnectionState.disconnected.obs; int get connectionState => _connectionState.value; // 公开的连接状态流,供外部监听 RxInt get connectionStateRx => _connectionState; // 连接状态监听 final _isConnected = false.obs; bool get isConnected => _isConnected.value; // 设备信息缓存 final deviceInfo = Rx(null); // 使用 Rx 包装 // 订阅 StreamSubscription? _statusSubscription; StreamSubscription? _dataSubscription; final GetStorage _storage = GetStorage(); /// 初始化 @override void onInit() { super.onInit(); Logger.info('BLE管理器初始化'); // 设置BLE事件监听 _setupBleListener(); } /// 释放资源 @override void onClose() { _statusSubscription?.cancel(); _dataSubscription?.cancel(); super.onClose(); } /// 设置BLE事件监听 void _setupBleListener() { _statusSubscription?.cancel(); _dataSubscription?.cancel(); try { // 监听BLE状态更新 _statusSubscription = _bleService.onStatusUpdated.listen( (event) { if (event is Map) { // 处理连接状态更新 if (event['type'] == 'connectionStateChanged') { final state = event['state'] as int; final oldState = _connectionState.value; _connectionState.value = state; Logger.d('BleManager', '🔄 BLE状态更新: $oldState → $state'); Logger.d('BleManager', '📡 通知监听器状态变化: ${_connectionState.value}'); // 连接状态转换 if (state == BleConnectionState.connected) { Logger.info('BLE设备已连接'); _isConnected.value = true; // 在连接成功后延迟 300 毫秒获取设备信息(可根据需要调整时间) Future.delayed(const Duration(milliseconds: 300), () { // 可选:检查是否仍处于连接状态 if (_isConnected.value) { // fetchDeviceInfo(); } }); } else if (state == BleConnectionState.disconnected || state == BleConnectionState.error) { Logger.info('BLE设备已断开或发生错误'); _isConnected.value = false; // 更新设备信息Add commentMore actions _updateDeviceInfoIfNeeded( batteryLevel: 0, leftEarBattery: 0, rightEarBattery: 0, caseBattery: 0, leftEarCharging: false, rightEarCharging: false, caseCharging: false, firmwareVersion: '', firmwareProductId: '', firmwareProductColor: '', ); // 断开连接时不清除设备信息,保留最后的电量信息 // 只有在需要完全清除设备时才重置信息 } } // 处理设备信息 _processDeviceInfo(event); } }, onError: (error) { Logger.error('BLE状态事件流错误: $error'); }, ); // 监听BLE数据流 } catch (e) { Logger.error('设置BLE事件监听器失败: ${e.toString()}'); } } /// 处理来自原生层的设备信息 void _processDeviceInfo(Map event) { try { // 检查是否是设备信息响应 if (event.containsKey('command') && event.containsKey('success')) { final bool success = event['success'] as bool; if (!success) { Logger.warning('设备命令执行失败: ${event['command']}'); return; } // 根据命令类型处理不同信息 final command = event['command']; if (command is int) { // 基于命令ID处理 _processDeviceInfoByCommandId(command, event); } else if (command is String) { // 基于命令名称处理 _processDeviceInfoByCommandName(command, event); } } } catch (e) { Logger.error('处理设备信息异常: ${e.toString()}'); } } /// 根据命令ID处理设备信息 void _processDeviceInfoByCommandId( int commandId, Map data) { switch (commandId) { case BleCommands.GET_VERSION: _updateVersionInfoFromData(data); break; case BleCommands.GET_PRODUCT_ID: _updateProductIdFromData(data); break; case BleCommands.GET_PRODUCT_COLOR: break; case BleCommands.GET_BATTERY_INFO: _updateBatteryInfoFromData(data); break; default: Logger.info('未处理的命令ID: $commandId'); } } /// 根据命令名称处理设备信息 void _processDeviceInfoByCommandName( String commandName, Map data) { switch (commandName) { case 'batteryInfo': _updateBatteryInfoFromData(data); break; case 'versionInfo': _updateVersionInfoFromData(data); break; case 'productId': _updateProductIdFromData(data); break; case 'productColor': break; default: Logger.info('未处理的命令名称: $commandName'); } } /// 更新电池信息 void _updateBatteryInfoFromData(Map data) { try { // 确保数据中包含电池信息 if (!data.containsKey('leftEarBattery') || !data.containsKey('rightEarBattery') || !data.containsKey('caseBattery')) { Logger.warning('电池信息数据不完整'); return; } // 提取电池信息 final int leftBattery = (data['leftEarBattery'] as int? ?? 0) > 100 ? 0 : (data['leftEarBattery'] as int? ?? 0); final int rightBattery = (data['rightEarBattery'] as int? ?? 0) > 100 ? 0 : (data['rightEarBattery'] as int? ?? 0); final int caseBattery = (data['caseBattery'] as int? ?? 0) > 100 ? 0 : (data['caseBattery'] as int? ?? 0); final bool leftCharging = data['leftEarCharging'] as bool? ?? false; final bool rightCharging = data['rightEarCharging'] as bool? ?? false; final bool caseCharging = data['caseCharging'] as bool? ?? false; // 获取整体电量(原生层使用左耳电量作为主要指示) final int overallBattery = data['batteryLevel'] as int? ?? leftBattery; // 更新设备信息 _updateDeviceInfoIfNeeded( batteryLevel: overallBattery, leftEarBattery: leftBattery, rightEarBattery: rightBattery, caseBattery: caseBattery, leftEarCharging: leftCharging, rightEarCharging: rightCharging, caseCharging: caseCharging, ); Logger.info( '设备电池信息已更新: 电量=$overallBattery%, 左耳=$leftBattery%, 右耳=$rightBattery%, 充电仓=$caseBattery%'); } catch (e) { Logger.error('更新电池信息失败: ${e.toString()}'); } } /// 更新版本信息 void _updateVersionInfoFromData(Map data) { try { // 确保数据中包含版本信息 if (!data.containsKey('version')) { Logger.warning('版本信息数据不完整'); return; } // 提取版本信息 final String version = data['version'] as String? ?? ''; // 更新设备信息 _updateDeviceInfoIfNeeded( firmwareVersion: version, ); Logger.info('设备版本信息已更新: 版本=$version'); } catch (e) { Logger.error('更新版本信息失败: ${e.toString()}'); } } /// 更新设备id void _updateProductIdFromData(Map data) { try { // 确保数据中包含版本信息 if (!data.containsKey('productId')) { Logger.warning('版本信息数据不完整'); return; } // 提取版本信息 final String productId = data['productId'] as String? ?? ''; // 更新设备信息 _updateDeviceInfoIfNeeded( firmwareProductId: productId, ); Logger.info('设备设备id已更新: 设备id=$productId'); } catch (e) { Logger.error('更新设备id失败: ${e.toString()}'); } } /// 更新设备信息(如果已存在设备) void _updateDeviceInfoIfNeeded({ int? batteryLevel, int? leftEarBattery, int? rightEarBattery, int? caseBattery, bool? leftEarCharging, bool? rightEarCharging, bool? caseCharging, String? firmwareVersion, String? firmwareProductId, String? firmwareProductColor, }) { // 如果设备信息已存在,则更新 if (deviceInfo.value != null) { deviceInfo.value = deviceInfo.value!.copyWith( batteryLevel: batteryLevel ?? deviceInfo.value?.batteryLevel, leftEarBattery: leftEarBattery ?? deviceInfo.value?.leftEarBattery, rightEarBattery: rightEarBattery ?? deviceInfo.value?.rightEarBattery, caseBattery: caseBattery ?? deviceInfo.value?.caseBattery, leftEarCharging: leftEarCharging ?? deviceInfo.value!.leftEarCharging, rightEarCharging: rightEarCharging ?? deviceInfo.value!.rightEarCharging, caseCharging: caseCharging ?? deviceInfo.value!.caseCharging, firmwareVersion: firmwareVersion ?? deviceInfo.value!.firmwareVersion, firmwareProductId: firmwareProductId ?? deviceInfo.value!.firmwareProductId, firmwareProductColor: firmwareProductColor ?? deviceInfo.value!.firmwareProductColor, ); } // 创建设备信息 // 如果设备信息不存在,但有地址和名称,则创建新的设备信息 else if (deviceInfo.value == null && _isConnected.value && (firmwareVersion != null || batteryLevel != null)) { // 使用保存的设备信息创建新的DeviceInfo对象 String deviceAddress = _currentDeviceAddress ?? ""; String deviceName = _currentDeviceName ?? ""; Logger.info('创建新的设备信息对象: address=$deviceAddress, name=$deviceName'); deviceInfo.value = DeviceInfo( address: deviceAddress, name: deviceName, batteryLevel: batteryLevel ?? 0, leftEarBattery: leftEarBattery ?? 0, rightEarBattery: rightEarBattery ?? 0, caseBattery: caseBattery ?? 0, leftEarCharging: leftEarCharging ?? false, rightEarCharging: rightEarCharging ?? false, caseCharging: caseCharging ?? false, firmwareVersion: firmwareVersion ?? '', firmwareProductId: firmwareProductId ?? '', firmwareProductColor: firmwareProductColor ?? '', ); } } /// 清除设备信息(用于完全断开连接或切换设备时) void clearDeviceInfo() { Logger.info('清除设备信息'); deviceInfo.value = null; _currentDeviceAddress = null; _currentDeviceName = null; } /// 连接成功后获取设备信息 Future fetchDeviceInfo() async { Logger.info('开始获取BLE设备详细信息'); try { // 确保设备信息对象存在 if (deviceInfo.value == null && _isConnected.value) { // 创建初始设备信息对象 String deviceAddress = _currentDeviceAddress ?? ""; String deviceName = _currentDeviceName ?? ""; Logger.info('初始化设备信息对象: address=$deviceAddress, name=$deviceName'); deviceInfo.value = DeviceInfo( address: deviceAddress, name: deviceName, batteryLevel: 0, leftEarBattery: 0, rightEarBattery: 0, caseBattery: 0, leftEarCharging: false, rightEarCharging: false, caseCharging: false, firmwareVersion: '', firmwareProductId: '', firmwareProductColor: '', ); } // 并行获取所有设备信息,不使用延迟 final results = await Future.wait([ _bleService.getBatteryInfo(), _bleService.getDeviceVersion(), _bleService.getProductId(), ]); Logger.info( '设备信息获取结果: 电池=${results[0]}, 版本=${results[1]}, 产品ID=${results[2]}'); if (!results[0]) { Logger.warning('电池信息获取指令发送失败'); } if (!results[1]) { Logger.warning('版本信息获取指令发送失败'); } if (!results[2]) { Logger.warning('产品ID获取指令发送失败'); } } catch (e) { Logger.error('获取BLE设备信息失败: ${e.toString()}'); } } /// 检查BLE连接状态 Future getConnectionState() async { try { final isConnected = await _bleService.isConnected(); _connectionState.value = isConnected ? BleConnectionState.connected : BleConnectionState.disconnected; _isConnected.value = isConnected; return _connectionState.value; } catch (e) { Logger.error('获取BLE连接状态失败: ${e.toString()}'); return BleConnectionState.error; } } /// 启动BLE服务 Future startAgentService() async { try { // 从.env文件直接读取环境变量 var serverurl = dotenv.env['SERVER_URL'] ?? ''; if (Get.locale?.countryCode != 'CN') { serverurl = dotenv.env['HW_SERVER_URL'] ?? ''; } var jsonString = _storage.read("logintoken"); Logger.info('启动BLE服务,serverurl: ${serverurl}'); // final azureSpeechRegion = dotenv.env['AZURE_SPEECH_REGION'] ?? 'eastasia'; // final openaiApiKey = dotenv.env['OPENAI_API_KEY'] ?? ''; // final openaiBaseUrl = // dotenv.env['OPENAI_BASE_URL'] ?? 'https://api.openai.com/v1'; // final openaiModel = dotenv.env['OPENAI_MODEL'] ?? 'gpt-3.5-turbo'; // 从Flutter资源包中加载.mcp.json // final mcpConfig = await rootBundle.loadString('.mcp.json'); // 验证JSON格式 // final jsonData = jsonDecode(mcpConfig); final azureSpeechKey = AppConfig.env('AZURE_SPEECH_KEY') ?? ''; final azureSpeechRegion = AppConfig.env('AZURE_SPEECH_REGION') ?? 'eastasia'; final openaiApiKey = AppConfig.env('OPENAI_API_KEY') ?? ''; final openaiBaseUrl = AppConfig.env('OPENAI_BASE_URL') ?? 'https://api.openai.com/v1'; final openaiModel = AppConfig.env('OPENAI_MODEL') ?? 'gpt-3.5-turbo'; final openaiModelMedia = AppConfig.env('OPENAI_API_VISION_MODEL') ?? 'doubao-1-5-vision-pro-32k-250115'; final openaiagentid = AppConfig.env('OPENAI_AGENT_ID') ?? 'personal_assistant'; final systemPrompt = AppConfig.agentsystemPrompt(openaiagentid); // 从Flutter资源包中加载.mcp.json final jsonData = AppConfig.mcpConfig(); // 根据APP语言动态配置语音识别语言 List supportedLanguages = []; try { // 使用 GetX 获取 APP 当前语言环境 (Locale) final appLocale = Get.locale; if (appLocale != null) { final lang = appLocale.languageCode; // e.g., 'en' final country = appLocale.countryCode; // e.g., 'US' // 构造 Azure SDK 需要的格式 (e.g., 'en-US') if (country != null && country.isNotEmpty) { supportedLanguages.add('$lang-$country'); } else { supportedLanguages.add(lang); // fallback only language code } } // 添加 en-US 作为备选 if (!supportedLanguages.contains('en-US')) { supportedLanguages.add('en-US'); } // 最终兜底 if (supportedLanguages.isEmpty) { supportedLanguages.add('en-US'); } Logger.info('动态配置语音识别语言: ${supportedLanguages.join(', ')}'); } catch (e) { Logger.error('获取APP语言配置失败,使用默认语言: $e'); supportedLanguages = ['zh-CN', 'en-US']; } final config = { // 语音代理配置参数 'azureSpeechKey': azureSpeechKey, 'azureSpeechRegion': azureSpeechRegion, 'openaiApiKey': openaiApiKey, 'openaiBaseUrl': openaiBaseUrl, 'openaiModel': openaiModel, 'openaivisionModel': openaiModelMedia, 'systemPrompt': systemPrompt, 'mcpServer': jsonEncode(jsonData), 'volcanoAppId': '2316081933', 'volcanoToken': 'mcJTh6OelBqU_L78lgGd77Nyrc_-5-En', 'serverurl': serverurl, 'usertoken': jsonString, 'supportedLanguages': supportedLanguages, }; // 记录日志(不记录敏感信息) Logger.info('启动BLE服务,配置参数键名: ${config}'); if (azureSpeechKey.isEmpty || openaiApiKey.isEmpty) { Logger.warning('缺少必要的API密钥,请检查.env文件配置'); // 检查.env中相关密钥是否存在 if (azureSpeechKey.isEmpty) { Logger.warning('AZURE_SPEECH_KEY未配置在.env文件中'); } if (openaiApiKey.isEmpty) { Logger.warning('OPENAI_API_KEY未配置在.env文件中'); } } final result = await AgentService.startAgentService(config); if (result) { Logger.info('BLE服务启动成功'); // 添加延迟以等待设备连接 await Future.delayed(const Duration(seconds: 2)); // 检查连接状态 final isConnected = await _bleService.isConnected(); if (isConnected) { _isConnected.value = true; _connectionState.value = BleConnectionState.connected; // 如果设备信息存在,则获取详细信息 if (deviceInfo.value != null) { // 获取详细设备信息 // fetchDeviceInfo(); } } } else { Logger.error('BLE服务启动失败'); } return result; } catch (e) { Logger.error('启动BLE服务失败: ${e.toString()}'); return false; } } /// 停止BLE服务 Future stopAgentService() async { try { final result = await AgentService.stopAgentService(); if (result) { Logger.info('BLE服务停止成功'); _isConnected.value = false; _connectionState.value = BleConnectionState.disconnected; // 停止服务时清除设备信息 clearDeviceInfo(); } else { Logger.error('BLE服务停止失败'); } return result; } catch (e) { Logger.error('停止BLE服务失败: ${e.toString()}'); return false; } } /// 获取电池电量 Future getBatteryLevel() async { try { return await _bleService.getBatteryLevel(); } catch (e) { Logger.error('获取电池电量失败: ${e.toString()}'); return 0; } } /// 主动获取电池信息 Future fetchBatteryInfo() async { try { return await _bleService.getBatteryInfo(); } catch (e) { Logger.error('获取电池信息失败: ${e.toString()}'); return false; } } /// 主动产品id Future getProductId() async { try { return await _bleService.getProductId(); } catch (e) { Logger.error('获取设备版本失败: ${e.toString()}'); return false; } } /// 主动获取设备版本信息 Future fetchDeviceVersion() async { try { return await _bleService.getDeviceVersion(); } catch (e) { Logger.error('获取设备版本失败: ${e.toString()}'); return false; } } /// 打开编码器 Future openEncoder() async { try { return await _bleService.openEncoder(); } catch (e) { Logger.error('打开编码器失败: ${e.toString()}'); return false; } } /// 打开解码器 Future openDecoder() async { try { return await _bleService.openDecoder(); } catch (e) { Logger.error('打开解码器失败: ${e.toString()}'); return false; } } /// 打开解码器 Future openA2DPDecoder() async { try { return await _bleService.openA2DPDecoder(); } catch (e) { Logger.error('打开解码器失败: ${e.toString()}'); return false; } } /// 关闭编解码器 Future closeCodec() async { try { return await _bleService.closeCodec(); } catch (e) { Logger.error('关闭编解码器失败: ${e.toString()}'); return false; } } /// 播放A2DP Future playA2DP() async { try { return await _bleService.playA2DP(); } catch (e) { Logger.error('播放A2DP失败: ${e.toString()}'); return false; } } // ==================== 配对相关方法 ==================== /// 检查设备是否支持Companion Device Manager Future isCompanionSupported() async { try { return await _bleService.isCompanionSupported(); } catch (e) { Logger.error('检查Companion支持失败: ${e.toString()}'); return false; } } /// 获取已配对的MAC地址 Future getPairedMacAddress() async { try { return await _bleService.getPairedMacAddress(); } catch (e) { Logger.error('获取已配对MAC地址失败: ${e.toString()}'); return null; } } /// 检查BLE连接状态 Future isBleConnected() async { try { return await _bleService.isBleConnected(); } catch (e) { Logger.error('检查BLE连接状态失败: ${e.toString()}'); return false; } } /// 设置是否是ota模式 Future setEnterOta(bool enterOta) async { try { await _bleService.setEnterOta(enterOta); } catch (e) { Logger.error('设置是否是ota模式失败: ${e.toString()}'); } } /// 断开连接 Future disconnect() async { try { await _bleService.disconnect(); } catch (e) { Logger.error('断开连接失败: ${e.toString()}'); } } /// 验证设备是否可以配对 Future startScan(String devicename) async { try { await _bleService.startScan(devicename); } catch (e) { Logger.error('开始扫描设备: ${e.toString()}'); } } /// 验证设备是否可以配对 Future stopScan() async { try { await _bleService.stopScan(); } catch (e) { Logger.error('停止扫描设备: ${e.toString()}'); } } Future?> getDeviceInfo(String deviceName) async { try { final result = _bleService.getDeviceInfo(deviceName); return result; } catch (e) { Logger.error('获取设备信息: ${e.toString()}'); return null; } } Future>?> getDeviceList(String deviceName) async { try { final result = _bleService.getDeviceList(deviceName); return result; } catch (e) { Logger.error('获取设备信息: ${e.toString()}'); return null; } } /// 验证设备是否可以配对 Future verifyDeviceCanPair(String macAddress) async { try { return true; } catch (e) { Logger.error('验证设备配对失败: ${e.toString()}'); return false; } } /// 启动设备关联 Future startDeviceAssociation({ required String deviceNamePattern, required String macAddress, }) async { try { return await _bleService.startDeviceAssociation( deviceNamePattern: deviceNamePattern, macAddress: macAddress, ); } catch (e) { Logger.error('启动设备关联失败: ${e.toString()}'); return false; } } /// 注册后台扫描 Future registerBackgroundScan({String? macAddress}) async { try { // 保存设备地址信息 if (macAddress != null) { _currentDeviceAddress = macAddress; // 从蓝牙管理器获取设备名称 final bluetoothManager = Get.find(); _currentDeviceName = bluetoothManager.currentDevice?.name ?? ""; Logger.info( '保存设备信息: address=$_currentDeviceAddress, name=$_currentDeviceName'); } return await _bleService.registerBackgroundScan(macAddress: macAddress); } catch (e) { Logger.error('注册后台扫描失败: ${e.toString()}'); return false; } } /// 注销后台扫描 Future unregisterBackgroundScan() async { try { return await _bleService.unregisterBackgroundScan(); } catch (e) { Logger.error('注销后台扫描失败: ${e.toString()}'); return false; } } /// 清除BLE配对设备 Future clearPairedDevices() async { try { return await _bleService.clearAssociations(); } catch (e) { Logger.error('清除BLE配对设备失败: ${e.toString()}'); return false; } } /// 注册服务 static Future init() async { if (!Get.isRegistered()) { Get.put(BleManager(), permanent: true); } return Future.value(Get.find()); } /// 请求蓝牙权限 Future requestBluetoothPermission() async { try { return await _bleService.requestBluetoothPermission(); } catch (e) { Logger.error('请求蓝牙权限失败: ${e.toString()}'); return false; } } }