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.
765 lines
24 KiB
765 lines
24 KiB
import 'dart:convert';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:app_settings/app_settings.dart';
|
|
import 'package:deep_voice/data/models/appconfig.dart';
|
|
import 'package:deep_voice/data/models/user_Info.dart';
|
|
import 'package:deep_voice/data/services/network/api.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'dart:async';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
import '../../../routes/app_routes.dart';
|
|
import '../../../core/utils/logger.dart';
|
|
import 'dart:io';
|
|
import '../../../data/services/bluetooth_manager.dart';
|
|
import '../../../data/services/ble_manager.dart';
|
|
import '../../../core/utils/permission_util.dart';
|
|
|
|
/// 配对状态枚举 - 简化版本
|
|
enum PairingState {
|
|
idle, // 空闲/初始状态
|
|
checking, // 检查中(蓝牙、权限等)
|
|
waitingClassic, // 等待经典蓝牙连接
|
|
verifying, // 验证设备
|
|
binding, //确认绑定设备
|
|
manualbinding, //手动绑定设备
|
|
associating, // 正在进行BLE设备关联
|
|
waitingBle, //等待BLE连接
|
|
completed, //配对完成
|
|
error, // 错误状态
|
|
}
|
|
|
|
/// 错误类型枚举
|
|
enum ErrorType {
|
|
none,
|
|
bluetoothOff, // 蓝牙关闭
|
|
noPermission, // 无权限
|
|
noClassicDevice, // 无经典蓝牙设备
|
|
deviceNotMatch, // 设备不匹配
|
|
deviceBound, // 设备已被绑定
|
|
associationFailed, // 关联失败
|
|
bleTimeout, // BLE连接超时
|
|
authnFailed, // 授权失败
|
|
networkError, // 网络错误
|
|
}
|
|
|
|
/// 配对控制器 - 基于简化状态机的实现
|
|
class PairingController extends GetxController {
|
|
static const String _tag = 'PairingCtrl';
|
|
static PairingController get to => Get.find();
|
|
|
|
// ========== 状态管理 ==========
|
|
final _currentState = PairingState.idle.obs;
|
|
final _errorType = ErrorType.none.obs;
|
|
final _errorMessage = ''.obs;
|
|
|
|
PairingState get currentState => _currentState.value;
|
|
ErrorType get errorType => _errorType.value;
|
|
String get errorMessage => _errorMessage.value;
|
|
|
|
// ========== UI状态 ==========
|
|
final statusText = ''.obs;
|
|
final isLoading = false.obs;
|
|
final showConnectButton = false.obs;
|
|
final showRetryButton = false.obs;
|
|
final showBindButton = false.obs;
|
|
final showRetryChectButton = false.obs;
|
|
final showAutoCodeInput = false.obs;
|
|
final showSkipButton = false.obs;
|
|
// 增加临时跳过绑定按钮状态
|
|
final showSkipBindingButton = false.obs; // 新增临时跳过绑定按钮
|
|
|
|
final connectButtonText = '连接设备'.obs;
|
|
final retryButtonText = '重试'.obs;
|
|
final deviceCode = ''.obs;
|
|
|
|
// ========== 监听器管理 ==========
|
|
final List<Worker> _workers = [];
|
|
Timer? _bleTimeoutTimer;
|
|
|
|
// ========== 依赖服务 ==========
|
|
late final BluetoothManager _bluetoothManager;
|
|
late final BleManager _bleManager;
|
|
|
|
// ========== 当前设备信息 ==========
|
|
BluetoothDevice? _currentClassicDevice;
|
|
String? _verifiedDeviceAddress;
|
|
TextEditingController codeInputController = TextEditingController();
|
|
|
|
// Public getter for view access
|
|
BluetoothDevice? get currentDevice => _currentClassicDevice;
|
|
|
|
@override
|
|
void onInit() {
|
|
super.onInit();
|
|
Logger.i(_tag, '配对控制器初始化');
|
|
|
|
// 确保服务已初始化
|
|
_bluetoothManager = Get.find<BluetoothManager>();
|
|
_bleManager = Get.find<BleManager>();
|
|
|
|
// 集中设置所有监听器
|
|
_setupAllListeners();
|
|
|
|
// 开始初始状态检查
|
|
// 延迟稍长时间,确保BluetoothManager有足够时间获取已连接设备
|
|
Future.delayed(const Duration(milliseconds: 300), () {
|
|
_startInitialCheck();
|
|
});
|
|
}
|
|
|
|
@override
|
|
void onClose() {
|
|
Logger.i(_tag, '配对控制器销毁');
|
|
// 清理所有Worker
|
|
for (var worker in _workers) {
|
|
worker.dispose();
|
|
}
|
|
_workers.clear();
|
|
|
|
// 清理定时器
|
|
_bleTimeoutTimer?.cancel();
|
|
|
|
super.onClose();
|
|
}
|
|
|
|
// ==================== 监听器设置 ====================
|
|
|
|
/// 集中设置所有监听器
|
|
void _setupAllListeners() {
|
|
// 1. 监听蓝牙开关状态
|
|
_setupBluetoothStateListener();
|
|
|
|
// 2. 监听经典蓝牙连接状态
|
|
_setupClassicConnectionListener();
|
|
|
|
// 3. 监听BLE连接状态
|
|
_setupBleConnectionListener();
|
|
}
|
|
|
|
/// 监听蓝牙开关状态
|
|
void _setupBluetoothStateListener() {
|
|
_workers.add(ever(_bluetoothManager.bluetoothStateRx, (String state) {
|
|
Logger.d(_tag, '蓝牙状态变化: $state');
|
|
_handleBluetoothStateChange(state);
|
|
}));
|
|
}
|
|
|
|
/// 监听经典蓝牙连接状态
|
|
void _setupClassicConnectionListener() {
|
|
_workers
|
|
.add(ever(_bluetoothManager.currentDeviceRx, (BluetoothDevice? device) {
|
|
Logger.d(_tag, '经典蓝牙设备变化: ${device?.name}');
|
|
_handleClassicDeviceChange(device);
|
|
}));
|
|
}
|
|
|
|
/// 监听BLE连接状态
|
|
void _setupBleConnectionListener() {
|
|
_workers.add(ever(_bleManager.connectionStateRx, (int state) {
|
|
Logger.d(_tag, 'BLE连接状态变化: $state');
|
|
_handleBleStateChange(state);
|
|
}));
|
|
}
|
|
|
|
// ==================== 状态处理 ====================
|
|
|
|
/// 处理蓝牙开关状态变化
|
|
void _handleBluetoothStateChange(String state) {
|
|
if (state == 'off') {
|
|
// 蓝牙关闭,进入错误状态
|
|
_setError(ErrorType.bluetoothOff, '请开启蓝牙');
|
|
} else if (state == 'on' && _errorType.value == ErrorType.bluetoothOff) {
|
|
// 蓝牙重新开启,恢复流程
|
|
Logger.i(_tag, '检测到蓝牙已开启,自动恢复配对流程');
|
|
_clearError();
|
|
// 延迟一下确保蓝牙服务完全就绪
|
|
Future.delayed(const Duration(milliseconds: 500), () {
|
|
_checkCurrentStatus();
|
|
});
|
|
}
|
|
}
|
|
|
|
/// 处理经典蓝牙设备变化
|
|
void _handleClassicDeviceChange(BluetoothDevice? device) {
|
|
_currentClassicDevice = device;
|
|
|
|
switch (_currentState.value) {
|
|
case PairingState.waitingClassic:
|
|
if (device != null) {
|
|
// 有设备连接,进入验证阶段
|
|
Logger.i(_tag, '检测到经典蓝牙设备连接,开始验证');
|
|
_transition(PairingState.verifying);
|
|
_verifyDevice(device);
|
|
}
|
|
break;
|
|
|
|
case PairingState.error:
|
|
// 如果在错误状态下检测到设备连接,且错误是无设备连接,则自动恢复
|
|
if (device != null && _errorType.value == ErrorType.noClassicDevice) {
|
|
Logger.i(_tag, '检测到设备重新连接,自动恢复配对流程');
|
|
_clearError();
|
|
_transition(PairingState.verifying);
|
|
_verifyDevice(device);
|
|
}
|
|
break;
|
|
|
|
case PairingState.verifying:
|
|
case PairingState.waitingBle:
|
|
case PairingState.completed:
|
|
if (device == null) {
|
|
// 设备断开,返回等待连接状态
|
|
_setError(ErrorType.noClassicDevice, '设备已断开');
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/// 处理BLE状态变化
|
|
void _handleBleStateChange(int state) {
|
|
if (_currentState.value == PairingState.waitingBle) {
|
|
if (state == 2) {
|
|
// BLE已连接
|
|
_bleTimeoutTimer?.cancel();
|
|
_transition(PairingState.completed);
|
|
}
|
|
}
|
|
|
|
// 如果在完成状态下BLE断开,显示警告但不改变状态
|
|
if (_currentState.value == PairingState.completed && state != 2) {
|
|
Logger.w(_tag, 'BLE连接已断开,但配对流程已完成');
|
|
}
|
|
}
|
|
|
|
// ==================== 状态转换 ====================
|
|
|
|
/// 状态转换
|
|
void _transition(PairingState newState) {
|
|
final oldState = _currentState.value;
|
|
_currentState.value = newState;
|
|
Logger.i(_tag, '状态转换: $oldState -> $newState');
|
|
|
|
// 根据新状态执行相应操作
|
|
_onStateChanged(newState);
|
|
}
|
|
|
|
/// 状态变化处理
|
|
void _onStateChanged(PairingState state) {
|
|
// 重置UI状态
|
|
isLoading.value = false;
|
|
showConnectButton.value = false;
|
|
showRetryButton.value = false;
|
|
showSkipBindingButton.value = false; // 重置临时跳过绑定按钮
|
|
showSkipButton.value = false;
|
|
showAutoCodeInput.value = false;
|
|
showBindButton.value = false;
|
|
showRetryChectButton.value = false;
|
|
switch (state) {
|
|
case PairingState.idle:
|
|
statusText.value = '准备开始配对';
|
|
break;
|
|
|
|
case PairingState.checking:
|
|
statusText.value = '正在检查环境...';
|
|
isLoading.value = true;
|
|
break;
|
|
|
|
case PairingState.waitingClassic:
|
|
statusText.value = '请确保耳机已开启并进入配对模式';
|
|
showConnectButton.value = true;
|
|
showSkipButton.value = true;
|
|
|
|
connectButtonText.value = '前往蓝牙设置';
|
|
break;
|
|
|
|
case PairingState.verifying:
|
|
statusText.value = '正在验证设备...';
|
|
isLoading.value = true;
|
|
break;
|
|
case PairingState.binding:
|
|
statusText.value = '确认绑定';
|
|
isLoading.value = true;
|
|
showBindButton.value = true;
|
|
showRetryChectButton.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;
|
|
// 延迟一下再调用,给BLE管理器时间更新状态
|
|
Future.delayed(const Duration(milliseconds: 200), () {
|
|
_startBleConnection();
|
|
});
|
|
break;
|
|
case PairingState.manualbinding:
|
|
statusText.value = '需要手动绑定授权码...';
|
|
isLoading.value = false;
|
|
showAutoCodeInput.value = true;
|
|
// showSkipButton.value = true;
|
|
showSkipBindingButton.value = true; // 显示临时跳过绑定按钮
|
|
break;
|
|
case PairingState.completed:
|
|
statusText.value = '配对成功!';
|
|
isLoading.value = false;
|
|
_navigateToHome();
|
|
break;
|
|
|
|
case PairingState.error:
|
|
statusText.value = _errorMessage.value;
|
|
isLoading.value = false;
|
|
showSkipButton.value = true;
|
|
|
|
// 根据错误类型决定显示哪个按钮和按钮文本
|
|
switch (_errorType.value) {
|
|
case ErrorType.bluetoothOff:
|
|
showConnectButton.value = true;
|
|
connectButtonText.value = '开启蓝牙';
|
|
break;
|
|
case ErrorType.noClassicDevice:
|
|
showConnectButton.value = true;
|
|
connectButtonText.value = '前往蓝牙设置';
|
|
break;
|
|
case ErrorType.noPermission:
|
|
showRetryButton.value = true;
|
|
retryButtonText.value = '授予权限';
|
|
break;
|
|
case ErrorType.associationFailed:
|
|
showRetryButton.value = true;
|
|
retryButtonText.value = '重新关联';
|
|
break;
|
|
case ErrorType.authnFailed:
|
|
showRetryButton.value = true;
|
|
retryButtonText.value = '重新授权';
|
|
break;
|
|
default:
|
|
showRetryButton.value = true;
|
|
retryButtonText.value = '重试';
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// ==================== 错误处理 ====================
|
|
|
|
/// 设置错误状态
|
|
void _setError(ErrorType type, String message) {
|
|
_errorType.value = type;
|
|
_errorMessage.value = message;
|
|
_transition(PairingState.error);
|
|
}
|
|
|
|
/// 清除错误状态
|
|
void _clearError() {
|
|
_errorType.value = ErrorType.none;
|
|
_errorMessage.value = '';
|
|
}
|
|
|
|
// ==================== 核心流程 ====================
|
|
|
|
/// 开始初始检查
|
|
void _startInitialCheck() {
|
|
_transition(PairingState.checking);
|
|
_checkCurrentStatus();
|
|
}
|
|
|
|
/// 检查当前状态并决定下一步
|
|
void _checkCurrentStatus() async {
|
|
try {
|
|
// 1. 检查蓝牙状态
|
|
if (_bluetoothManager.bluetoothState == 'off') {
|
|
_setError(ErrorType.bluetoothOff, '请开启蓝牙');
|
|
return;
|
|
}
|
|
|
|
// 2. 检查权限
|
|
if (!await _checkPermissions()) {
|
|
_setError(ErrorType.noPermission, '请授予必要权限');
|
|
return;
|
|
}
|
|
|
|
// 3. 先刷新设备连接状态,确保获取最新的连接信息
|
|
await _bluetoothManager.refreshDeviceConnection();
|
|
|
|
// 4. 检查经典蓝牙连接
|
|
final classicDevice = _bluetoothManager.currentDevice;
|
|
if (classicDevice == null) {
|
|
_transition(PairingState.waitingClassic);
|
|
return;
|
|
}
|
|
|
|
// 5. 如果有设备,进行验证
|
|
_currentClassicDevice = classicDevice;
|
|
_transition(PairingState.verifying);
|
|
await _verifyDevice(classicDevice);
|
|
} catch (e) {
|
|
Logger.e(_tag, '状态检查失败: $e');
|
|
_setError(ErrorType.networkError, '检查失败,请重试');
|
|
}
|
|
}
|
|
|
|
/// 检查权限
|
|
Future<bool> _checkPermissions() async {
|
|
// Android权限检查
|
|
if (Platform.isAndroid) {
|
|
// 检查蓝牙相关权限
|
|
final bluetoothScan = await Permission.bluetoothScan.request();
|
|
final bluetoothConnect = await Permission.bluetoothConnect.request();
|
|
final location = await Permission.locationWhenInUse.request();
|
|
|
|
return bluetoothScan.isGranted &&
|
|
bluetoothConnect.isGranted &&
|
|
location.isGranted;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/// 验证设备
|
|
Future<void> _verifyDevice(BluetoothDevice device) async {
|
|
try {
|
|
Logger.i(_tag, '开始验证设备: ${device.name} (${device.address})');
|
|
final result = await authbindingDevice(device);
|
|
if (result == 2) {
|
|
//验证失败 进入手动授权
|
|
await connectble(device);
|
|
} else if (result == 1) {
|
|
//跳转绑定界面
|
|
//验证失败 进入手动授权
|
|
if (currentDevice != null) {
|
|
_transition(PairingState.binding);
|
|
} else {
|
|
_transition(PairingState.checking);
|
|
_checkCurrentStatus();
|
|
}
|
|
} else {
|
|
final authcode_open = AppConfig.env("APP_AUTHCODE_OPEN") ?? "";
|
|
if (authcode_open == "true") {
|
|
//验证失败 进入手动授权
|
|
_transition(PairingState.manualbinding);
|
|
} else {
|
|
_setError(ErrorType.deviceNotMatch, '请连接 DeepSound 设备');
|
|
}
|
|
}
|
|
} catch (e) {
|
|
Logger.e(_tag, '设备验证异常: $e');
|
|
_setError(ErrorType.networkError, '验证失败,请重试');
|
|
}
|
|
}
|
|
|
|
//连接ble
|
|
Future<void> connectble(BluetoothDevice device) async {
|
|
Logger.i(_tag, '设备验证通过');
|
|
_verifiedDeviceAddress = device.address;
|
|
// 检查是否已有BLE关联
|
|
final pairedMacAddress = await _bleManager.getPairedMacAddress();
|
|
Logger.i(_tag, '已关联的MAC地址: $pairedMacAddress');
|
|
|
|
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设备关联');
|
|
_transition(PairingState.associating);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/// 开始设备关联
|
|
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 {
|
|
// 设置超时定时器
|
|
_bleTimeoutTimer?.cancel();
|
|
_bleTimeoutTimer = Timer(const Duration(seconds: 30), () {
|
|
if (_currentState.value == PairingState.waitingBle) {
|
|
_setError(ErrorType.bleTimeout, 'BLE连接超时,请重试');
|
|
}
|
|
});
|
|
|
|
// 检查是否已连接 - 直接从原生层获取最新状态
|
|
final currentBleState = await _bleManager.getConnectionState();
|
|
Logger.i(_tag, 'BLE当前连接状态: $currentBleState');
|
|
|
|
if (currentBleState == 2) {
|
|
// BleConnectionState.connected
|
|
Logger.i(_tag, 'BLE已经连接,直接完成配对');
|
|
_bleTimeoutTimer?.cancel();
|
|
_transition(PairingState.completed);
|
|
return;
|
|
}
|
|
|
|
// 注册后台扫描以开始BLE配对
|
|
if (_verifiedDeviceAddress != null) {
|
|
final success = await _bleManager.registerBackgroundScan(
|
|
macAddress: _verifiedDeviceAddress);
|
|
if (!success && _currentState.value == PairingState.waitingBle) {
|
|
_setError(ErrorType.bleTimeout, 'BLE配对启动失败');
|
|
}
|
|
}
|
|
} catch (e) {
|
|
Logger.e(_tag, 'BLE连接失败: $e');
|
|
_setError(ErrorType.bleTimeout, 'BLE连接失败');
|
|
}
|
|
}
|
|
|
|
//自动绑定设备 0 未合作商 1 合作商 2,已绑定
|
|
Future<int> authbindingDevice(BluetoothDevice device) async {
|
|
if (User.instance.earphonemac == device.address) {
|
|
// 已经绑定
|
|
return 2;
|
|
}
|
|
|
|
// 检查设备名称是否包含 DeepSound 或 DeapSound
|
|
final deviceName = device.name;
|
|
print('获取到 deviceName: $deviceName');
|
|
if (deviceName.contains('DeepSound') || deviceName.contains('DeapSound')) {
|
|
await _bleManager.startScan();
|
|
await Future.delayed(const Duration(seconds: 1));
|
|
// 尝试最多读取 3 次设备信息,每次间隔 1 秒
|
|
Map<String, String>? deviceinfo;
|
|
for (int i = 0; i < 3; i++) {
|
|
deviceinfo = await _bleManager.getDeviceInfo(device.address);
|
|
print('获取到 deviceinfo: $deviceinfo');
|
|
if (deviceinfo != null) {
|
|
break;
|
|
}
|
|
await Future.delayed(Duration(seconds: 1));
|
|
}
|
|
print('获取到 deviceinfo: $deviceinfo');
|
|
if (deviceinfo != null) {
|
|
// final code = processHex(deviceinfo["hex"]!, 15, 25);
|
|
String code = extractAndReverseBytes(deviceinfo["hex"]!, 15, 24);
|
|
print('获取到 code: $code');
|
|
// 安全检查长度
|
|
if (code != "") {
|
|
deviceCode.value = code;
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
return 0;
|
|
// 调用BLE管理器的自动绑定方法
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//确认绑定设备
|
|
void confirmBindDevice() async {
|
|
final response = await Api.bindearphone({
|
|
"code": deviceCode.value,
|
|
"earphonname": currentDevice?.name,
|
|
"earphonemac": currentDevice?.address,
|
|
});
|
|
Logger.i(_tag, '手动授权结果 ${response}');
|
|
if (response != null) {
|
|
Logger.i(_tag, '绑定设备成功');
|
|
User.instance.earphonemac = currentDevice?.address ?? '';
|
|
User.instance.earphonename = currentDevice?.name ?? '';
|
|
User.instance.earphoneauthcode = deviceCode.value;
|
|
_transition(PairingState.verifying);
|
|
_verifyDevice(_currentClassicDevice!);
|
|
return;
|
|
} else {
|
|
Logger.e(_tag, '绑定设备失败!');
|
|
return;
|
|
}
|
|
}
|
|
|
|
int reverseBits(int byte) {
|
|
// 这里是 nibble swap 还是 bit 反转?看你需求,先保持 nibble swap
|
|
return ((byte & 0x0F) << 4) | ((byte & 0xF0) >> 4);
|
|
}
|
|
|
|
String extractAndReverseBytes(String hex, int start, int end) {
|
|
List<int> bytes = [];
|
|
for (int i = 0; i < hex.length; i += 2) {
|
|
bytes.add(int.parse(hex.substring(i, i + 2), radix: 16));
|
|
}
|
|
List<int> slice = bytes.sublist(start, end + 1);
|
|
List<int> reversed = slice.reversed.toList();
|
|
return reversed
|
|
.map((b) => b.toRadixString(16).padLeft(2, '0'))
|
|
.join()
|
|
.toUpperCase();
|
|
}
|
|
|
|
/// 用户点击授权码输入框
|
|
void onAutoCodeInputTap() async {
|
|
// 调用BLE管理器的自动绑定方法
|
|
final response = await Api.bindauthcode({
|
|
"earphonemac": currentDevice?.address,
|
|
"earphoneauthcode": codeInputController.text.trim(),
|
|
});
|
|
Logger.i(_tag, '手动授权结果 ${response}');
|
|
if (response != null) {
|
|
User.instance.earphonemac = currentDevice?.address ?? '';
|
|
User.instance.earphonename = currentDevice?.name ?? '';
|
|
User.instance.earphoneauthcode = codeInputController.text.trim();
|
|
_transition(PairingState.verifying);
|
|
_verifyDevice(_currentClassicDevice!);
|
|
} else {
|
|
Logger.e(_tag, '手动绑定失败!');
|
|
_setError(ErrorType.authnFailed, '设备授权失败,请检查授权码');
|
|
}
|
|
}
|
|
|
|
/// 导航到主页
|
|
void _navigateToHome() {
|
|
Future.delayed(const Duration(seconds: 1), () async {
|
|
// 启动AgentService服务
|
|
try {
|
|
Logger.i(_tag, '启动AgentService服务');
|
|
await _bleManager.startAgentService();
|
|
} catch (e) {
|
|
Logger.e(_tag, '启动AgentService失败: $e');
|
|
}
|
|
|
|
Get.offAllNamed(Routes.home);
|
|
});
|
|
}
|
|
|
|
// ==================== 用户操作 ====================
|
|
|
|
/// 用户点击连接按钮
|
|
void onConnectTap() {
|
|
Logger.i(_tag, '用户点击连接按钮');
|
|
|
|
// 根据当前状态或错误类型决定行为
|
|
if (_currentState.value == PairingState.error) {
|
|
switch (_errorType.value) {
|
|
case ErrorType.bluetoothOff:
|
|
// 引导用户去开启蓝牙
|
|
Logger.i(_tag, '引导用户开启蓝牙');
|
|
AppSettings.openAppSettings(type: AppSettingsType.bluetooth);
|
|
break;
|
|
case ErrorType.noClassicDevice:
|
|
// 引导用户去蓝牙设置连接设备
|
|
Logger.i(_tag, '引导用户去蓝牙设置');
|
|
AppSettings.openAppSettings(type: AppSettingsType.bluetooth);
|
|
break;
|
|
default:
|
|
// 其他错误情况,刷新并重试
|
|
_bluetoothManager.refreshDeviceConnection();
|
|
_checkCurrentStatus();
|
|
break;
|
|
}
|
|
} else if (_currentState.value == PairingState.waitingClassic) {
|
|
// 等待经典蓝牙连接状态,引导去设置
|
|
Logger.i(_tag, '等待经典蓝牙连接,引导用户去蓝牙设置');
|
|
AppSettings.openAppSettings(type: AppSettingsType.bluetooth);
|
|
} else {
|
|
// 其他情况,刷新设备连接
|
|
_bluetoothManager.refreshDeviceConnection();
|
|
_checkCurrentStatus();
|
|
}
|
|
}
|
|
|
|
/// 用户点击重试按钮
|
|
void onRetryTap() {
|
|
Logger.i(_tag, '用户点击重试按钮');
|
|
|
|
// 如果是权限问题,引导去设置
|
|
if (_errorType.value == ErrorType.noPermission) {
|
|
Logger.i(_tag, '引导用户去应用设置授予权限');
|
|
AppSettings.openAppSettings();
|
|
} else {
|
|
// 其他情况,清除错误并重试
|
|
_clearError();
|
|
_startInitialCheck();
|
|
}
|
|
}
|
|
|
|
/// 用户点击跳过绑定按钮
|
|
void onSkipBindingTap() {
|
|
Logger.i(_tag, '用户选择临时跳过手动绑定');
|
|
|
|
User.instance.earphonemac = currentDevice?.address ?? '';
|
|
_transition(PairingState.verifying);
|
|
_verifyDevice(_currentClassicDevice!);
|
|
}
|
|
|
|
/// 用户点击跳过按钮
|
|
void onSkipTap() async {
|
|
Logger.i(_tag, '用户选择跳过配对');
|
|
|
|
// 启动AgentService服务
|
|
try {
|
|
Logger.i(_tag, '启动AgentService服务');
|
|
await _bleManager.startAgentService();
|
|
} catch (e) {
|
|
Logger.e(_tag, '启动AgentService失败: $e');
|
|
}
|
|
|
|
Get.offAllNamed(Routes.home);
|
|
}
|
|
|
|
/// 打开蓝牙设置
|
|
void openBluetoothSettings() {
|
|
AppSettings.openAppSettings(type: AppSettingsType.bluetooth);
|
|
}
|
|
|
|
/// 清除设备关联(在需要重新配对时调用)
|
|
Future<void> clearDeviceAssociation() async {
|
|
try {
|
|
Logger.i(_tag, '清除设备关联');
|
|
await _bleManager.clearPairedDevices();
|
|
} catch (e) {
|
|
Logger.e(_tag, '清除设备关联失败: $e');
|
|
}
|
|
}
|
|
}
|
|
|