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.

249 lines
7.8 KiB

import 'dart:async';
import 'dart:math' as math;
import 'package:get/get.dart';
import 'package:classic_bluetooth/classic_bluetooth.dart';
import 'package:deep_voice/core/utils/logger.dart';
import 'package:flutter/services.dart';
/// 蓝牙设备信息缓存模型
class DeviceInfo {
final String address;
final String name;
// 整体电池电量
final int batteryLevel;
// 详细电池信息
final int leftEarBattery;
final int rightEarBattery;
final int caseBattery;
// 充电状态
final bool leftEarCharging;
final bool rightEarCharging;
final bool caseCharging;
final String firmwareVersion;
final String productId;
final String colorId;
final DateTime lastUpdated;
DeviceInfo({
required this.address,
required this.name,
this.batteryLevel = 0,
this.leftEarBattery = 0,
this.rightEarBattery = 0,
this.caseBattery = 0,
this.leftEarCharging = false,
this.rightEarCharging = false,
this.caseCharging = false,
this.firmwareVersion = '',
this.productId = '',
this.colorId = '',
DateTime? lastUpdated,
}) : lastUpdated = lastUpdated ?? DateTime.now();
/// 创建更新后的设备信息副本
DeviceInfo copyWith({
String? address,
String? name,
int? batteryLevel,
int? leftEarBattery,
int? rightEarBattery,
int? caseBattery,
bool? leftEarCharging,
bool? rightEarCharging,
bool? caseCharging,
String? firmwareVersion,
String? productId,
String? colorId,
}) {
return DeviceInfo(
address: address ?? this.address,
name: name ?? this.name,
batteryLevel: batteryLevel ?? this.batteryLevel,
leftEarBattery: leftEarBattery ?? this.leftEarBattery,
rightEarBattery: rightEarBattery ?? this.rightEarBattery,
caseBattery: caseBattery ?? this.caseBattery,
leftEarCharging: leftEarCharging ?? this.leftEarCharging,
rightEarCharging: rightEarCharging ?? this.rightEarCharging,
caseCharging: caseCharging ?? this.caseCharging,
firmwareVersion: firmwareVersion ?? this.firmwareVersion,
productId: productId ?? this.productId,
colorId: colorId ?? this.colorId,
lastUpdated: DateTime.now(),
);
}
@override
String toString() {
return 'DeviceInfo(address: $address, name: $name, '
'battery: $batteryLevel%, L: $leftEarBattery%, R: $rightEarBattery%, Case: $caseBattery%, '
'charging: L:$leftEarCharging, R:$rightEarCharging, C:$caseCharging, '
'version: $firmwareVersion, productId: $productId, colorId: $colorId)';
}
}
/// 蓝牙服务 - 管理经典蓝牙服务,提供设备信息缓存
class BluetoothService extends GetxService {
static BluetoothService get to => Get.find<BluetoothService>();
// 蓝牙状态
final _bluetoothState = 'unknown'.obs;
String get bluetoothState => _bluetoothState.value;
// 当前经典蓝牙设备
final Rx<BluetoothDevice?> currentDeviceRx = Rx<BluetoothDevice?>(null);
BluetoothDevice? get currentDevice => currentDeviceRx.value;
// 设备信息缓存
final Rx<DeviceInfo?> _deviceInfo = Rx<DeviceInfo?>(null);
DeviceInfo? get deviceInfo => _deviceInfo.value;
// 表明当前连接类型,本服务只处理经典蓝牙
bool get isBleConnection => false;
// 订阅
StreamSubscription<BluetoothEvent>? _bluetoothSubscription;
/// 初始化
@override
void onInit() {
super.onInit();
Logger.info('蓝牙服务初始化');
// 设置蓝牙事件监听
_setupBluetoothListener();
}
/// 释放资源
@override
void onClose() {
_bluetoothSubscription?.cancel();
super.onClose();
}
/// 设置经典蓝牙事件监听
void _setupBluetoothListener() {
_bluetoothSubscription?.cancel();
try {
_bluetoothSubscription = ClassicBluetooth.events.listen(
(event) {
if (event.type == 'stateChanged' && event.state != null) {
_bluetoothState.value = event.state!;
Logger.info('蓝牙状态变更: ${event.state}');
// 如果蓝牙关闭,清除设备
if (event.state == 'off') {
currentDeviceRx.value = null;
_deviceInfo.value = null;
}
} else if (event.type == 'deviceConnected' && event.device != null) {
// 直接从事件中获取设备信息
final newDevice = event.device!;
// 更新当前设备
currentDeviceRx.value = newDevice;
Logger.info('经典蓝牙设备已连接: ${newDevice.name} (${newDevice.address})');
// 创建基本设备信息
if (_deviceInfo.value == null || _deviceInfo.value!.address != newDevice.address) {
_deviceInfo.value = DeviceInfo(
address: newDevice.address,
name: newDevice.name,
);
Logger.info('创建设备信息缓存: ${_deviceInfo.value}');
}
} else if (event.type == 'deviceDisconnected' && event.device != null) {
// 直接从事件中获取设备信息
final disconnectedDevice = event.device!;
Logger.info('经典蓝牙设备已断开: ${disconnectedDevice.name} (${disconnectedDevice.address})');
// 如果断开的是当前设备,清除当前设备
if (currentDeviceRx.value?.address == disconnectedDevice.address) {
currentDeviceRx.value = null;
// 不清除设备信息缓存,保留最后状态
Logger.info('已清除当前设备引用,保留最后设备信息缓存');
}
}
},
onError: (error) {
Logger.error('蓝牙事件流错误: $error');
},
);
} catch (e) {
Logger.error('设置蓝牙事件监听器失败: $e');
}
}
/// 刷新设备连接状态
Future<void> refreshDeviceConnection() async {
try {
// 检查经典蓝牙连接
final devices = await ClassicBluetooth.getConnectedDevices();
if (devices.isNotEmpty) {
final newDevice = devices.first;
// 更新当前设备
currentDeviceRx.value = newDevice;
Logger.info('已连接经典蓝牙设备: ${newDevice.name} (${newDevice.address})');
// 创建基本设备信息
if (_deviceInfo.value == null || _deviceInfo.value!.address != newDevice.address) {
_deviceInfo.value = DeviceInfo(
address: newDevice.address,
name: newDevice.name,
);
Logger.info('创建设备信息缓存: ${_deviceInfo.value}');
}
return;
}
// 没有任何连接
currentDeviceRx.value = null;
Logger.info('未找到已连接的蓝牙设备');
} catch (e) {
Logger.error('刷新设备连接失败: $e');
}
}
/// 检查蓝牙是否已启用
Future<bool> isBluetoothEnabled() async {
try {
final isEnabled = await ClassicBluetooth.isBluetoothEnabled();
_bluetoothState.value = isEnabled ? 'on' : 'off';
return isEnabled;
} catch (e) {
Logger.error('检查蓝牙状态失败: $e');
return false;
}
}
/// 启动BLE服务(不适用于此服务,仅为接口兼容)
Future<bool> startBleService(Map<String, dynamic> config) async {
Logger.warning('BluetoothService不支持BLE服务,请使用BleService');
return false;
}
/// 停止BLE服务(不适用于此服务,仅为接口兼容)
Future<bool> stopBleService() async {
Logger.warning('BluetoothService不支持BLE服务,请使用BleService');
return false;
}
/// 注册服务
static Future<BluetoothService> init() async {
if (!Get.isRegistered<BluetoothService>()) {
Get.put(BluetoothService(), permanent: true);
}
return Future.value(Get.find<BluetoothService>());
}
}