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); // 订阅 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; // 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; /// 初始化蓝牙服务 Future init() async { try { // 不在初始化时检查权限,改为在需要时才检查 // await _checkAndRequestPermissions(); // 监听蓝牙状态 _stateSubscription = FlutterBluePlus.adapterState.listen((state) { _isOn.value = state == BluetoothAdapterState.on; _isAvailable.value = state != BluetoothAdapterState.unavailable; if (state == BluetoothAdapterState.on) { // 蓝牙打开时,获取已连接设备,但不请求权限 // 只有在用户主动扫描时才请求权限 _getConnectedDevices(); } else if (state == BluetoothAdapterState.off) { // 蓝牙关闭时,清空设备列表 _connectedDevices.clear(); _scanResults.clear(); _selectedDevice.value = null; } }); // 检查当前蓝牙状态,如果已开启则获取设备 if (await FlutterBluePlus.isOn) { _isOn.value = true; _isAvailable.value = true; _getConnectedDevices(); } 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; _connectedDevices.value = devices; // 如果有已连接的设备但没有选中设备,则选中第一个 if (_connectedDevices.isNotEmpty && _selectedDevice.value == null) { _selectedDevice.value = _connectedDevices[0]; _monitorConnectionState(_selectedDevice.value!); } 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 startScan({Duration? timeout}) async { if (_isScanning.value) return; // 清空旧的扫描结果 _scanResults.clear(); try { // 开始扫描 _scanSubscription?.cancel(); _scanSubscription = FlutterBluePlus.scanResults.listen((results) { _scanResults.value = results; }); // 设置扫描中状态 _isScanning.value = true; // 开始扫描 await FlutterBluePlus.startScan( timeout: timeout ?? const Duration(seconds: 10), ); // 扫描完成后更新状态 _isScanning.value = false; Logger.info('蓝牙扫描完成,发现 ${_scanResults.length} 个设备'); } catch (e) { _isScanning.value = false; Logger.error('蓝牙扫描失败: $e'); } } /// 停止扫描 Future stopScan() async { if (!_isScanning.value) return; try { await FlutterBluePlus.stopScan(); _isScanning.value = false; } catch (e) { Logger.error('停止蓝牙扫描失败: $e'); } } /// 连接到指定设备 Future connectToDevice(BluetoothDevice device) async { if (_selectedDevice.value == device) { // 如果是当前选中设备,检查连接状态 if (_connectionState.value == BluetoothConnectionState.connected) { Logger.info('设备 ${device.platformName} 已经连接,无需重新连接'); return true; } } try { // 检查设备是否已连接 bool isAlreadyConnected = false; // 检查设备连接状态 BluetoothConnectionState state = await device.connectionState.first; if (state == BluetoothConnectionState.connected) { Logger.info('设备 ${device.platformName} 已处于连接状态'); isAlreadyConnected = true; } // 如果设备已连接,直接更新状态而不尝试连接 if (isAlreadyConnected) { // 断开当前跟踪的设备(如果有) if (_selectedDevice.value != null && _selectedDevice.value != device) { _connectionSubscription?.cancel(); } // 更新状态 _selectedDevice.value = device; _monitorConnectionState(device); return true; } // 断开当前连接 await disconnectFromDevice(); // 连接新设备 await device.connect(); // 更新状态 _selectedDevice.value = device; _monitorConnectionState(device); return true; } catch (e) { Logger.error('连接蓝牙设备失败: $e'); return false; } } /// 断开与当前设备的连接 Future disconnectFromDevice() async { if (_selectedDevice.value == null) return true; try { await _selectedDevice.value!.disconnect(); _connectionSubscription?.cancel(); _connectionSubscription = null; _selectedDevice.value = null; return true; } catch (e) { Logger.error('断开蓝牙设备连接失败: $e'); return false; } } /// 监控连接状态 void _monitorConnectionState(BluetoothDevice device) { _connectionSubscription?.cancel(); _connectionSubscription = device.connectionState.listen((state) { _connectionState.value = state; if (state == BluetoothConnectionState.disconnected) { _selectedDevice.value = null; } }); } /// 获取已连接设备的信息 Map getConnectedDeviceInfo() { if (_selectedDevice.value == null) { return { 'connected': false, 'device': null, }; } return { '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 } }; } @override void onClose() { _stateSubscription?.cancel(); _scanSubscription?.cancel(); _connectionSubscription?.cancel(); disconnectFromDevice(); super.onClose(); } }