import 'dart:async'; import 'package:flutter/foundation.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart'; import 'package:get/get.dart'; import '../../core/utils/logger.dart'; import 'dart:io' show Platform; import 'package:permission_handler/permission_handler.dart'; /// 蓝牙设备服务,用于发现和管理蓝牙设备 class BluetoothService extends GetxService { static BluetoothService get to => Get.find(); // 单例实例 static final BluetoothService _instance = BluetoothService._internal(); factory BluetoothService() => _instance; BluetoothService._internal(); // 设备状态 final _isAvailable = false.obs; final _isOn = false.obs; // 已连接的设备 final _connectedDevices = [].obs; // 扫描状态 final _isScanning = false.obs; // 扫描结果 final _scanResults = [].obs; // 当前选中的设备 final _selectedDevice = Rx(null); // 连接状态 final _connectionState = Rx(BluetoothConnectionState.disconnected); // 存储最后连接的设备信息,供其他控制器使用 final _lastConnectedDeviceInfo = Rx>({}); // 订阅 StreamSubscription? _stateSubscription; StreamSubscription? _scanSubscription; StreamSubscription? _connectionSubscription; // 权限状态 final _permissionsGranted = false.obs; bool get permissionsGranted => _permissionsGranted.value; // Getters bool get isAvailable => _isAvailable.value; bool get isOn => _isOn.value; bool get isScanning => _isScanning.value; List get connectedDevices => _connectedDevices; List get scanResults => _scanResults; BluetoothDevice? get selectedDevice => _selectedDevice.value; BluetoothConnectionState get connectionState => _connectionState.value; Map get lastConnectedDeviceInfo => _lastConnectedDeviceInfo.value; // Observable getters (for reactive programming) RxBool get isAvailableObs => _isAvailable; RxBool get isOnObs => _isOn; RxList get connectedDevicesObs => _connectedDevices; RxList get scanResultsObs => _scanResults; Rx get selectedDeviceObs => _selectedDevice; Rx get connectionStateObs => _connectionState; Rx> get lastConnectedDeviceInfoObs => _lastConnectedDeviceInfo; /// 初始化蓝牙服务 Future init() async { try { // 不在初始化时检查权限,改为在需要时才检查 // await _checkAndRequestPermissions(); // 在后台线程初始化蓝牙状态监听,避免主线程阻塞 Future.microtask(() { // 监听蓝牙状态 _stateSubscription = FlutterBluePlus.adapterState.listen((state) { _isOn.value = state == BluetoothAdapterState.on; _isAvailable.value = state != BluetoothAdapterState.unavailable; if (state == BluetoothAdapterState.on) { // 蓝牙打开时,获取已连接设备,但不请求权限 // 只有在用户主动扫描时才请求权限 // 在后台线程执行,避免主线程阻塞 Future.microtask(() => _getConnectedDevices()); } else if (state == BluetoothAdapterState.off) { // 蓝牙关闭时,清空设备列表 _connectedDevices.clear(); _scanResults.clear(); _selectedDevice.value = null; _lastConnectedDeviceInfo.value = {}; } }); }); // 不在初始化时立即检查蓝牙状态,而是延迟到UI渲染完成后 // 这样可以避免启动时卡顿 Future.delayed(const Duration(milliseconds: 800), () async { try { // 使用超时机制,避免无限等待蓝牙 bool isOn = await FlutterBluePlus.isOn .timeout(const Duration(seconds: 3), onTimeout: () { Logger.error('检查蓝牙状态超时'); return false; }); _isOn.value = isOn; _isAvailable.value = isOn; if (isOn) { // 在后台线程获取设备,避免主线程阻塞 Future.microtask(() => _getConnectedDevices()); } } catch (e) { Logger.error('延迟检查蓝牙状态失败: $e'); } }); return this; } catch (e) { Logger.error('初始化蓝牙服务失败: $e'); return this; } } /// 检查并请求蓝牙所需权限 Future _checkAndRequestPermissions() async { // 暂时跳过权限检查,直接返回true _permissionsGranted.value = true; return true; } /// 再次请求权限 Future requestPermissions() async { // 暂时跳过权限检查,直接返回true _permissionsGranted.value = true; return true; } /// 获取已连接的设备 Future _getConnectedDevices() async { try { // 使用超时机制,避免无限等待 List devices = await FlutterBluePlus.connectedSystemDevices .timeout(const Duration(seconds: 3), onTimeout: () { Logger.error('获取已连接设备超时'); return []; }); _connectedDevices.value = devices; // 如果有已连接的设备但没有选中设备,则选中第一个 if (_connectedDevices.isNotEmpty && _selectedDevice.value == null) { _selectedDevice.value = _connectedDevices[0]; _monitorConnectionState(_selectedDevice.value!); // 更新最后连接的设备信息 _updateLastConnectedDeviceInfo(); } Logger.info('已连接设备数量: ${_connectedDevices.length}'); } catch (e) { Logger.error('获取已连接设备失败: $e'); } } /// 获取系统中已配对的设备 Future> getPairedDevices() async { try { // 获取已配对的设备(系统已知设备) List systemDevices = await FlutterBluePlus.bondedDevices; return systemDevices; } catch (e) { Logger.error('获取已配对设备失败: $e'); return []; } } /// 开始扫描附近的蓝牙设备并尝试连接最强信号设备 Future scanAndConnectToDevice({Duration? timeout}) async { if (_isScanning.value) { await stopScan(); } // 清空旧的扫描结果 _scanResults.clear(); try { // 设置扫描监听 _scanSubscription?.cancel(); _scanSubscription = FlutterBluePlus.scanResults.listen((results) { _scanResults.value = results; }); // 设置扫描中状态 _isScanning.value = true; // 开始扫描 await FlutterBluePlus.startScan( timeout: timeout ?? const Duration(seconds: 5), ); // 扫描完成 _isScanning.value = false; Logger.info('蓝牙扫描完成,发现 ${_scanResults.length} 个设备'); // 如果找到设备,尝试连接信号最强的 if (_scanResults.isNotEmpty) { // 按信号强度排序 List sortedResults = List.from(_scanResults); sortedResults.sort((a, b) => b.rssi.compareTo(a.rssi)); // 尝试连接信号最强的设备 final topDevice = sortedResults.first.device; Logger.info('尝试连接信号最强的设备: ${topDevice.platformName}'); bool success = await connectToDevice(topDevice); if (success) { return topDevice; } } return null; } catch (e) { _isScanning.value = false; Logger.error('蓝牙扫描或连接失败: $e'); return null; } } /// 停止扫描 Future stopScan() async { if (!_isScanning.value) return; try { await FlutterBluePlus.stopScan(); _isScanning.value = false; } catch (e) { Logger.error('停止蓝牙扫描失败: $e'); } } /// 连接到指定的蓝牙设备 - 简化版本 Future connectToDevice(BluetoothDevice device) async { Logger.info('尝试连接设备: ${device.platformName} (${device.remoteId.str})'); try { // 如果是当前已连接设备,直接返回成功 if (_selectedDevice.value == device && _connectionState.value == BluetoothConnectionState.connected) { Logger.info('设备已连接,无需重新连接'); return true; } // 断开当前连接 if (_selectedDevice.value != null && _selectedDevice.value != device) { await disconnectFromDevice(); } // 直接尝试连接 Logger.info('直接连接设备 ${device.platformName}'); await device.connect(); // 更新设备信息 _selectedDevice.value = device; _monitorConnectionState(device); _updateLastConnectedDeviceInfo(); Logger.info('设备 ${device.platformName} 连接成功'); return true; } catch (e) { Logger.error('连接设备 ${device.platformName} 失败: $e'); return false; } } /// 断开与当前设备的连接 Future disconnectFromDevice() async { if (_selectedDevice.value == null) { Logger.info('没有当前选中的设备,无需断开连接'); return true; } try { Logger.info('正在断开设备 ${_selectedDevice.value!.platformName} 的连接'); await _selectedDevice.value!.disconnect(); Logger.info('设备连接已断开,取消连接状态监听'); _connectionSubscription?.cancel(); _connectionSubscription = null; _selectedDevice.value = null; // 清除最后连接的设备信息 _lastConnectedDeviceInfo.value = {}; return true; } catch (e) { Logger.error('断开蓝牙设备连接失败: $e'); return false; } } /// 监控连接状态 void _monitorConnectionState(BluetoothDevice device) { Logger.info('设置设备 ${device.platformName} 的连接状态监听'); // 取消之前的监听 if (_connectionSubscription != null) { Logger.info('取消之前的连接状态监听'); _connectionSubscription!.cancel(); _connectionSubscription = null; } // 设置新的监听 _connectionSubscription = device.connectionState.listen((state) { Logger.info('设备 ${device.platformName} 连接状态变更为: $state'); _connectionState.value = state; if (state == BluetoothConnectionState.disconnected) { Logger.info('设备 ${device.platformName} 已断开连接'); _selectedDevice.value = null; // 设备断开连接时,不清除最后连接的设备信息,以便下次可以重新连接 } else if (state == BluetoothConnectionState.connected) { Logger.info('设备 ${device.platformName} 已成功连接'); // 设备连接成功时,更新最后连接的设备信息 _updateLastConnectedDeviceInfo(); } else if (state == BluetoothConnectionState.connecting) { Logger.info('设备 ${device.platformName} 正在连接中...'); } else if (state == BluetoothConnectionState.disconnecting) { Logger.info('设备 ${device.platformName} 正在断开连接...'); } }); Logger.info('设备 ${device.platformName} 的连接状态监听已设置'); } /// 获取已连接设备的信息 Map getConnectedDeviceInfo() { if (_selectedDevice.value == null) { return { 'connected': false, 'device': null, }; } final deviceInfo = { 'connected': _connectionState.value == BluetoothConnectionState.connected, 'device': { 'name': _selectedDevice.value!.platformName.isEmpty ? '未命名设备' : _selectedDevice.value!.platformName, 'id': _selectedDevice.value!.remoteId.str, 'isConnected': _connectionState.value == BluetoothConnectionState.connected, 'rssi': _scanResults .firstWhereOrNull((r) => r.device.remoteId == _selectedDevice.value!.remoteId) ?.rssi } }; // 更新最后连接的设备信息 _lastConnectedDeviceInfo.value = deviceInfo; return deviceInfo; } /// 更新最后连接的设备信息 void _updateLastConnectedDeviceInfo() { if (_selectedDevice.value != null) { _lastConnectedDeviceInfo.value = { 'connected': _connectionState.value == BluetoothConnectionState.connected, 'device': { 'name': _selectedDevice.value!.platformName.isEmpty ? '未命名设备' : _selectedDevice.value!.platformName, 'id': _selectedDevice.value!.remoteId.str, 'isConnected': _connectionState.value == BluetoothConnectionState.connected, 'rssi': _scanResults .firstWhereOrNull((r) => r.device.remoteId == _selectedDevice.value!.remoteId) ?.rssi } }; } } /// 一个综合方法,执行自动查找并连接设备的完整流程 Future autoConnectDevice() async { try { // 1. 先检查当前已连接设备 if (_selectedDevice.value != null && _connectionState.value == BluetoothConnectionState.connected) { Logger.info('使用当前已连接设备: ${_selectedDevice.value!.platformName}'); return _selectedDevice.value; } // 2. 检查系统中已连接的设备 try { List connectedDevices = await FlutterBluePlus.connectedSystemDevices .timeout(const Duration(seconds: 3)); if (connectedDevices.isNotEmpty) { // 有已连接的设备,直接使用第一个 Logger.info('发现系统已连接设备: ${connectedDevices.first.platformName}'); // 连接设备并更新服务状态 await connectToDevice(connectedDevices.first); return connectedDevices.first; } } catch (e) { Logger.error('检查系统连接设备失败: $e'); } // 3. 尝试连接之前用过的设备(从已配对设备中寻找) List pairedDevices = await FlutterBluePlus.bondedDevices; // 如果有配对设备,尝试连接第一个 if (pairedDevices.isNotEmpty) { Logger.info('尝试连接已配对设备: ${pairedDevices.first.platformName}'); bool success = await connectToDevice(pairedDevices.first); if (success) { return pairedDevices.first; } } // 4. 没有找到可用设备 return null; } catch (e) { Logger.error('自动连接设备流程失败: $e'); return null; } } /// 获取设备连接状态的简化方法 (用于兼容现有代码) Future getReliableConnectionState(BluetoothDevice device) async { try { // 直接获取设备当前状态 BluetoothConnectionState state = await device.connectionState.first .timeout(const Duration(seconds: 2), onTimeout: () { Logger.info('获取设备 ${device.platformName} 连接状态超时'); return BluetoothConnectionState.disconnected; }); // 如果获取到的状态是已连接,直接返回 if (state == BluetoothConnectionState.connected) { return BluetoothConnectionState.connected; } // 作为备用检查,看设备是否在系统已连接列表中 try { List connectedDevices = await FlutterBluePlus.connectedSystemDevices .timeout(const Duration(seconds: 2)); for (var connectedDevice in connectedDevices) { if (connectedDevice.remoteId.str == device.remoteId.str) { return BluetoothConnectionState.connected; } } } catch (e) { // 忽略检查系统设备列表的错误 } return state; } catch (e) { Logger.error('获取设备 ${device.platformName} 连接状态失败: $e'); return BluetoothConnectionState.disconnected; } } @override void onClose() { _stateSubscription?.cancel(); _scanSubscription?.cancel(); _connectionSubscription?.cancel(); disconnectFromDevice(); super.onClose(); } }