import 'dart:async'; import 'package:get/get.dart'; import '../../../core/routes/app_routes.dart'; import '../../../data/services/bluetooth_service.dart'; import 'package:flutter_blue_plus/flutter_blue_plus.dart' hide BluetoothService; import '../../../core/utils/logger.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:flutter/material.dart'; enum SearchStatus { searching, // 正在搜索设备 found, // 找到设备 failed, // 搜索失败 noPermission, // 缺少权限 needsSystemPairing // 需要在系统设置中配对 } class PairingController extends GetxController { // 搜索状态 final _searchStatus = SearchStatus.searching.obs; SearchStatus get searchStatus => _searchStatus.value; // 搜索动画的点 final _searchDots = ''.obs; String get searchDots => _searchDots.value; // 动画定时器 Timer? _animationTimer; // 蓝牙服务 late BluetoothService _bluetoothService; // 设备信息 final _deviceInfo = Rx>({}); Map get deviceInfo => _deviceInfo.value; // 蓝牙状态 final _isBluetoothAvailable = false.obs; final _isBluetoothOn = false.obs; bool get isBluetoothAvailable => _isBluetoothAvailable.value; bool get isBluetoothOn => _isBluetoothOn.value; // 错误消息 final _errorMessage = ''.obs; String get errorMessage => _errorMessage.value; // 扫描到的设备列表 final _scannedDevices = [].obs; List get scannedDevices => _scannedDevices; // 已配对的设备列表 final _pairedDevices = [].obs; List get pairedDevices => _pairedDevices; // 重试计数 int _retryCount = 0; static const int MAX_RETRY_COUNT = 3; @override void onInit() { super.onInit(); // 启动搜索动画 _startSearchingAnimation(); // 初始化蓝牙服务 _initBluetoothService(); } @override void onClose() { _stopSearchingAnimation(); super.onClose(); } // 初始化蓝牙服务 Future _initBluetoothService() async { try { // 获取蓝牙服务实例 if (Get.isRegistered()) { _bluetoothService = Get.find(); // 如果蓝牙服务已初始化,直接开始查找设备 if (_bluetoothService.isInitialized) { _setupBluetoothListeners(); } else { // 等待蓝牙服务初始化完成 ever(_bluetoothService.isInitializedObs, (bool initialized) { if (initialized) { _setupBluetoothListeners(); } }); } } else { // 初始化蓝牙服务 _bluetoothService = await Get.put(BluetoothService()).init(); _setupBluetoothListeners(); } } catch (e) { Logger.error('初始化蓝牙服务失败: $e'); _errorMessage.value = '初始化蓝牙服务失败'; _searchStatus.value = SearchStatus.failed; _stopSearchingAnimation(); // 重试初始化 _retryInitialization(); } } // 设置蓝牙监听器 void _setupBluetoothListeners() { // 监听蓝牙状态变化 ever(_bluetoothService.isAvailableObs, (bool available) { _isBluetoothAvailable.value = available; }); ever(_bluetoothService.isOnObs, (bool on) { _isBluetoothOn.value = on; // 如果蓝牙开启,开始查找设备 if (on) { _findConnectedDevices(); } else { _errorMessage.value = '请打开蓝牙以搜索设备'; _searchStatus.value = SearchStatus.failed; _stopSearchingAnimation(); } }); // 如果蓝牙已经开启,直接开始查找 if (_bluetoothService.isOn) { _isBluetoothOn.value = true; _findConnectedDevices(); } else { _errorMessage.value = '请打开蓝牙以搜索设备'; } } // 重试初始化 void _retryInitialization() { if (_retryCount < MAX_RETRY_COUNT) { _retryCount++; Logger.info('重试初始化蓝牙服务 (${_retryCount}/${MAX_RETRY_COUNT})'); Future.delayed(const Duration(seconds: 2), () { _initBluetoothService(); }); } } // 启动搜索动画 void _startSearchingAnimation() { _stopSearchingAnimation(); // 清除已有的定时器 int count = 0; _animationTimer = Timer.periodic(const Duration(milliseconds: 500), (timer) { count = (count + 1) % 4; _searchDots.value = '.' * count; }); } // 停止搜索动画 void _stopSearchingAnimation() { _animationTimer?.cancel(); _animationTimer = null; _searchDots.value = ''; } // 请求必要权限 Future _requestPermissions() async { try { return await _bluetoothService.requestPermissions(); } catch (e) { Logger.error('请求权限失败: $e'); return false; } } // 打开应用设置 void goToAppSettings() async { try { await openAppSettings(); } catch (e) { Logger.error('打开应用设置失败: $e'); Get.snackbar( '提示', '无法打开应用设置,请手动打开系统设置授予权限', snackPosition: SnackPosition.TOP, backgroundColor: Colors.red[100], colorText: Colors.red[800], duration: const Duration(seconds: 3), ); } } // 查找已连接的设备 Future _findConnectedDevices() async { try { _searchStatus.value = SearchStatus.searching; // 检查权限 bool hasPermissions = await _requestPermissions(); if (!hasPermissions) { Logger.warning('没有足够的蓝牙权限'); _searchStatus.value = SearchStatus.noPermission; _stopSearchingAnimation(); return; } // 1. 先检查是否有上次连接的设备信息 if (_bluetoothService.lastConnectedDeviceInfo.isNotEmpty && _bluetoothService.lastConnectedDeviceInfo['connected'] == true) { Logger.info('使用上次连接的设备信息'); _deviceInfo.value = _bluetoothService.lastConnectedDeviceInfo; _onDeviceFound(); return; } // 2. 查找系统已连接的设备 Logger.info('查找系统已连接的设备'); BluetoothDevice? device = await _bluetoothService.findConnectedSystemDevice() .timeout(const Duration(seconds: 5), onTimeout: () { Logger.error('获取已连接设备超时'); return null; }); if (device != null) { Logger.info('找到系统已连接设备'); _deviceInfo.value = _bluetoothService.getConnectedDeviceInfo(); _onDeviceFound(); return; } // 3. 如果没有找到已连接设备,提示用户选择 // 获取已配对设备列表 _pairedDevices.value = _bluetoothService.systemPairedDevices; // 如果有已配对的设备,直接尝试连接第一个 if (_pairedDevices.isNotEmpty) { Logger.info('找到已配对设备,尝试连接'); // 尝试连接第一个配对设备 await tryConnectDevice(_pairedDevices.first); } else { // 如果没有已配对设备,开始扫描附近设备 await _scanForDevices(); } } catch (e) { Logger.error('查找设备失败: $e'); _errorMessage.value = '查找设备失败'; _searchStatus.value = SearchStatus.failed; _stopSearchingAnimation(); // 重试查找设备 _retryFindDevices(); } } // 重试查找设备 void _retryFindDevices() { if (_retryCount < MAX_RETRY_COUNT) { _retryCount++; Logger.info('重试查找设备 (${_retryCount}/${MAX_RETRY_COUNT})'); Future.delayed(const Duration(seconds: 2), () { _findConnectedDevices(); }); } } // 扫描附近的蓝牙设备 Future _scanForDevices() async { try { Logger.info('开始扫描附近设备'); _searchStatus.value = SearchStatus.searching; _startSearchingAnimation(); // 开始扫描 List results = await _bluetoothService.startScan( timeout: const Duration(seconds: 10) ); _scannedDevices.value = results; // 过滤出可能是耳机的设备 List audioDevices = results.where((result) { String name = result.device.platformName.toLowerCase(); return name.contains('headphone') || name.contains('earphone') || name.contains('earbuds') || name.contains('headset') || name.contains('speaker') || name.contains('audio') || name.contains('耳机') || name.contains('音箱'); }).toList(); if (audioDevices.isNotEmpty) { // 按信号强度排序 audioDevices.sort((a, b) => b.rssi.compareTo(a.rssi)); Logger.info('找到可能的音频设备'); // 直接尝试连接信号最强的音频设备 await tryConnectDevice(audioDevices.first.device); } else if (results.isNotEmpty) { // 如果没有明确的音频设备但有其他设备,尝试连接信号最强的设备 results.sort((a, b) => b.rssi.compareTo(a.rssi)); Logger.info('未找到明确的音频设备,尝试连接信号最强的设备'); await tryConnectDevice(results.first.device); } else { // 未找到任何设备 _errorMessage.value = '未找到蓝牙设备,请确保设备已开启并在附近'; _searchStatus.value = SearchStatus.failed; _stopSearchingAnimation(); // 重试扫描 _retryScan(); } } catch (e) { Logger.error('扫描设备失败: $e'); _errorMessage.value = '扫描设备失败'; _searchStatus.value = SearchStatus.failed; _stopSearchingAnimation(); // 重试扫描 _retryScan(); } } // 重试扫描 void _retryScan() { if (_retryCount < MAX_RETRY_COUNT) { _retryCount++; Logger.info('重试扫描设备 (${_retryCount}/${MAX_RETRY_COUNT})'); Future.delayed(const Duration(seconds: 2), () { _scanForDevices(); }); } } // 尝试连接特定设备 Future tryConnectDevice(BluetoothDevice device) async { try { Logger.info('尝试连接设备'); _searchStatus.value = SearchStatus.searching; _startSearchingAnimation(); _errorMessage.value = ''; bool connected = await _bluetoothService.connectToDevice(device); if (connected) { Logger.info('连接设备成功'); _deviceInfo.value = _bluetoothService.getConnectedDeviceInfo(); _onDeviceFound(); } else { Logger.error('连接设备失败'); // 检查设备类型 if (_bluetoothService.deviceType == DeviceType.classicAudio) { // 对于经典蓝牙音频设备,提示用户在系统设置中配对 _searchStatus.value = SearchStatus.needsSystemPairing; _errorMessage.value = '这是音频设备,需要在系统设置中配对并连接'; } else { // 其他类型设备连接失败 _searchStatus.value = SearchStatus.failed; _errorMessage.value = '连接设备失败,请重试或检查设备状态'; } _stopSearchingAnimation(); // 重试连接 _retryConnect(device); } } catch (e) { Logger.error('连接设备失败: $e'); _errorMessage.value = '连接设备失败'; _searchStatus.value = SearchStatus.failed; _stopSearchingAnimation(); // 重试连接 _retryConnect(device); } } // 重试连接 void _retryConnect(BluetoothDevice device) { if (_retryCount < MAX_RETRY_COUNT) { _retryCount++; Logger.info('重试连接设备 (${_retryCount}/${MAX_RETRY_COUNT})'); Future.delayed(const Duration(seconds: 2), () { tryConnectDevice(device); }); } } // 设备找到并连接成功后的处理 void _onDeviceFound() { _searchStatus.value = SearchStatus.found; _stopSearchingAnimation(); // 更新日志并延迟跳转到主页 Logger.info('设备连接成功,准备跳转到主页'); Timer(const Duration(seconds: 1), () { Get.offAllNamed(Routes.home, arguments: _deviceInfo.value); }); } // 手动刷新/重新搜索 void refreshSearch() { // 停止当前扫描(如果有) _bluetoothService.stopScan(); // 重置重试计数 _retryCount = 0; // 更新UI状态 _startSearchingAnimation(); _searchStatus.value = SearchStatus.searching; _errorMessage.value = ''; // 重新开始查找过程 _findConnectedDevices(); } // 跳转到系统蓝牙设置 void openSystemBluetoothSettings() async { try { Logger.info('尝试打开系统蓝牙设置'); // 不同平台需要不同的处理 if (GetPlatform.isAndroid) { await openAppSettings(); } else { // iOS不能直接打开蓝牙设置 Get.snackbar( '提示', '请手动打开系统设置并配对您的蓝牙设备', snackPosition: SnackPosition.TOP, backgroundColor: Colors.blue[100], colorText: Colors.blue[800], duration: const Duration(seconds: 3), ); } } catch (e) { Logger.error('打开系统蓝牙设置失败: $e'); Get.snackbar( '提示', '无法打开系统设置,请手动打开蓝牙设置并配对设备', snackPosition: SnackPosition.TOP, backgroundColor: Colors.red[100], colorText: Colors.red[800], duration: const Duration(seconds: 3), ); } } // 稍后再说 void skipConnecting() { // 停止当前扫描 _bluetoothService.stopScan(); _stopSearchingAnimation(); // 直接跳转到主页 Get.offAllNamed(Routes.home); } }