Browse Source

bluetooth fix2

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

39
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,17 +98,15 @@ 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) {
Logger.info('Android平台,请求蓝牙权限');
await _checkAndRequestPermissions(); await _checkAndRequestPermissions();
} }
});
// 在后台线程初始化蓝牙状态监听 // 设置蓝牙状态监听
Future.microtask(() {
// 监听蓝牙状态
_stateSubscription = FlutterBluePlus.adapterState.listen((state) { _stateSubscription = FlutterBluePlus.adapterState.listen((state) {
_isOn.value = state == BluetoothAdapterState.on; _isOn.value = state == BluetoothAdapterState.on;
_isAvailable.value = state != BluetoothAdapterState.unavailable; _isAvailable.value = state != BluetoothAdapterState.unavailable;
@ -121,14 +124,11 @@ class BluetoothService extends GetxService {
_deviceType.value = DeviceType.unknown; _deviceType.value = DeviceType.unknown;
} }
}); });
});
// 延迟检查蓝牙状态,避免启动时卡顿 // 检查蓝牙状态
Future.delayed(const Duration(milliseconds: 800), () async {
try { try {
// 使用超时机制
bool isOn = await FlutterBluePlus.isOn bool isOn = await FlutterBluePlus.isOn
.timeout(const Duration(seconds: 3), onTimeout: () { .timeout(const Duration(seconds: 5), onTimeout: () {
Logger.error('检查蓝牙状态超时'); Logger.error('检查蓝牙状态超时');
return false; return false;
}); });
@ -137,14 +137,16 @@ class BluetoothService extends GetxService {
_isAvailable.value = isOn; _isAvailable.value = isOn;
if (isOn) { if (isOn) {
// 在后台刷新设备状态 // 刷新设备状态
_refreshSystemDevices(); await _refreshSystemDevices();
} }
} catch (e) { } catch (e) {
Logger.error('延迟检查蓝牙状态失败: $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;

131
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,11 +78,36 @@ class PairingController extends GetxController {
// 获取蓝牙服务实例 // 获取蓝牙服务实例
if (Get.isRegistered<BluetoothService>()) { if (Get.isRegistered<BluetoothService>()) {
_bluetoothService = Get.find<BluetoothService>(); _bluetoothService = Get.find<BluetoothService>();
// 如果蓝牙服务已初始化,直接开始查找设备
if (_bluetoothService.isInitialized) {
_setupBluetoothListeners();
} else {
// 等待蓝牙服务初始化完成
ever(_bluetoothService.isInitializedObs, (bool initialized) {
if (initialized) {
_setupBluetoothListeners();
}
});
}
} else { } else {
// 初始化蓝牙服务 // 初始化蓝牙服务
_bluetoothService = await Get.put(BluetoothService()).init(); _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) { ever(_bluetoothService.isAvailableObs, (bool available) {
_isBluetoothAvailable.value = available; _isBluetoothAvailable.value = available;
@ -91,10 +118,7 @@ class PairingController extends GetxController {
// 如果蓝牙开启,开始查找设备 // 如果蓝牙开启,开始查找设备
if (on) { if (on) {
// 延迟开始查找,给权限请求等操作留出时间
Future.delayed(const Duration(milliseconds: 800), () {
_findConnectedDevices(); _findConnectedDevices();
});
} else { } else {
_errorMessage.value = '请打开蓝牙以搜索设备'; _errorMessage.value = '请打开蓝牙以搜索设备';
_searchStatus.value = SearchStatus.failed; _searchStatus.value = SearchStatus.failed;
@ -105,18 +129,21 @@ class PairingController extends GetxController {
// 如果蓝牙已经开启,直接开始查找 // 如果蓝牙已经开启,直接开始查找
if (_bluetoothService.isOn) { if (_bluetoothService.isOn) {
_isBluetoothOn.value = true; _isBluetoothOn.value = true;
// 延迟开始查找
Future.delayed(const Duration(milliseconds: 800), () {
_findConnectedDevices(); _findConnectedDevices();
});
} else { } else {
_errorMessage.value = '请打开蓝牙以搜索设备'; _errorMessage.value = '请打开蓝牙以搜索设备';
} }
} catch (e) { }
Logger.error('初始化蓝牙服务失败: $e');
_errorMessage.value = '初始化蓝牙服务失败'; // 重试初始化
_searchStatus.value = SearchStatus.failed; void _retryInitialization() {
_stopSearchingAnimation(); 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