|
|
|
@ -6,12 +6,11 @@ import 'package:flutter/material.dart'; |
|
|
|
import '../../../data/services/bluetooth_manager.dart'; |
|
|
|
import '../../../data/services/ble_manager.dart'; |
|
|
|
|
|
|
|
/// 连接状态枚举 |
|
|
|
enum ConnectionStatus { |
|
|
|
disconnected, // 未连接 |
|
|
|
connecting, // 连接中 |
|
|
|
connected, // 已连接 |
|
|
|
failed // 连接失败 |
|
|
|
disconnected, |
|
|
|
connecting, |
|
|
|
connected, |
|
|
|
failed |
|
|
|
} |
|
|
|
|
|
|
|
/// 主页控制器,管理设备连接状态和信息展示 |
|
|
|
@ -19,20 +18,14 @@ class HomeController extends GetxController { |
|
|
|
static const String _tag = 'HomeCtrl'; |
|
|
|
static HomeController get to => Get.find(); |
|
|
|
|
|
|
|
// 连接状态相关 |
|
|
|
final _isFullyConnected = false.obs; |
|
|
|
|
|
|
|
// 缓存最后连接的设备信息,用于断开后短暂显示 |
|
|
|
String? _lastConnectedDeviceName; |
|
|
|
String? _lastConnectedDeviceAddress; |
|
|
|
|
|
|
|
// Getter方法 |
|
|
|
bool get isFullyConnected => _isFullyConnected.value; |
|
|
|
RxBool get isFullyConnectedRx => _isFullyConnected; // 响应式getter供UI使用 |
|
|
|
RxBool get isFullyConnectedRx => _isFullyConnected; |
|
|
|
BluetoothDevice? get currentDevice => _bluetoothManager.currentDevice; |
|
|
|
Rx<DeviceInfo?> get deviceInfo => _bleManager.deviceInfo; |
|
|
|
|
|
|
|
// 设备详细信息的getter,从deviceInfo获取数据 |
|
|
|
final leftEarBattery = 0.obs; |
|
|
|
final rightEarBattery = 0.obs; |
|
|
|
final caseBattery = 0.obs; |
|
|
|
@ -40,15 +33,6 @@ class HomeController extends GetxController { |
|
|
|
final rightEarCharging = false.obs; |
|
|
|
final caseCharging = false.obs; |
|
|
|
final firmwareVersion = ''.obs; |
|
|
|
|
|
|
|
// int get leftEarBattery => deviceInfo?.leftEarBattery ?? 0; |
|
|
|
// int get rightEarBattery => deviceInfo?.rightEarBattery ?? 0; |
|
|
|
// int get caseBattery => deviceInfo?.caseBattery ?? 0; |
|
|
|
// bool get leftEarCharging => deviceInfo?.leftEarCharging ?? false; |
|
|
|
// bool get rightEarCharging => deviceInfo?.rightEarCharging ?? false; |
|
|
|
// bool get caseCharging => deviceInfo?.caseCharging ?? false; |
|
|
|
// String get firmwareVersion => deviceInfo?.firmwareVersion ?? ''; |
|
|
|
/// 当有新的deviceInfo时更新所有Observable变量 |
|
|
|
void updateDeviceInfo(DeviceInfo? newDeviceInfo) { |
|
|
|
leftEarBattery.value = newDeviceInfo?.leftEarBattery ?? 0; |
|
|
|
rightEarBattery.value = newDeviceInfo?.rightEarBattery ?? 0; |
|
|
|
@ -59,12 +43,10 @@ class HomeController extends GetxController { |
|
|
|
firmwareVersion.value = newDeviceInfo?.firmwareVersion ?? ''; |
|
|
|
} |
|
|
|
|
|
|
|
// 监听和订阅 |
|
|
|
Worker? _deviceInfoWorker; |
|
|
|
Worker? _classicBluetoothWorker; |
|
|
|
Worker? _bleConnectionWorker; |
|
|
|
|
|
|
|
// 蓝牙服务 |
|
|
|
final _bluetoothManager = Get.find<BluetoothManager>(); |
|
|
|
final _bleManager = Get.find<BleManager>(); |
|
|
|
@override |
|
|
|
@ -81,112 +63,73 @@ class HomeController extends GetxController { |
|
|
|
super.onClose(); |
|
|
|
} |
|
|
|
|
|
|
|
/// 初始化 |
|
|
|
void _initWithCachedInfo() { |
|
|
|
// 设置监听器 |
|
|
|
_setupStateListeners(); |
|
|
|
|
|
|
|
// 立即检查初始连接状态 |
|
|
|
_checkConnectionStatus(); |
|
|
|
} |
|
|
|
|
|
|
|
/// 设置状态监听器 |
|
|
|
void _setupStateListeners() { |
|
|
|
// 设备信息监听 |
|
|
|
_deviceInfoWorker = ever(_bleManager.deviceInfo, (DeviceInfo? info) { |
|
|
|
if (info != null) { |
|
|
|
Logger.d(_tag, '更新设备信息: ${info.toString()}'); |
|
|
|
updateDeviceInfo(info); |
|
|
|
} |
|
|
|
update(); |
|
|
|
}); |
|
|
|
|
|
|
|
// 经典蓝牙连接监听 |
|
|
|
_classicBluetoothWorker = ever(_bluetoothManager.currentDeviceRx, (BluetoothDevice? device) { |
|
|
|
Logger.d(_tag, '经典蓝牙: ${device != null ? "已连接" : "已断开"}'); |
|
|
|
// 保存设备信息用于断开后显示 |
|
|
|
if (device != null) { |
|
|
|
_lastConnectedDeviceName = device.name; |
|
|
|
_lastConnectedDeviceAddress = device.address; |
|
|
|
} |
|
|
|
// 立即检查状态,不使用延迟 |
|
|
|
_checkConnectionStatus(); |
|
|
|
}); |
|
|
|
|
|
|
|
// BLE连接监听 |
|
|
|
_bleConnectionWorker = ever(_bleManager.connectionStateRx, (int state) { |
|
|
|
Logger.d(_tag, 'BLE状态变化: $state (${state == 2 ? "已连接" : "未连接"})'); |
|
|
|
// 立即检查状态,不使用延迟 |
|
|
|
_checkConnectionStatus(); |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
/// 刷新设备连接状态 |
|
|
|
Future<void> refreshDeviceConnection() async { |
|
|
|
await _checkConnectionStatus(); |
|
|
|
} |
|
|
|
|
|
|
|
// 导航和功能方法 |
|
|
|
|
|
|
|
/// 重新扫描设备 |
|
|
|
void rescanDevices() { |
|
|
|
Get.toNamed(Routes.pairing); |
|
|
|
} |
|
|
|
|
|
|
|
/// 打开翻译功能 |
|
|
|
void openTranslation() { |
|
|
|
Get.toNamed(Routes.translation); |
|
|
|
} |
|
|
|
|
|
|
|
/// 展示AI功能 |
|
|
|
void exploreAIFeatures() { |
|
|
|
Get.toNamed(Routes.agent); |
|
|
|
} |
|
|
|
|
|
|
|
// UI辅助方法 |
|
|
|
|
|
|
|
/// 检查连接状态 |
|
|
|
Future<void> _checkConnectionStatus() async { |
|
|
|
try { |
|
|
|
// 主动从原生层获取最新的BLE状态 |
|
|
|
final currentBleState = await _bleManager.getConnectionState(); |
|
|
|
|
|
|
|
bool hasClassicBluetooth = currentDevice != null; |
|
|
|
bool hasBleConnection = currentBleState == 2; // 使用实时查询的状态 |
|
|
|
|
|
|
|
Logger.d(_tag, '连接状态检查: 经典蓝牙=$hasClassicBluetooth, BLE=$hasBleConnection (实时状态值=$currentBleState)'); |
|
|
|
|
|
|
|
bool hasBleConnection = currentBleState == 2; |
|
|
|
bool wasConnected = _isFullyConnected.value; |
|
|
|
bool isNowConnected = hasClassicBluetooth && hasBleConnection; |
|
|
|
|
|
|
|
// 状态一致性检查:如果声称已连接但没有设备信息,强制断开 |
|
|
|
if (isNowConnected && currentDevice == null) { |
|
|
|
Logger.w(_tag, '状态不一致:已连接但无设备信息,强制更新为未连接'); |
|
|
|
isNowConnected = false; |
|
|
|
} |
|
|
|
|
|
|
|
// 只有状态真正改变时才更新 |
|
|
|
if (_isFullyConnected.value != isNowConnected) { |
|
|
|
// 立即同步更新状态 |
|
|
|
_isFullyConnected.value = isNowConnected; |
|
|
|
Logger.d(_tag, '连接状态变更: ${wasConnected ? "已连接" : "未连接"} -> ${isNowConnected ? "已连接" : "未连接"}'); |
|
|
|
|
|
|
|
// 立即触发UI更新,不使用延迟 |
|
|
|
_isFullyConnected.refresh(); |
|
|
|
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(); |
|
|
|
@ -195,43 +138,31 @@ class HomeController extends GetxController { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// 获取连接状态对应的颜色 |
|
|
|
Color getConnectionStatusColor() { |
|
|
|
final isConnected = _isFullyConnected.value; |
|
|
|
Logger.d(_tag, 'getConnectionStatusColor called: isConnected=$isConnected'); |
|
|
|
return isConnected ? Colors.green : Colors.grey; |
|
|
|
return _isFullyConnected.value ? Colors.green : Colors.grey; |
|
|
|
} |
|
|
|
|
|
|
|
/// 获取连接状态对应的文本 |
|
|
|
String getConnectionStatusText() { |
|
|
|
final isConnected = _isFullyConnected.value; |
|
|
|
Logger.d(_tag, 'getConnectionStatusText called: isConnected=$isConnected'); |
|
|
|
return isConnected ? 'connected'.tr : 'unconnected'.tr; |
|
|
|
return _isFullyConnected.value ? 'connected'.tr : 'unconnected'.tr; |
|
|
|
} |
|
|
|
|
|
|
|
/// 判断是否应该显示设备信息(即使未完全连接) |
|
|
|
bool get shouldShowDeviceInfo => currentDevice != null; |
|
|
|
|
|
|
|
/// 获取设备名称 |
|
|
|
String getDeviceName() { |
|
|
|
// 状态一致性检查 |
|
|
|
if (_isFullyConnected.value && currentDevice == null) { |
|
|
|
Logger.w(_tag, '状态不一致:显示已连接但无设备信息'); |
|
|
|
// 立即重新检查状态 |
|
|
|
_checkConnectionStatus(); |
|
|
|
} |
|
|
|
|
|
|
|
// 优先使用当前设备名称 |
|
|
|
if (currentDevice?.name != null && currentDevice!.name!.isNotEmpty) { |
|
|
|
return currentDevice!.name!; |
|
|
|
final deviceName = currentDevice?.name; |
|
|
|
if (deviceName != null && deviceName.isNotEmpty) { |
|
|
|
return deviceName; |
|
|
|
} |
|
|
|
|
|
|
|
// 如果当前没有设备但有BLE设备信息,使用BLE的设备名 |
|
|
|
if (deviceInfo.value?.name != null && deviceInfo.value!.name.isNotEmpty) { |
|
|
|
return deviceInfo.value!.name; |
|
|
|
final bleDeviceName = deviceInfo.value?.name; |
|
|
|
if (bleDeviceName != null && bleDeviceName.isNotEmpty) { |
|
|
|
return bleDeviceName; |
|
|
|
} |
|
|
|
|
|
|
|
// 如果刚断开连接,使用缓存的设备名称(提供更好的用户体验) |
|
|
|
if (!_isFullyConnected.value && _lastConnectedDeviceName != null && _lastConnectedDeviceName!.isNotEmpty) { |
|
|
|
return _lastConnectedDeviceName!; |
|
|
|
} |
|
|
|
@ -239,7 +170,6 @@ class HomeController extends GetxController { |
|
|
|
return 'unknownEquipment'.tr; |
|
|
|
} |
|
|
|
|
|
|
|
/// 获取信号强度(模拟数据) |
|
|
|
String getSignalStrength() { |
|
|
|
if (!_isFullyConnected.value) { |
|
|
|
return 'zeroSignal'.tr; |
|
|
|
@ -256,12 +186,10 @@ class HomeController extends GetxController { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// 获取设备ID |
|
|
|
String getDeviceId() { |
|
|
|
return deviceInfo.value?.address ?? currentDevice?.address ?? 'unknown'.tr; |
|
|
|
} |
|
|
|
|
|
|
|
/// 获取设备电量文本 |
|
|
|
String getBatteryText() { |
|
|
|
return deviceInfo.value?.batteryLevel != null && |
|
|
|
deviceInfo.value!.batteryLevel > 0 |
|
|
|
@ -269,9 +197,8 @@ class HomeController extends GetxController { |
|
|
|
: 'unknown'.tr; |
|
|
|
} |
|
|
|
|
|
|
|
/// 获取耳机左右电量文本 |
|
|
|
String getEarbudsText() { |
|
|
|
if (deviceInfo == null || |
|
|
|
if (deviceInfo.value == null || |
|
|
|
(deviceInfo.value!.leftEarBattery <= 0 && |
|
|
|
deviceInfo.value!.rightEarBattery <= 0 || |
|
|
|
deviceInfo.value!.caseBattery > 100)) { |
|
|
|
@ -293,7 +220,6 @@ class HomeController extends GetxController { |
|
|
|
return '左耳: $leftStatus / 右耳: $rightStatus'; |
|
|
|
} |
|
|
|
|
|
|
|
/// 获取充电仓电量文本 |
|
|
|
String getCaseText() { |
|
|
|
if (deviceInfo.value == null || |
|
|
|
deviceInfo.value!.caseBattery <= 0 || |
|
|
|
@ -309,9 +235,8 @@ class HomeController extends GetxController { |
|
|
|
return '充电仓: $caseStatus'; |
|
|
|
} |
|
|
|
|
|
|
|
/// 获取充电状态文本 |
|
|
|
String getChargingText() { |
|
|
|
if (deviceInfo == null) { |
|
|
|
if (deviceInfo.value == null) { |
|
|
|
return 'unknown'.tr; |
|
|
|
} |
|
|
|
|
|
|
|
@ -322,7 +247,6 @@ class HomeController extends GetxController { |
|
|
|
return isCharging ? 'charging'.tr : 'notCharging'.tr; |
|
|
|
} |
|
|
|
|
|
|
|
/// 获取设备版本文本 |
|
|
|
String getVersionText() { |
|
|
|
return deviceInfo.value?.firmwareVersion.isNotEmpty == true |
|
|
|
? deviceInfo.value!.firmwareVersion |
|
|
|
|