wolfplus 1 year ago
parent
commit
5c70e00b4a
  1. 125
      lib/modules/home/controllers/home_controller.dart
  2. 81
      lib/modules/pairing/controllers/pairing_controller.dart
  3. 8
      lib/modules/pairing/views/pairing_view.dart
  4. 5
      lib/modules/pairing/views/pairing_view_new.dart

125
lib/modules/home/controllers/home_controller.dart

@ -22,6 +22,10 @@ class HomeController extends GetxController {
// 连接状态相关
final _isFullyConnected = false.obs;
// 缓存最后连接的设备信息,用于断开后短暂显示
String? _lastConnectedDeviceName;
String? _lastConnectedDeviceAddress;
// Getter方法
bool get isFullyConnected => _isFullyConnected.value;
RxBool get isFullyConnectedRx => _isFullyConnected; // 响应式getter供UI使用
@ -82,10 +86,8 @@ class HomeController extends GetxController {
// 设置监听器
_setupStateListeners();
// 延迟检查初始连接状态,确保监听器已经设置
Future.delayed(const Duration(milliseconds: 100), () {
_checkConnectionStatus();
});
// 立即检查初始连接状态
_checkConnectionStatus();
}
/// 设置状态监听器
@ -102,29 +104,26 @@ class HomeController extends GetxController {
// 经典蓝牙连接监听
_classicBluetoothWorker = ever(_bluetoothManager.currentDeviceRx, (BluetoothDevice? device) {
Logger.d(_tag, '经典蓝牙: ${device != null ? "已连接" : "已断开"}');
// 保存设备信息用于断开后显示
if (device != null) {
_lastConnectedDeviceName = device.name;
_lastConnectedDeviceAddress = device.address;
}
// 立即检查状态,不使用延迟
_checkConnectionStatus();
// 额外的刷新确保UI更新
Future.delayed(const Duration(milliseconds: 50), () {
_isFullyConnected.refresh();
update();
});
});
// BLE连接监听
_bleConnectionWorker = ever(_bleManager.connectionStateRx, (int state) {
Logger.d(_tag, 'BLE状态变化: $state (${state == 2 ? "已连接" : "未连接"})');
// 立即检查状态,不使用延迟
_checkConnectionStatus();
// 额外的刷新确保UI更新
Future.delayed(const Duration(milliseconds: 50), () {
_isFullyConnected.refresh();
update();
});
});
}
/// 刷新设备连接状态
Future<void> refreshDeviceConnection() async {
_checkConnectionStatus();
await _checkConnectionStatus();
}
// 导航和功能方法
@ -147,47 +146,53 @@ class HomeController extends GetxController {
// UI辅助方法
/// 检查连接状态
void _checkConnectionStatus() {
// 直接检查,不使用延迟
bool hasClassicBluetooth = currentDevice != null;
bool hasBleConnection = _bleManager.connectionState == 2; // 直接检查状态值,2 = connected
Logger.d(_tag, '连接状态检查: 经典蓝牙=$hasClassicBluetooth, BLE=$hasBleConnection (状态值=${_bleManager.connectionState})');
bool wasConnected = _isFullyConnected.value;
bool isNowConnected = hasClassicBluetooth && hasBleConnection;
// 只有状态真正改变时才更新
if (_isFullyConnected.value != isNowConnected) {
// 先更新状态
_isFullyConnected.value = isNowConnected;
Logger.d(_tag, '连接状态变更: ${wasConnected ? "已连接" : "未连接"} -> ${isNowConnected ? "已连接" : "未连接"}');
Future<void> _checkConnectionStatus() async {
try {
// 主动从原生层获取最新的BLE状态
final currentBleState = await _bleManager.getConnectionState();
bool hasClassicBluetooth = currentDevice != null;
bool hasBleConnection = currentBleState == 2; // 使用实时查询的状态
// 强制触发响应式更新
_isFullyConnected.refresh();
Logger.d(_tag, '连接状态检查: 经典蓝牙=$hasClassicBluetooth, BLE=$hasBleConnection (实时状态值=$currentBleState)');
// 如果从未连接变为连接,主动获取耳机信息
if (!wasConnected && isNowConnected) {
Logger.d(_tag, '设备连接成功,获取耳机信息');
_bleManager.fetchDeviceInfo();
bool wasConnected = _isFullyConnected.value;
bool isNowConnected = hasClassicBluetooth && hasBleConnection;
// 状态一致性检查:如果声称已连接但没有设备信息,强制断开
if (isNowConnected && currentDevice == null) {
Logger.w(_tag, '状态不一致:已连接但无设备信息,强制更新为未连接');
isNowConnected = false;
}
// 延迟一帧后再次刷新,确保UI更新
Future.delayed(Duration.zero, () {
update();
// 再次强制刷新响应式变量
// 只有状态真正改变时才更新
if (_isFullyConnected.value != isNowConnected) {
// 立即同步更新状态
_isFullyConnected.value = isNowConnected;
Logger.d(_tag, '连接状态变更: ${wasConnected ? "已连接" : "未连接"} -> ${isNowConnected ? "已连接" : "未连接"}');
// 立即触发UI更新,不使用延迟
_isFullyConnected.refresh();
});
// 延迟稍长时间再刷新一次,处理某些特殊情况
Future.delayed(const Duration(milliseconds: 100), () {
update();
// 如果从未连接变为连接,主动获取耳机信息
if (!wasConnected && isNowConnected) {
Logger.d(_tag, '设备连接成功,获取耳机信息');
await _bleManager.fetchDeviceInfo();
}
}
// 确保UI刷新
update();
} catch (e) {
Logger.e(_tag, '检查连接状态失败: $e');
// 出错时设置为未连接
if (_isFullyConnected.value) {
_isFullyConnected.value = false;
_isFullyConnected.refresh();
});
update();
}
}
// 总是调用update确保UI刷新
update();
}
/// 获取连接状态对应的颜色
@ -209,7 +214,29 @@ class HomeController extends GetxController {
/// 获取设备名称
String getDeviceName() {
return currentDevice?.name ?? 'unknownEquipment'.tr;
// 状态一致性检查
if (_isFullyConnected.value && currentDevice == null) {
Logger.w(_tag, '状态不一致:显示已连接但无设备信息');
// 立即重新检查状态
_checkConnectionStatus();
}
// 优先使用当前设备名称
if (currentDevice?.name != null && currentDevice!.name!.isNotEmpty) {
return currentDevice!.name!;
}
// 如果当前没有设备但有BLE设备信息,使用BLE的设备名
if (deviceInfo.value?.name != null && deviceInfo.value!.name.isNotEmpty) {
return deviceInfo.value!.name;
}
// 如果刚断开连接,使用缓存的设备名称(提供更好的用户体验)
if (!_isFullyConnected.value && _lastConnectedDeviceName != null && _lastConnectedDeviceName!.isNotEmpty) {
return _lastConnectedDeviceName!;
}
return 'unknownEquipment'.tr;
}
/// 获取信号强度(模拟数据)

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

@ -15,6 +15,7 @@ enum PairingState {
checking, // 检查中(蓝牙、权限等)
waitingClassic, // 等待经典蓝牙连接
verifying, // 验证设备
associating, // 正在进行BLE设备关联
waitingBle, // 等待BLE连接
completed, // 配对完成
error, // 错误状态
@ -28,6 +29,7 @@ enum ErrorType {
noClassicDevice, // 无经典蓝牙设备
deviceNotMatch, // 设备不匹配
deviceBound, // 设备已被绑定
associationFailed, // 关联失败
bleTimeout, // BLE连接超时
networkError, // 网络错误
}
@ -261,6 +263,15 @@ class PairingController extends GetxController {
isLoading.value = true;
break;
case PairingState.associating:
statusText.value = '正在关联设备...';
isLoading.value = true;
// 延迟执行关联,确保状态已更新
Future.delayed(const Duration(milliseconds: 200), () {
_startDeviceAssociation();
});
break;
case PairingState.waitingBle:
statusText.value = '正在建立安全连接...';
isLoading.value = true;
@ -295,6 +306,10 @@ class PairingController extends GetxController {
showRetryButton.value = true;
retryButtonText.value = '授予权限';
break;
case ErrorType.associationFailed:
showRetryButton.value = true;
retryButtonText.value = '重新关联';
break;
default:
showRetryButton.value = true;
retryButtonText.value = '重试';
@ -394,16 +409,27 @@ class PairingController extends GetxController {
Logger.i(_tag, '设备验证通过');
_verifiedDeviceAddress = device.address;
// 检查BLE状态 - 直接从原生层获取
final currentBleState = await _bleManager.getConnectionState();
Logger.i(_tag, '验证时BLE状态: $currentBleState');
// 检查是否已有BLE关联
final pairedMacAddress = await _bleManager.getPairedMacAddress();
Logger.i(_tag, '已关联的MAC地址: $pairedMacAddress');
if (currentBleState == 2) { // BleConnectionState.connected
Logger.i(_tag, 'BLE已连接,直接完成配对');
_transition(PairingState.completed);
if (pairedMacAddress != null && pairedMacAddress.toUpperCase() == device.address.toUpperCase()) {
// 已有关联,检查BLE连接状态
Logger.i(_tag, '设备已关联,检查BLE连接状态');
final currentBleState = await _bleManager.getConnectionState();
Logger.i(_tag, '验证时BLE状态: $currentBleState');
if (currentBleState == 2) { // BleConnectionState.connected
Logger.i(_tag, 'BLE已连接,直接完成配对');
_transition(PairingState.completed);
} else {
Logger.i(_tag, 'BLE未连接,等待BLE连接');
_transition(PairingState.waitingBle);
}
} else {
Logger.i(_tag, 'BLE未连接,等待BLE连接');
_transition(PairingState.waitingBle);
// 没有关联或关联的是其他设备,需要进行关联
Logger.i(_tag, '需要进行BLE设备关联');
_transition(PairingState.associating);
}
} else {
_setError(ErrorType.deviceNotMatch, '请连接 DeepSound 设备');
@ -414,6 +440,35 @@ class PairingController extends GetxController {
}
}
/// 开始设备关联
void _startDeviceAssociation() async {
try {
if (_verifiedDeviceAddress == null) {
_setError(ErrorType.associationFailed, '设备地址无效');
return;
}
Logger.i(_tag, '开始BLE设备关联: $_verifiedDeviceAddress');
// 调用BLE管理器的关联方法
final success = await _bleManager.startDeviceAssociation(
deviceNamePattern: 'DeapSound', // 或者使用 _currentClassicDevice?.name
macAddress: _verifiedDeviceAddress!,
);
if (success) {
Logger.i(_tag, 'BLE设备关联成功');
// 关联成功后,转到等待BLE连接状态
_transition(PairingState.waitingBle);
} else {
_setError(ErrorType.associationFailed, 'BLE设备关联失败');
}
} catch (e) {
Logger.e(_tag, 'BLE设备关联异常: $e');
_setError(ErrorType.associationFailed, '设备关联失败,请重试');
}
}
/// 开始BLE连接
void _startBleConnection() async {
try {
@ -517,4 +572,14 @@ class PairingController extends GetxController {
void openBluetoothSettings() {
AppSettings.openAppSettings(type: AppSettingsType.bluetooth);
}
/// 清除设备关联(在需要重新配对时调用)
Future<void> clearDeviceAssociation() async {
try {
Logger.i(_tag, '清除设备关联');
await _bleManager.clearPairedDevices();
} catch (e) {
Logger.e(_tag, '清除设备关联失败: $e');
}
}
}

8
lib/modules/pairing/views/pairing_view.dart

@ -234,6 +234,8 @@ class PairingView extends GetView<PairingController> {
switch (state) {
case PairingState.completed:
return Icons.check_circle;
case PairingState.associating:
return Icons.link;
case PairingState.error:
final errorType = controller.errorType;
switch (errorType) {
@ -243,6 +245,8 @@ class PairingView extends GetView<PairingController> {
case ErrorType.noClassicDevice:
case ErrorType.deviceNotMatch:
return Icons.headphones_outlined;
case ErrorType.associationFailed:
return Icons.link_off;
default:
return Icons.error_outline;
}
@ -307,6 +311,8 @@ class PairingView extends GetView<PairingController> {
return '请先通过系统蓝牙连接DeapSound设备';
case PairingState.verifying:
return '正在验证设备...';
case PairingState.associating:
return '正在建立设备关联...';
case PairingState.waitingBle:
return '请稍候,正在完成配对...';
case PairingState.completed:
@ -324,6 +330,8 @@ class PairingView extends GetView<PairingController> {
return '请确保连接的是DeapSound设备';
case ErrorType.deviceBound:
return '该设备已被其他账号绑定';
case ErrorType.associationFailed:
return '设备关联失败,请重试';
case ErrorType.bleTimeout:
return '扫描超时,请确保设备在附近';
case ErrorType.networkError:

5
lib/modules/pairing/views/pairing_view_new.dart

@ -153,6 +153,11 @@ class PairingView extends GetView<PairingController> {
iconColor = Colors.orange;
break;
case PairingState.associating:
iconData = Icons.link;
iconColor = Colors.blue;
break;
case PairingState.waitingBle:
iconData = Icons.sync;
iconColor = Colors.blue;

Loading…
Cancel
Save