Browse Source

bluetooth fix2

newdev_shunjiawei
wolfplus 2 years ago
parent
commit
7977d9a1df
  1. 99
      lib/data/services/bluetooth_service.dart
  2. 173
      lib/modules/pairing/controllers/pairing_controller.dart

99
lib/data/services/bluetooth_service.dart

@ -63,6 +63,11 @@ class BluetoothService extends GetxService {
final _permissionsGranted = false.obs; final _permissionsGranted = false.obs;
bool get permissionsGranted => _permissionsGranted.value; bool get permissionsGranted => _permissionsGranted.value;
// 初始化完成标志
final _isInitialized = false.obs;
bool get isInitialized => _isInitialized.value;
RxBool get isInitializedObs => _isInitialized;
// Getters // Getters
bool get isAvailable => _isAvailable.value; bool get isAvailable => _isAvailable.value;
bool get isOn => _isOn.value; bool get isOn => _isOn.value;
@ -93,58 +98,55 @@ class BluetoothService extends GetxService {
/// 初始化蓝牙服务 /// 初始化蓝牙服务
Future<BluetoothService> init() async { Future<BluetoothService> init() async {
try { try {
// 确保权限检查在后台线程执行,避免主线程阻塞 Logger.info('开始初始化蓝牙服务');
Future.microtask(() async {
// 仅在Android上请求权限 // 先请求权限,确保权限请求完成后再进行后续操作
if (Platform.isAndroid) { if (Platform.isAndroid) {
await _checkAndRequestPermissions(); Logger.info('Android平台,请求蓝牙权限');
await _checkAndRequestPermissions();
}
// 设置蓝牙状态监听
_stateSubscription = FlutterBluePlus.adapterState.listen((state) {
_isOn.value = state == BluetoothAdapterState.on;
_isAvailable.value = state != BluetoothAdapterState.unavailable;
if (state == BluetoothAdapterState.on) {
// 蓝牙打开时,获取已连接和已配对设备
_refreshSystemDevices();
} else if (state == BluetoothAdapterState.off) {
// 蓝牙关闭时,清空设备列表
_connectedDevices.clear();
_systemPairedDevices.clear();
_scanResults.clear();
_selectedDevice.value = null;
_lastConnectedDeviceInfo.value = {};
_deviceType.value = DeviceType.unknown;
} }
}); });
// 在后台线程初始化蓝牙状态监听 // 检查蓝牙状态
Future.microtask(() { try {
// 监听蓝牙状态 bool isOn = await FlutterBluePlus.isOn
_stateSubscription = FlutterBluePlus.adapterState.listen((state) { .timeout(const Duration(seconds: 5), onTimeout: () {
_isOn.value = state == BluetoothAdapterState.on; Logger.error('检查蓝牙状态超时');
_isAvailable.value = state != BluetoothAdapterState.unavailable; return false;
if (state == BluetoothAdapterState.on) {
// 蓝牙打开时,获取已连接和已配对设备
_refreshSystemDevices();
} else if (state == BluetoothAdapterState.off) {
// 蓝牙关闭时,清空设备列表
_connectedDevices.clear();
_systemPairedDevices.clear();
_scanResults.clear();
_selectedDevice.value = null;
_lastConnectedDeviceInfo.value = {};
_deviceType.value = DeviceType.unknown;
}
}); });
});
_isOn.value = isOn;
// 延迟检查蓝牙状态,避免启动时卡顿 _isAvailable.value = isOn;
Future.delayed(const Duration(milliseconds: 800), () async {
try { if (isOn) {
// 使用超时机制 // 刷新设备状态
bool isOn = await FlutterBluePlus.isOn await _refreshSystemDevices();
.timeout(const Duration(seconds: 3), onTimeout: () {
Logger.error('检查蓝牙状态超时');
return false;
});
_isOn.value = isOn;
_isAvailable.value = isOn;
if (isOn) {
// 在后台刷新设备状态
_refreshSystemDevices();
}
} catch (e) {
Logger.error('延迟检查蓝牙状态失败: $e');
} }
}); } catch (e) {
Logger.error('检查蓝牙状态失败: $e');
}
// 标记初始化完成
_isInitialized.value = true;
Logger.info('蓝牙服务初始化完成');
return this; return this;
} catch (e) { } catch (e) {
Logger.error('初始化蓝牙服务失败: $e'); Logger.error('初始化蓝牙服务失败: $e');
@ -200,7 +202,7 @@ class BluetoothService extends GetxService {
// 获取系统已连接设备 // 获取系统已连接设备
try { try {
List<BluetoothDevice> devices = await FlutterBluePlus.connectedSystemDevices List<BluetoothDevice> devices = await FlutterBluePlus.connectedSystemDevices
.timeout(const Duration(seconds: 3), onTimeout: () { .timeout(const Duration(seconds: 5), onTimeout: () {
Logger.error('获取已连接设备超时'); Logger.error('获取已连接设备超时');
return <BluetoothDevice>[]; return <BluetoothDevice>[];
}); });
@ -229,7 +231,7 @@ class BluetoothService extends GetxService {
// 获取已配对设备 // 获取已配对设备
try { try {
List<BluetoothDevice> pairedDevices = await FlutterBluePlus.bondedDevices List<BluetoothDevice> pairedDevices = await FlutterBluePlus.bondedDevices
.timeout(const Duration(seconds: 3), onTimeout: () { .timeout(const Duration(seconds: 5), onTimeout: () {
Logger.error('获取已配对设备超时'); Logger.error('获取已配对设备超时');
return <BluetoothDevice>[]; return <BluetoothDevice>[];
}); });
@ -242,7 +244,6 @@ class BluetoothService extends GetxService {
// 如果有已连接的设备但没有选中设备,自动选择第一个 // 如果有已连接的设备但没有选中设备,自动选择第一个
if (_connectedDevices.isNotEmpty && _selectedDevice.value == null) { if (_connectedDevices.isNotEmpty && _selectedDevice.value == null) {
Logger.info('自动选择第一个已连接设备: ${_connectedDevices[0].platformName}');
_selectedDevice.value = _connectedDevices[0]; _selectedDevice.value = _connectedDevices[0];
_determineDeviceType(_selectedDevice.value!); _determineDeviceType(_selectedDevice.value!);
_connectionState.value = BluetoothConnectionState.connected; _connectionState.value = BluetoothConnectionState.connected;

173
lib/modules/pairing/controllers/pairing_controller.dart

@ -52,16 +52,18 @@ class PairingController extends GetxController {
final _pairedDevices = <BluetoothDevice>[].obs; final _pairedDevices = <BluetoothDevice>[].obs;
List<BluetoothDevice> get pairedDevices => _pairedDevices; List<BluetoothDevice> get pairedDevices => _pairedDevices;
// 重试计数
int _retryCount = 0;
static const int MAX_RETRY_COUNT = 3;
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
// 启动搜索动画 // 启动搜索动画
_startSearchingAnimation(); _startSearchingAnimation();
// 延迟初始化蓝牙服务,避免在应用启动时就阻塞主线程 // 初始化蓝牙服务
Future.delayed(const Duration(milliseconds: 800), () { _initBluetoothService();
_initBluetoothService();
});
} }
@override @override
@ -76,47 +78,72 @@ class PairingController extends GetxController {
// 获取蓝牙服务实例 // 获取蓝牙服务实例
if (Get.isRegistered<BluetoothService>()) { if (Get.isRegistered<BluetoothService>()) {
_bluetoothService = Get.find<BluetoothService>(); _bluetoothService = Get.find<BluetoothService>();
} else {
// 初始化蓝牙服务
_bluetoothService = await Get.put(BluetoothService()).init();
}
// 监听蓝牙状态变化
ever(_bluetoothService.isAvailableObs, (bool available) {
_isBluetoothAvailable.value = available;
});
ever(_bluetoothService.isOnObs, (bool on) {
_isBluetoothOn.value = on;
// 如果蓝牙开启,开始查找设备 // 如果蓝牙服务已初始化,直接开始查找设备
if (on) { if (_bluetoothService.isInitialized) {
// 延迟开始查找,给权限请求等操作留出时间 _setupBluetoothListeners();
Future.delayed(const Duration(milliseconds: 800), () {
_findConnectedDevices();
});
} else { } else {
_errorMessage.value = '请打开蓝牙以搜索设备'; // 等待蓝牙服务初始化完成
_searchStatus.value = SearchStatus.failed; ever(_bluetoothService.isInitializedObs, (bool initialized) {
_stopSearchingAnimation(); if (initialized) {
_setupBluetoothListeners();
}
});
} }
});
// 如果蓝牙已经开启,直接开始查找
if (_bluetoothService.isOn) {
_isBluetoothOn.value = true;
// 延迟开始查找
Future.delayed(const Duration(milliseconds: 800), () {
_findConnectedDevices();
});
} else { } else {
_errorMessage.value = '请打开蓝牙以搜索设备'; // 初始化蓝牙服务
_bluetoothService = await Get.put(BluetoothService()).init();
_setupBluetoothListeners();
} }
} catch (e) { } catch (e) {
Logger.error('初始化蓝牙服务失败: $e'); Logger.error('初始化蓝牙服务失败: $e');
_errorMessage.value = '初始化蓝牙服务失败'; _errorMessage.value = '初始化蓝牙服务失败';
_searchStatus.value = SearchStatus.failed; _searchStatus.value = SearchStatus.failed;
_stopSearchingAnimation(); _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();
});
} }
} }
@ -192,12 +219,12 @@ class PairingController extends GetxController {
Logger.info('查找系统已连接的设备'); Logger.info('查找系统已连接的设备');
BluetoothDevice? device = await _bluetoothService.findConnectedSystemDevice() BluetoothDevice? device = await _bluetoothService.findConnectedSystemDevice()
.timeout(const Duration(seconds: 5), onTimeout: () { .timeout(const Duration(seconds: 5), onTimeout: () {
Logger.info('查找系统已连接设备超时'); Logger.error('获取已连接设备超时');
return null; return null;
}); });
if (device != null) { if (device != null) {
Logger.info('找到系统已连接设备: ${device.platformName}'); Logger.info('找到系统已连接设备');
_deviceInfo.value = _bluetoothService.getConnectedDeviceInfo(); _deviceInfo.value = _bluetoothService.getConnectedDeviceInfo();
_onDeviceFound(); _onDeviceFound();
return; return;
@ -209,7 +236,7 @@ class PairingController extends GetxController {
// 如果有已配对的设备,直接尝试连接第一个 // 如果有已配对的设备,直接尝试连接第一个
if (_pairedDevices.isNotEmpty) { if (_pairedDevices.isNotEmpty) {
Logger.info('找到${_pairedDevices.length}个已配对设备,尝试连接第一个'); Logger.info('找到已配对设备,尝试连接');
// 尝试连接第一个配对设备 // 尝试连接第一个配对设备
await tryConnectDevice(_pairedDevices.first); await tryConnectDevice(_pairedDevices.first);
@ -219,9 +246,24 @@ class PairingController extends GetxController {
} }
} catch (e) { } catch (e) {
Logger.error('查找设备失败: $e'); Logger.error('查找设备失败: $e');
_errorMessage.value = '查找设备失败: ${e.toString()}'; _errorMessage.value = '查找设备失败';
_searchStatus.value = SearchStatus.failed; _searchStatus.value = SearchStatus.failed;
_stopSearchingAnimation(); _stopSearchingAnimation();
// 重试查找设备
_retryFindDevices();
}
}
// 重试查找设备
void _retryFindDevices() {
if (_retryCount < MAX_RETRY_COUNT) {
_retryCount++;
Logger.info('重试查找设备 (${_retryCount}/${MAX_RETRY_COUNT})');
Future.delayed(const Duration(seconds: 2), () {
_findConnectedDevices();
});
} }
} }
@ -255,14 +297,14 @@ class PairingController extends GetxController {
if (audioDevices.isNotEmpty) { if (audioDevices.isNotEmpty) {
// 按信号强度排序 // 按信号强度排序
audioDevices.sort((a, b) => b.rssi.compareTo(a.rssi)); audioDevices.sort((a, b) => b.rssi.compareTo(a.rssi));
Logger.info('找到可能的音频设备: ${audioDevices.first.device.platformName}'); Logger.info('找到可能的音频设备');
// 直接尝试连接信号最强的音频设备 // 直接尝试连接信号最强的音频设备
await tryConnectDevice(audioDevices.first.device); await tryConnectDevice(audioDevices.first.device);
} else if (results.isNotEmpty) { } else if (results.isNotEmpty) {
// 如果没有明确的音频设备但有其他设备,尝试连接信号最强的设备 // 如果没有明确的音频设备但有其他设备,尝试连接信号最强的设备
results.sort((a, b) => b.rssi.compareTo(a.rssi)); results.sort((a, b) => b.rssi.compareTo(a.rssi));
Logger.info('未找到明确的音频设备,尝试连接信号最强的设备: ${results.first.device.platformName}'); Logger.info('未找到明确的音频设备,尝试连接信号最强的设备');
await tryConnectDevice(results.first.device); await tryConnectDevice(results.first.device);
} else { } else {
@ -270,19 +312,37 @@ class PairingController extends GetxController {
_errorMessage.value = '未找到蓝牙设备,请确保设备已开启并在附近'; _errorMessage.value = '未找到蓝牙设备,请确保设备已开启并在附近';
_searchStatus.value = SearchStatus.failed; _searchStatus.value = SearchStatus.failed;
_stopSearchingAnimation(); _stopSearchingAnimation();
// 重试扫描
_retryScan();
} }
} catch (e) { } catch (e) {
Logger.error('扫描设备失败: $e'); Logger.error('扫描设备失败: $e');
_errorMessage.value = '扫描设备失败: ${e.toString()}'; _errorMessage.value = '扫描设备失败';
_searchStatus.value = SearchStatus.failed; _searchStatus.value = SearchStatus.failed;
_stopSearchingAnimation(); _stopSearchingAnimation();
// 重试扫描
_retryScan();
}
}
// 重试扫描
void _retryScan() {
if (_retryCount < MAX_RETRY_COUNT) {
_retryCount++;
Logger.info('重试扫描设备 (${_retryCount}/${MAX_RETRY_COUNT})');
Future.delayed(const Duration(seconds: 2), () {
_scanForDevices();
});
} }
} }
// 尝试连接特定设备 // 尝试连接特定设备
Future<void> tryConnectDevice(BluetoothDevice device) async { Future<void> tryConnectDevice(BluetoothDevice device) async {
try { try {
Logger.info('尝试连接设备: ${device.platformName}'); Logger.info('尝试连接设备');
_searchStatus.value = SearchStatus.searching; _searchStatus.value = SearchStatus.searching;
_startSearchingAnimation(); _startSearchingAnimation();
_errorMessage.value = ''; _errorMessage.value = '';
@ -290,11 +350,11 @@ class PairingController extends GetxController {
bool connected = await _bluetoothService.connectToDevice(device); bool connected = await _bluetoothService.connectToDevice(device);
if (connected) { if (connected) {
Logger.info('连接设备成功: ${device.platformName}'); Logger.info('连接设备成功');
_deviceInfo.value = _bluetoothService.getConnectedDeviceInfo(); _deviceInfo.value = _bluetoothService.getConnectedDeviceInfo();
_onDeviceFound(); _onDeviceFound();
} else { } else {
Logger.error('连接设备失败: ${device.platformName}'); Logger.error('连接设备失败');
// 检查设备类型 // 检查设备类型
if (_bluetoothService.deviceType == DeviceType.classicAudio) { if (_bluetoothService.deviceType == DeviceType.classicAudio) {
@ -307,12 +367,30 @@ class PairingController extends GetxController {
_errorMessage.value = '连接设备失败,请重试或检查设备状态'; _errorMessage.value = '连接设备失败,请重试或检查设备状态';
} }
_stopSearchingAnimation(); _stopSearchingAnimation();
// 重试连接
_retryConnect(device);
} }
} catch (e) { } catch (e) {
Logger.error('连接设备失败: $e'); Logger.error('连接设备失败: $e');
_errorMessage.value = '连接设备失败: ${e.toString()}'; _errorMessage.value = '连接设备失败';
_searchStatus.value = SearchStatus.failed; _searchStatus.value = SearchStatus.failed;
_stopSearchingAnimation(); _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);
});
} }
} }
@ -333,6 +411,9 @@ class PairingController extends GetxController {
// 停止当前扫描(如果有) // 停止当前扫描(如果有)
_bluetoothService.stopScan(); _bluetoothService.stopScan();
// 重置重试计数
_retryCount = 0;
// 更新UI状态 // 更新UI状态
_startSearchingAnimation(); _startSearchingAnimation();
_searchStatus.value = SearchStatus.searching; _searchStatus.value = SearchStatus.searching;

Loading…
Cancel
Save