|
|
@ -44,7 +44,7 @@ enum ErrorType { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// 配对控制器 - 基于简化状态机的实现 |
|
|
/// 配对控制器 - 基于简化状态机的实现 |
|
|
class PairingController extends GetxController { |
|
|
class PairingController extends GetxController with WidgetsBindingObserver { |
|
|
static const String _tag = 'PairingCtrl'; |
|
|
static const String _tag = 'PairingCtrl'; |
|
|
static PairingController get to => Get.find(); |
|
|
static PairingController get to => Get.find(); |
|
|
|
|
|
|
|
|
@ -100,6 +100,11 @@ class PairingController extends GetxController { |
|
|
super.onInit(); |
|
|
super.onInit(); |
|
|
Logger.i(_tag, '配对控制器初始化'); |
|
|
Logger.i(_tag, '配对控制器初始化'); |
|
|
|
|
|
|
|
|
|
|
|
// 注册应用生命周期监听器 |
|
|
|
|
|
Logger.i(_tag, '正在注册应用生命周期监听器'); |
|
|
|
|
|
WidgetsBinding.instance.addObserver(this); |
|
|
|
|
|
Logger.i(_tag, '应用生命周期监听器注册完成'); |
|
|
|
|
|
|
|
|
// 确保服务已初始化 |
|
|
// 确保服务已初始化 |
|
|
_bluetoothManager = Get.find<BluetoothManager>(); |
|
|
_bluetoothManager = Get.find<BluetoothManager>(); |
|
|
_bleManager = Get.find<BleManager>(); |
|
|
_bleManager = Get.find<BleManager>(); |
|
|
@ -123,6 +128,10 @@ class PairingController extends GetxController { |
|
|
@override |
|
|
@override |
|
|
void onClose() { |
|
|
void onClose() { |
|
|
Logger.i(_tag, '配对控制器销毁'); |
|
|
Logger.i(_tag, '配对控制器销毁'); |
|
|
|
|
|
|
|
|
|
|
|
// 移除应用生命周期监听器 |
|
|
|
|
|
WidgetsBinding.instance.removeObserver(this); |
|
|
|
|
|
|
|
|
// 清理所有Worker |
|
|
// 清理所有Worker |
|
|
for (var worker in _workers) { |
|
|
for (var worker in _workers) { |
|
|
worker.dispose(); |
|
|
worker.dispose(); |
|
|
@ -135,6 +144,109 @@ class PairingController extends GetxController { |
|
|
super.onClose(); |
|
|
super.onClose(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 应用生命周期状态变化回调 |
|
|
|
|
|
@override |
|
|
|
|
|
void didChangeAppLifecycleState(AppLifecycleState state) { |
|
|
|
|
|
super.didChangeAppLifecycleState(state); |
|
|
|
|
|
// 使用多种日志级别确保输出 |
|
|
|
|
|
Logger.i(_tag, '=== 应用生命周期状态变化: $state ==='); |
|
|
|
|
|
print('PairingCtrl: 应用生命周期状态变化: $state'); // 直接使用print确保输出 |
|
|
|
|
|
|
|
|
|
|
|
switch (state) { |
|
|
|
|
|
case AppLifecycleState.resumed: |
|
|
|
|
|
// 应用从后台切回前台 |
|
|
|
|
|
Logger.i(_tag, '=== 应用从后台切回前台 ==='); |
|
|
|
|
|
print('PairingCtrl: 应用从后台切回前台'); |
|
|
|
|
|
_onAppResumed(); |
|
|
|
|
|
break; |
|
|
|
|
|
case AppLifecycleState.paused: |
|
|
|
|
|
// 应用切到后台 |
|
|
|
|
|
Logger.i(_tag, '应用切到后台'); |
|
|
|
|
|
print('PairingCtrl: 应用切到后台'); |
|
|
|
|
|
_onAppPaused(); |
|
|
|
|
|
break; |
|
|
|
|
|
case AppLifecycleState.inactive: |
|
|
|
|
|
// 应用处于非活跃状态(如来电话时) |
|
|
|
|
|
Logger.i(_tag, '应用处于非活跃状态'); |
|
|
|
|
|
print('PairingCtrl: 应用处于非活跃状态'); |
|
|
|
|
|
break; |
|
|
|
|
|
case AppLifecycleState.detached: |
|
|
|
|
|
// 应用即将被销毁 |
|
|
|
|
|
Logger.i(_tag, '应用即将被销毁'); |
|
|
|
|
|
print('PairingCtrl: 应用即将被销毁'); |
|
|
|
|
|
break; |
|
|
|
|
|
case AppLifecycleState.hidden: |
|
|
|
|
|
// 应用被隐藏(iOS 13+) |
|
|
|
|
|
Logger.i(_tag, '应用被隐藏'); |
|
|
|
|
|
print('PairingCtrl: 应用被隐藏'); |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 应用从后台切回前台时的处理逻辑 |
|
|
|
|
|
void _onAppResumed() { |
|
|
|
|
|
Logger.i(_tag, '处理应用从后台切回前台事件'); |
|
|
|
|
|
|
|
|
|
|
|
// 刷新蓝牙连接状态 |
|
|
|
|
|
_bluetoothManager.refreshDeviceConnection(); |
|
|
|
|
|
|
|
|
|
|
|
// 根据当前配对状态执行相应操作 |
|
|
|
|
|
switch (_currentState.value) { |
|
|
|
|
|
case PairingState.waitingClassic: |
|
|
|
|
|
// 如果在等待经典蓝牙连接,重新检查连接状态 |
|
|
|
|
|
Logger.i(_tag, '重新检查经典蓝牙连接状态'); |
|
|
|
|
|
_checkCurrentStatus(); |
|
|
|
|
|
break; |
|
|
|
|
|
case PairingState.waitingBle: |
|
|
|
|
|
// 如果在等待BLE连接,重新检查BLE状态 |
|
|
|
|
|
Logger.i(_tag, '重新检查BLE连接状态'); |
|
|
|
|
|
_checkBleConnectionAfterResume(); |
|
|
|
|
|
break; |
|
|
|
|
|
case PairingState.error: |
|
|
|
|
|
// 如果在错误状态,根据错误类型决定是否自动重试 |
|
|
|
|
|
if (_errorType.value == ErrorType.bluetoothOff) { |
|
|
|
|
|
Logger.i(_tag, '检查蓝牙是否已重新开启'); |
|
|
|
|
|
_checkCurrentStatus(); |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
|
|
|
default: |
|
|
|
|
|
// 其他状态暂不处理 |
|
|
|
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 应用切到后台时的处理逻辑 |
|
|
|
|
|
void _onAppPaused() { |
|
|
|
|
|
Logger.i(_tag, '处理应用切到后台事件'); |
|
|
|
|
|
|
|
|
|
|
|
// 可以在这里暂停一些不必要的操作,如蓝牙扫描等 |
|
|
|
|
|
if (_currentState.value == PairingState.associating) { |
|
|
|
|
|
Logger.i(_tag, '应用切到后台,暂停BLE扫描'); |
|
|
|
|
|
_bleManager.stopScan(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 应用恢复后检查BLE连接状态 |
|
|
|
|
|
Future<void> _checkBleConnectionAfterResume() async { |
|
|
|
|
|
try { |
|
|
|
|
|
final currentBleState = await _bleManager.getConnectionState(); |
|
|
|
|
|
Logger.i(_tag, '应用恢复后BLE连接状态: $currentBleState'); |
|
|
|
|
|
|
|
|
|
|
|
if (currentBleState == 2) { |
|
|
|
|
|
// BLE已连接,直接完成配对 |
|
|
|
|
|
Logger.i(_tag, '检测到BLE已连接,完成配对'); |
|
|
|
|
|
_bleTimeoutTimer?.cancel(); |
|
|
|
|
|
_transition(PairingState.completed); |
|
|
|
|
|
} else { |
|
|
|
|
|
// BLE未连接,重新启动连接流程 |
|
|
|
|
|
Logger.i(_tag, '重新启动BLE连接流程'); |
|
|
|
|
|
_startBleConnection(); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
Logger.e(_tag, '检查BLE连接状态失败: $e'); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// ==================== 监听器设置 ==================== |
|
|
// ==================== 监听器设置 ==================== |
|
|
|
|
|
|
|
|
/// 集中设置所有监听器 |
|
|
/// 集中设置所有监听器 |
|
|
|