You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
328 lines
9.8 KiB
328 lines
9.8 KiB
import 'package:get/get.dart';
|
|
import 'dart:async';
|
|
import '../../../routes/app_routes.dart';
|
|
import '../../../core/utils/logger.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:classic_bluetooth/classic_bluetooth.dart' show BluetoothDevice;
|
|
import '../../../data/services/bluetooth_manager.dart';
|
|
import '../../../data/services/ble_manager.dart';
|
|
|
|
/// 连接状态枚举
|
|
enum ConnectionStatus {
|
|
disconnected, // 未连接
|
|
connecting, // 连接中
|
|
connected, // 已连接
|
|
failed // 连接失败
|
|
}
|
|
|
|
/// 主页控制器,管理设备连接状态和信息展示
|
|
class HomeController extends GetxController {
|
|
static HomeController get to => Get.find();
|
|
|
|
// 连接状态相关
|
|
final _connectionStatus = ConnectionStatus.disconnected.obs;
|
|
final _connectionErrorMsg = ''.obs;
|
|
final _bluetoothState = 'unknown'.obs;
|
|
|
|
// Getter方法
|
|
ConnectionStatus get connectionStatus => _connectionStatus.value;
|
|
String get connectionErrorMsg => _connectionErrorMsg.value;
|
|
String get bluetoothState => _bluetoothState.value;
|
|
BluetoothDevice? get currentDevice => _bluetoothManager.currentDevice;
|
|
Rx<DeviceInfo?> get deviceInfo => _bleManager.deviceInfo;
|
|
bool get isConnected => currentDevice != null;
|
|
|
|
// 设备详细信息的getter,从deviceInfo获取数据
|
|
final leftEarBattery = 0.obs;
|
|
final rightEarBattery = 0.obs;
|
|
final caseBattery = 0.obs;
|
|
final leftEarCharging = false.obs;
|
|
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;
|
|
caseBattery.value = newDeviceInfo?.caseBattery ?? 0;
|
|
leftEarCharging.value = newDeviceInfo?.leftEarCharging ?? false;
|
|
rightEarCharging.value = newDeviceInfo?.rightEarCharging ?? false;
|
|
caseCharging.value = newDeviceInfo?.caseCharging ?? false;
|
|
firmwareVersion.value = newDeviceInfo?.firmwareVersion ?? '';
|
|
}
|
|
|
|
// 监听和订阅
|
|
Worker? _deviceInfoWorker;
|
|
Worker? _bluetoothStateWorker;
|
|
Worker? _deviceWorker;
|
|
|
|
// 蓝牙服务
|
|
final _bluetoothManager = Get.find<BluetoothManager>();
|
|
final _bleManager = Get.find<BleManager>();
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
_initWithCachedInfo();
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
_deviceInfoWorker?.dispose();
|
|
_bluetoothStateWorker?.dispose();
|
|
_deviceWorker?.dispose();
|
|
super.onClose();
|
|
}
|
|
|
|
/// 使用缓存的蓝牙设备信息初始化
|
|
void _initWithCachedInfo() {
|
|
// 使用蓝牙服务中的当前状态
|
|
_bluetoothState.value = _bluetoothManager.bluetoothState;
|
|
|
|
// 根据当前设备状态设置连接状态
|
|
if (currentDevice != null) {
|
|
_connectionStatus.value = ConnectionStatus.connected;
|
|
_connectionErrorMsg.value = '';
|
|
updateDeviceInfo(_bleManager.deviceInfo.value);
|
|
Logger.info('主页加载缓存设备信息: ${currentDevice!.name}');
|
|
} else {
|
|
_connectionStatus.value = ConnectionStatus.disconnected;
|
|
if (_bluetoothState.value == 'off') {
|
|
_connectionErrorMsg.value = '蓝牙未开启';
|
|
} else {
|
|
_connectionErrorMsg.value = '未连接到设备';
|
|
}
|
|
}
|
|
|
|
// 设置监听器监听蓝牙服务状态变化
|
|
_setupStateListeners();
|
|
}
|
|
|
|
/// 设置状态监听器
|
|
void _setupStateListeners() {
|
|
// 设备信息监听 - 设备信息更新时自动触发UI更新
|
|
_deviceInfoWorker = ever(_bleManager.deviceInfo, (DeviceInfo? info) {
|
|
Logger.info('设备信息监听');
|
|
if (info != null) {
|
|
Logger.info('主页更新设备信息: ${info.toString()}');
|
|
updateDeviceInfo(info);
|
|
} else {
|
|
Logger.info('主页清空设备信息');
|
|
}
|
|
|
|
update();
|
|
});
|
|
|
|
// 蓝牙状态监听
|
|
_bluetoothStateWorker =
|
|
ever(_bluetoothManager.bluetoothState.obs, (String state) {
|
|
_bluetoothState.value = state;
|
|
|
|
// 如果蓝牙关闭,更新错误信息
|
|
if (state == 'off') {
|
|
_connectionErrorMsg.value = '蓝牙未开启';
|
|
_connectionStatus.value = ConnectionStatus.disconnected;
|
|
}
|
|
|
|
update();
|
|
});
|
|
|
|
// 设备连接状态监听 - 直接监听设备变化
|
|
_deviceWorker =
|
|
ever(_bluetoothManager.currentDeviceRx, (BluetoothDevice? device) {
|
|
if (device != null) {
|
|
// 设备已连接
|
|
if (_connectionStatus.value != ConnectionStatus.connected) {
|
|
_connectionStatus.value = ConnectionStatus.connected;
|
|
_connectionErrorMsg.value = '';
|
|
Logger.info('主页检测到设备已连接: ${device.name}');
|
|
}
|
|
} else if (_connectionStatus.value == ConnectionStatus.connected) {
|
|
// 设备已断开
|
|
_connectionStatus.value = ConnectionStatus.disconnected;
|
|
_connectionErrorMsg.value = '设备已断开连接';
|
|
|
|
Logger.info('主页检测到设备已断开连接');
|
|
}
|
|
|
|
update();
|
|
});
|
|
}
|
|
|
|
/// 刷新设备连接状态
|
|
/// 注意:此方法不会主动刷新设备,只更新UI状态
|
|
Future<void> refreshDeviceConnection() async {
|
|
// 更新当前状态以反映UI变化
|
|
bool hasDevice = currentDevice != null;
|
|
|
|
if (hasDevice) {
|
|
_connectionStatus.value = ConnectionStatus.connected;
|
|
_connectionErrorMsg.value = '';
|
|
await _bleManager.fetchDeviceInfo();
|
|
|
|
Logger.info('使用缓存设备信息: ${currentDevice!.name}');
|
|
} else {
|
|
if (_bluetoothState.value == 'off') {
|
|
_connectionErrorMsg.value = '蓝牙未开启';
|
|
} else {
|
|
_connectionErrorMsg.value = '未连接到设备';
|
|
}
|
|
_connectionStatus.value = ConnectionStatus.disconnected;
|
|
}
|
|
|
|
// 刷新UI
|
|
update();
|
|
}
|
|
|
|
// 导航和功能方法
|
|
|
|
/// 重新扫描设备
|
|
void rescanDevices() {
|
|
Get.toNamed(Routes.pairing);
|
|
}
|
|
|
|
/// 打开翻译功能
|
|
void openTranslation() {
|
|
Get.toNamed(Routes.translation);
|
|
}
|
|
|
|
/// 展示AI功能
|
|
void exploreAIFeatures() {
|
|
Get.toNamed(Routes.agent);
|
|
}
|
|
|
|
// UI辅助方法
|
|
|
|
/// 获取连接状态对应的颜色
|
|
Color getConnectionStatusColor() {
|
|
switch (_connectionStatus.value) {
|
|
case ConnectionStatus.connected:
|
|
return Colors.green;
|
|
case ConnectionStatus.connecting:
|
|
return Colors.amber;
|
|
case ConnectionStatus.failed:
|
|
return Colors.red;
|
|
case ConnectionStatus.disconnected:
|
|
default:
|
|
return Colors.grey;
|
|
}
|
|
}
|
|
|
|
/// 获取连接状态对应的文本
|
|
String getConnectionStatusText() {
|
|
if (bluetoothState == 'off') {
|
|
return 'bluetoothOff'.tr;
|
|
}
|
|
|
|
switch (_connectionStatus.value) {
|
|
case ConnectionStatus.connected:
|
|
return 'connected'.tr;
|
|
case ConnectionStatus.connecting:
|
|
return 'connecting'.tr;
|
|
case ConnectionStatus.failed:
|
|
return 'connectionFailure'.tr;
|
|
case ConnectionStatus.disconnected:
|
|
default:
|
|
return 'unconnected'.tr;
|
|
}
|
|
}
|
|
|
|
/// 获取设备名称
|
|
String getDeviceName() {
|
|
return currentDevice?.name ?? 'unknownEquipment'.tr;
|
|
}
|
|
|
|
/// 获取信号强度(模拟数据)
|
|
String getSignalStrength() {
|
|
if (!isConnected) {
|
|
return 'zeroSignal'.tr;
|
|
}
|
|
|
|
final random = DateTime.now().millisecondsSinceEpoch % 3;
|
|
switch (random) {
|
|
case 0:
|
|
return 'good'.tr;
|
|
case 1:
|
|
return 'fine'.tr;
|
|
default:
|
|
return 'excellent'.tr;
|
|
}
|
|
}
|
|
|
|
/// 获取设备ID
|
|
String getDeviceId() {
|
|
return deviceInfo.value?.address ?? currentDevice?.address ?? 'unknown'.tr;
|
|
}
|
|
|
|
/// 获取设备电量文本
|
|
String getBatteryText() {
|
|
return deviceInfo.value?.batteryLevel != null &&
|
|
deviceInfo.value!.batteryLevel > 0
|
|
? '${deviceInfo.value?.batteryLevel}%'
|
|
: 'unknown'.tr;
|
|
}
|
|
|
|
/// 获取耳机左右电量文本
|
|
String getEarbudsText() {
|
|
if (deviceInfo == null ||
|
|
(deviceInfo.value!.leftEarBattery <= 0 &&
|
|
deviceInfo.value!.rightEarBattery <= 0)) {
|
|
return 'unknown'.tr;
|
|
}
|
|
|
|
String leftStatus = deviceInfo.value!.leftEarBattery > 0
|
|
? '${deviceInfo.value!.leftEarBattery}%'
|
|
: 'N/A';
|
|
String rightStatus = deviceInfo.value!.rightEarBattery > 0
|
|
? '${deviceInfo.value!.rightEarBattery}%'
|
|
: 'N/A';
|
|
|
|
leftStatus =
|
|
deviceInfo.value!.leftEarCharging ? '$leftStatus ⚡' : leftStatus;
|
|
rightStatus =
|
|
deviceInfo.value!.rightEarCharging ? '$rightStatus ⚡' : rightStatus;
|
|
|
|
return '左耳: $leftStatus / 右耳: $rightStatus';
|
|
}
|
|
|
|
/// 获取充电仓电量文本
|
|
String getCaseText() {
|
|
if (deviceInfo.value == null || deviceInfo.value!.caseBattery <= 0) {
|
|
return 'unknown'.tr;
|
|
}
|
|
|
|
String caseStatus = '${deviceInfo.value!.caseBattery}%';
|
|
if (deviceInfo.value!.caseCharging) {
|
|
caseStatus = '$caseStatus ⚡';
|
|
}
|
|
|
|
return '充电仓: $caseStatus';
|
|
}
|
|
|
|
/// 获取充电状态文本
|
|
String getChargingText() {
|
|
if (deviceInfo == null) {
|
|
return 'unknown'.tr;
|
|
}
|
|
|
|
bool isCharging = deviceInfo.value!.leftEarCharging ||
|
|
deviceInfo.value!.rightEarCharging ||
|
|
deviceInfo.value!.caseCharging;
|
|
|
|
return isCharging ? 'charging'.tr : 'notCharging'.tr;
|
|
}
|
|
|
|
/// 获取设备版本文本
|
|
String getVersionText() {
|
|
return deviceInfo.value?.firmwareVersion.isNotEmpty == true
|
|
? deviceInfo.value!.firmwareVersion
|
|
: 'unknown'.tr;
|
|
}
|
|
}
|
|
|