|
|
@ -15,8 +15,6 @@ import 'package:flutter/material.dart'; |
|
|
class PairingController extends GetxController { |
|
|
class PairingController extends GetxController { |
|
|
static PairingController get to => Get.find(); |
|
|
static PairingController get to => Get.find(); |
|
|
|
|
|
|
|
|
// 需要设备 |
|
|
|
|
|
final bool needdeivice = false; |
|
|
|
|
|
// 状态标志 |
|
|
// 状态标志 |
|
|
final isLoading = false.obs; |
|
|
final isLoading = false.obs; |
|
|
|
|
|
|
|
|
@ -65,6 +63,9 @@ class PairingController extends GetxController { |
|
|
// BLE服务 |
|
|
// BLE服务 |
|
|
final _bleService = BleService(); |
|
|
final _bleService = BleService(); |
|
|
|
|
|
|
|
|
|
|
|
// 日志tag |
|
|
|
|
|
static const _tag = 'PairingController'; |
|
|
|
|
|
|
|
|
@override |
|
|
@override |
|
|
void onInit() { |
|
|
void onInit() { |
|
|
super.onInit(); |
|
|
super.onInit(); |
|
|
@ -102,7 +103,7 @@ class PairingController extends GetxController { |
|
|
// 检查蓝牙状态并刷新设备 |
|
|
// 检查蓝牙状态并刷新设备 |
|
|
await _checkBluetoothAndRefresh(); |
|
|
await _checkBluetoothAndRefresh(); |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
Logger.error('初始化配对控制器失败: ${e.toString()}'); |
|
|
Logger.e(_tag, '初始化配对控制器失败: ${e.toString()}'); |
|
|
statusDescription.value = 'initializationFailure'.tr; |
|
|
statusDescription.value = 'initializationFailure'.tr; |
|
|
} finally { |
|
|
} finally { |
|
|
isLoading.value = false; |
|
|
isLoading.value = false; |
|
|
@ -134,13 +135,12 @@ class PairingController extends GetxController { |
|
|
|
|
|
|
|
|
/// 检查设备配对状态 |
|
|
/// 检查设备配对状态 |
|
|
Future<void> _checkDevicePairingStatus() async { |
|
|
Future<void> _checkDevicePairingStatus() async { |
|
|
// 只在Android平台且设备已连接时执行 |
|
|
if (!isDeviceConnected) return; |
|
|
if (!Platform.isAndroid || !isDeviceConnected) return; |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
final isSupported = await _bleService.isCompanionSupported(); |
|
|
final isSupported = await _bleService.isCompanionSupported(); |
|
|
if (!isSupported) { |
|
|
if (!isSupported) { |
|
|
Logger.info('设备不支持Companion功能'); |
|
|
Logger.i(_tag, '设备不支持Companion功能'); |
|
|
_companionAssociated.value = true; // 不支持则视为已配对 |
|
|
_companionAssociated.value = true; // 不支持则视为已配对 |
|
|
_userRejectedAssociation.value = false; // 重置拒绝状态 |
|
|
_userRejectedAssociation.value = false; // 重置拒绝状态 |
|
|
return; |
|
|
return; |
|
|
@ -149,16 +149,16 @@ class PairingController extends GetxController { |
|
|
final pairedMac = await _bleService.getPairedMacAddress(); |
|
|
final pairedMac = await _bleService.getPairedMacAddress(); |
|
|
if (pairedMac == null) { |
|
|
if (pairedMac == null) { |
|
|
// 没有配对记录,需要开始配对 |
|
|
// 没有配对记录,需要开始配对 |
|
|
Logger.info('无配对记录,需要开始设备配对'); |
|
|
Logger.i(_tag, '无配对记录,需要开始设备配对'); |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Logger.info('发现已关联的Companion设备: $pairedMac'); |
|
|
Logger.i(_tag, '发现已关联的Companion设备: $pairedMac'); |
|
|
|
|
|
|
|
|
// 检查当前连接设备与已保存的设备是否一致 |
|
|
// 检查当前连接设备与已保存的设备是否一致 |
|
|
if (currentDevice!.address != pairedMac) { |
|
|
if (currentDevice!.address != pairedMac) { |
|
|
// MAC地址不匹配 |
|
|
// MAC地址不匹配 |
|
|
Logger.warning('当前连接的设备与已配对的DeepSound设备不符'); |
|
|
Logger.w(_tag, '当前连接的设备与已配对的DeepSound设备不符'); |
|
|
statusDescription.value = 'pleaseConnectPairedDevice'.tr; |
|
|
statusDescription.value = 'pleaseConnectPairedDevice'.tr; |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
@ -170,13 +170,13 @@ class PairingController extends GetxController { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 设备匹配且合规,标记为已配对 |
|
|
// 设备匹配且合规,标记为已配对 |
|
|
Logger.info('当前设备与已配对设备匹配'); |
|
|
Logger.i(_tag, '当前设备与已配对设备匹配'); |
|
|
_companionAssociated.value = true; |
|
|
_companionAssociated.value = true; |
|
|
_userRejectedAssociation.value = false; // 重置拒绝状态 |
|
|
_userRejectedAssociation.value = false; // 重置拒绝状态 |
|
|
await _bleService.registerBackgroundScan(); |
|
|
await _bleService.registerBackgroundScan(); |
|
|
_autoNavigateToHome(); |
|
|
_autoNavigateToHome(); |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
Logger.error('检查设备配对状态失败: ${e.toString()}'); |
|
|
Logger.e(_tag, '检查设备配对状态失败: ${e.toString()}'); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -198,45 +198,70 @@ class PairingController extends GetxController { |
|
|
permissionsToRequest.add(Permission.bluetoothConnect); |
|
|
permissionsToRequest.add(Permission.bluetoothConnect); |
|
|
} |
|
|
} |
|
|
} else if (Platform.isIOS) { |
|
|
} else if (Platform.isIOS) { |
|
|
// iOS上单独处理蓝牙权限请求,避免冲突 |
|
|
// iOS需要请求的权限 |
|
|
PermissionStatus status = await Permission.bluetooth.status; |
|
|
permissionsToRequest.add(Permission.bluetooth); |
|
|
|
|
|
permissionsToRequest.add(Permission.location); |
|
|
|
|
|
|
|
|
if (status.isPermanentlyDenied) { |
|
|
// 如果需要麦克风权限(例如语音功能) |
|
|
Logger.warning('iOS蓝牙权限状态为permanentlyDenied,这可能是iOS系统误报'); |
|
|
// permissionsToRequest.add(Permission.microphone); |
|
|
|
|
|
|
|
|
// 在iOS上打开蓝牙设置对话框 |
|
|
try { |
|
|
Get.dialog( |
|
|
// 先尝试请求权限 |
|
|
AlertDialog( |
|
|
if (permissionsToRequest.isNotEmpty) { |
|
|
title: Text('需要蓝牙权限'), |
|
|
statuses = await permissionsToRequest.request(); |
|
|
content: Text('请在系统设置中手动开启蓝牙权限,以便连接设备'), |
|
|
bool allGranted = true; |
|
|
actions: [ |
|
|
statuses.forEach((permission, status) { |
|
|
TextButton( |
|
|
if (!status.isGranted) { |
|
|
onPressed: () => Get.back(), |
|
|
allGranted = false; |
|
|
child: Text('稍后'), |
|
|
Logger.w(_tag, 'iOS权限 ${permission.toString()} 未被授予: $status'); |
|
|
), |
|
|
|
|
|
TextButton( |
|
|
// 特殊处理蓝牙权限 |
|
|
onPressed: () { |
|
|
if (permission == Permission.bluetooth) { |
|
|
Get.back(); |
|
|
Logger.w(_tag, 'iOS蓝牙权限未授予,状态: $status'); |
|
|
openAppSettings(); |
|
|
} |
|
|
}, |
|
|
} |
|
|
child: Text('前往设置'), |
|
|
}); |
|
|
), |
|
|
|
|
|
], |
|
|
// 如果有权限未授予,但不是永久拒绝,继续尝试 |
|
|
), |
|
|
if (!allGranted) { |
|
|
barrierDismissible: false, |
|
|
bool hasPermanentlyDenied = statuses.values.any((status) => status.isPermanentlyDenied); |
|
|
); |
|
|
if (hasPermanentlyDenied) { |
|
|
return false; |
|
|
// 有权限被永久拒绝,需要引导用户去设置 |
|
|
} else if (!status.isGranted) { |
|
|
_showPermissionSettingsDialog('部分权限被永久拒绝,请在设置中启用'); |
|
|
// 单独请求蓝牙权限 |
|
|
|
|
|
PermissionStatus result = await Permission.bluetooth.request(); |
|
|
|
|
|
if (!result.isGranted) { |
|
|
|
|
|
Logger.warning('iOS蓝牙权限申请失败: $result'); |
|
|
|
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// iOS不再添加到批量请求列表 |
|
|
// 直接尝试使用蓝牙功能,这会触发iOS原生权限请求 |
|
|
// permissionsToRequest.add(Permission.bluetooth); |
|
|
bool isEnabled = await _bluetoothService.isBluetoothEnabled(); |
|
|
|
|
|
Logger.i(_tag, 'iOS蓝牙状态检查: ${isEnabled ? "已开启" : "未开启"}'); |
|
|
|
|
|
|
|
|
|
|
|
// 检测AccessorySetupKit支持情况(iOS 18+特性) |
|
|
|
|
|
bool companionSupported = await _bleService.isCompanionSupported(); |
|
|
|
|
|
Logger.i(_tag, 'iOS Companion支持检查: ${companionSupported ? "支持" : "不支持"}'); |
|
|
|
|
|
|
|
|
|
|
|
if (companionSupported) { |
|
|
|
|
|
// 针对iOS 18+,尝试预热AccessorySetupKit框架 |
|
|
|
|
|
try { |
|
|
|
|
|
// 此调用会触发AccessorySetupKit相关权限请求 |
|
|
|
|
|
final pairedMac = await _bleService.getPairedMacAddress(); |
|
|
|
|
|
Logger.i(_tag, '获取已配对设备MAC: ${pairedMac ?? "无"}'); |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
Logger.w(_tag, 'iOS 18+ AccessorySetupKit初始化失败: ${e.toString()}'); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 在iOS上视为权限已授予 |
|
|
|
|
|
_hasPermissions.value = true; |
|
|
|
|
|
return true; |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
Logger.e(_tag, "iOS蓝牙初始化失败: ${e.toString()}"); |
|
|
|
|
|
|
|
|
|
|
|
// 显示自定义对话框引导用户 |
|
|
|
|
|
_showPermissionSettingsDialog('需要开启蓝牙权限才能配对设备'); |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 如果还有其他权限需要请求 |
|
|
// 如果还有其他权限需要请求 |
|
|
@ -247,7 +272,7 @@ class PairingController extends GetxController { |
|
|
statuses.forEach((permission, status) { |
|
|
statuses.forEach((permission, status) { |
|
|
if (!status.isGranted) { |
|
|
if (!status.isGranted) { |
|
|
allGranted = false; |
|
|
allGranted = false; |
|
|
Logger.warning('权限 ${permission.toString()} 未被授予: $status'); |
|
|
Logger.w(_tag, '权限 ${permission.toString()} 未被授予: $status'); |
|
|
} |
|
|
} |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
@ -260,6 +285,30 @@ class PairingController extends GetxController { |
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 显示权限设置对话框 |
|
|
|
|
|
void _showPermissionSettingsDialog(String message) { |
|
|
|
|
|
Get.dialog( |
|
|
|
|
|
AlertDialog( |
|
|
|
|
|
title: Text('需要权限'), |
|
|
|
|
|
content: Text(message), |
|
|
|
|
|
actions: [ |
|
|
|
|
|
TextButton( |
|
|
|
|
|
onPressed: () => Get.back(), |
|
|
|
|
|
child: Text('稍后'), |
|
|
|
|
|
), |
|
|
|
|
|
TextButton( |
|
|
|
|
|
onPressed: () { |
|
|
|
|
|
Get.back(); |
|
|
|
|
|
openBluetoothSettings(); |
|
|
|
|
|
}, |
|
|
|
|
|
child: Text('去设置'), |
|
|
|
|
|
), |
|
|
|
|
|
], |
|
|
|
|
|
), |
|
|
|
|
|
barrierDismissible: false, |
|
|
|
|
|
); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// 辅助方法获取Android SDK版本 |
|
|
// 辅助方法获取Android SDK版本 |
|
|
Future<int> _getAndroidSdkVersion() async { |
|
|
Future<int> _getAndroidSdkVersion() async { |
|
|
if (Platform.isAndroid) { |
|
|
if (Platform.isAndroid) { |
|
|
@ -281,14 +330,11 @@ class PairingController extends GetxController { |
|
|
_deviceWorker = |
|
|
_deviceWorker = |
|
|
ever(_bluetoothService.currentDeviceRx, (BluetoothDevice? device) { |
|
|
ever(_bluetoothService.currentDeviceRx, (BluetoothDevice? device) { |
|
|
if (device != null && !_isNavigatingToHome) { |
|
|
if (device != null && !_isNavigatingToHome) { |
|
|
Logger.info('配对页面发现设备已连接: ${device.name}'); |
|
|
Logger.i(_tag, '配对页面发现设备已连接: ${device.name}'); |
|
|
_handleDeviceConnected(); |
|
|
_handleDeviceConnected(); |
|
|
} |
|
|
} |
|
|
_updateStatusDescription(); |
|
|
_updateStatusDescription(); |
|
|
}); |
|
|
}); |
|
|
if (needdeivice) { |
|
|
|
|
|
_handleDeviceConnected(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// 处理设备连接成功事件 |
|
|
/// 处理设备连接成功事件 |
|
|
@ -347,9 +393,8 @@ class PairingController extends GetxController { |
|
|
|
|
|
|
|
|
/// 启动Companion设备关联流程 |
|
|
/// 启动Companion设备关联流程 |
|
|
Future<void> _startCompanionAssociation() async { |
|
|
Future<void> _startCompanionAssociation() async { |
|
|
// 如果不是Android平台,已跳转,已完成关联或正在进行关联,直接返回 |
|
|
// 如果已跳转,已完成关联或正在进行关联,直接返回 |
|
|
if (!Platform.isAndroid || |
|
|
if (_isNavigatingToHome || |
|
|
_isNavigatingToHome || |
|
|
|
|
|
_companionAssociated.value || |
|
|
_companionAssociated.value || |
|
|
_isAssociating || |
|
|
_isAssociating || |
|
|
!isDeviceConnected) { |
|
|
!isDeviceConnected) { |
|
|
@ -367,7 +412,7 @@ class PairingController extends GetxController { |
|
|
// 检查是否支持Companion功能 |
|
|
// 检查是否支持Companion功能 |
|
|
final isSupported = await _bleService.isCompanionSupported(); |
|
|
final isSupported = await _bleService.isCompanionSupported(); |
|
|
if (!isSupported) { |
|
|
if (!isSupported) { |
|
|
Logger.info('设备不支持Companion功能,跳过关联'); |
|
|
Logger.i(_tag, '设备不支持Companion功能,跳过关联'); |
|
|
_companionAssociated.value = true; |
|
|
_companionAssociated.value = true; |
|
|
_autoNavigateToHome(); |
|
|
_autoNavigateToHome(); |
|
|
return; |
|
|
return; |
|
|
@ -380,7 +425,7 @@ class PairingController extends GetxController { |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Logger.info('开始Companion设备关联流程, 设备MAC: ${currentDevice!.address}'); |
|
|
Logger.i(_tag, '开始Companion设备关联流程, 设备MAC: ${currentDevice!.address}'); |
|
|
|
|
|
|
|
|
var success = await _bleService.startDeviceAssociation( |
|
|
var success = await _bleService.startDeviceAssociation( |
|
|
deviceNamePattern: currentDevice!.name, |
|
|
deviceNamePattern: currentDevice!.name, |
|
|
@ -389,7 +434,7 @@ class PairingController extends GetxController { |
|
|
_isAssociating = false; |
|
|
_isAssociating = false; |
|
|
|
|
|
|
|
|
if (success) { |
|
|
if (success) { |
|
|
Logger.info('Companion设备关联成功'); |
|
|
Logger.i(_tag, 'Companion设备关联成功'); |
|
|
_companionAssociated.value = true; |
|
|
_companionAssociated.value = true; |
|
|
_userRejectedAssociation.value = false; |
|
|
_userRejectedAssociation.value = false; |
|
|
|
|
|
|
|
|
@ -400,14 +445,14 @@ class PairingController extends GetxController { |
|
|
// 关联成功后跳转 |
|
|
// 关联成功后跳转 |
|
|
_autoNavigateToHome(); |
|
|
_autoNavigateToHome(); |
|
|
} else { |
|
|
} else { |
|
|
Logger.error('Companion设备关联失败或被用户拒绝'); |
|
|
Logger.e(_tag, 'Companion设备关联失败或被用户拒绝'); |
|
|
// 关联失败 - 用户拒绝关联 |
|
|
// 关联失败 - 用户拒绝关联 |
|
|
_userRejectedAssociation.value = true; |
|
|
_userRejectedAssociation.value = true; |
|
|
// 确保UI状态更新 |
|
|
// 确保UI状态更新 |
|
|
_updateStatusDescription(); |
|
|
_updateStatusDescription(); |
|
|
} |
|
|
} |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
Logger.error('Companion设备关联过程发生错误: ${e.toString()}'); |
|
|
Logger.e(_tag, 'Companion设备关联过程发生错误: ${e.toString()}'); |
|
|
_isAssociating = false; |
|
|
_isAssociating = false; |
|
|
_userRejectedAssociation.value = true; |
|
|
_userRejectedAssociation.value = true; |
|
|
_updateStatusDescription(); |
|
|
_updateStatusDescription(); |
|
|
@ -416,13 +461,13 @@ class PairingController extends GetxController { |
|
|
|
|
|
|
|
|
/// 自动跳转到主页 |
|
|
/// 自动跳转到主页 |
|
|
Future<void> _autoNavigateToHome() async { |
|
|
Future<void> _autoNavigateToHome() async { |
|
|
if (needdeivice && (_isNavigatingToHome || !isDeviceConnected)) return; |
|
|
if (_isNavigatingToHome || !isDeviceConnected) return; |
|
|
|
|
|
|
|
|
// 启动BLE后台服务 |
|
|
// 启动BLE后台服务 |
|
|
await _startAgentService(); |
|
|
await _startAgentService(); |
|
|
|
|
|
|
|
|
_isNavigatingToHome = true; |
|
|
_isNavigatingToHome = true; |
|
|
Logger.info('已找到连接的设备 ${currentDevice!.name},自动跳转到主页'); |
|
|
Logger.i(_tag, '已找到连接的设备 ${currentDevice!.name},自动跳转到主页'); |
|
|
|
|
|
|
|
|
Future.delayed(const Duration(milliseconds: 500), () { |
|
|
Future.delayed(const Duration(milliseconds: 500), () { |
|
|
Get.offAllNamed(Routes.home); |
|
|
Get.offAllNamed(Routes.home); |
|
|
@ -432,12 +477,13 @@ class PairingController extends GetxController { |
|
|
/// 启动BLE后台服务 |
|
|
/// 启动BLE后台服务 |
|
|
Future<void> _startAgentService() async { |
|
|
Future<void> _startAgentService() async { |
|
|
try { |
|
|
try { |
|
|
if (needdeivice && !isDeviceConnected) return; |
|
|
// 注释掉设备连接检查,确保无论是否连接设备都能启动服务 |
|
|
|
|
|
// if (!isDeviceConnected) return; |
|
|
|
|
|
|
|
|
final result = await BleManager.to.startAgentService(); |
|
|
final result = await BleManager.to.startAgentService(); |
|
|
Logger.info(result ? 'BLE后台服务启动成功' : 'BLE后台服务启动失败'); |
|
|
Logger.i(_tag, result ? 'BLE后台服务启动成功' : 'BLE后台服务启动失败'); |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
Logger.error('启动BLE后台服务发生错误: ${e.toString()}'); |
|
|
Logger.e(_tag, '启动BLE后台服务发生错误: ${e.toString()}'); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -445,9 +491,9 @@ class PairingController extends GetxController { |
|
|
Future<void> _stopAgentService() async { |
|
|
Future<void> _stopAgentService() async { |
|
|
try { |
|
|
try { |
|
|
final result = await BleManager.to.stopAgentService(); |
|
|
final result = await BleManager.to.stopAgentService(); |
|
|
Logger.info(result ? 'BLE后台服务停止成功' : 'BLE后台服务停止失败'); |
|
|
Logger.i(_tag, result ? 'BLE后台服务停止成功' : 'BLE后台服务停止失败'); |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
Logger.error('停止BLE后台服务发生错误: ${e.toString()}'); |
|
|
Logger.e(_tag, '停止BLE后台服务发生错误: ${e.toString()}'); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -470,12 +516,79 @@ class PairingController extends GetxController { |
|
|
} else if (Platform.isAndroid && !isBluetoothOn) { |
|
|
} else if (Platform.isAndroid && !isBluetoothOn) { |
|
|
AppSettings.openAppSettings(type: AppSettingsType.bluetooth); |
|
|
AppSettings.openAppSettings(type: AppSettingsType.bluetooth); |
|
|
} else if (Platform.isIOS) { |
|
|
} else if (Platform.isIOS) { |
|
|
|
|
|
// iOS上优先尝试打开蓝牙设置 |
|
|
|
|
|
if (!isBluetoothOn) { |
|
|
|
|
|
// iOS上无法直接打开蓝牙设置,只能打开应用设置 |
|
|
|
|
|
AppSettings.openAppSettings(); |
|
|
|
|
|
} else { |
|
|
|
|
|
// 如果蓝牙开启但有其他权限问题,打开应用设置 |
|
|
openAppSettings(); |
|
|
openAppSettings(); |
|
|
|
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
AppSettings.openAppSettings(type: AppSettingsType.bluetooth); |
|
|
AppSettings.openAppSettings(type: AppSettingsType.bluetooth); |
|
|
} |
|
|
} |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
Logger.error('打开设置失败: ${e.toString()}'); |
|
|
Logger.e(_tag, '打开设置失败: ${e.toString()}'); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 重新初始化蓝牙 |
|
|
|
|
|
Future<void> reinitializeBluetooth() async { |
|
|
|
|
|
try { |
|
|
|
|
|
isLoading.value = true; |
|
|
|
|
|
statusDescription.value = '正在重新初始化蓝牙...'; |
|
|
|
|
|
|
|
|
|
|
|
// iOS上尝试重置权限状态 |
|
|
|
|
|
if (Platform.isIOS) { |
|
|
|
|
|
await Future.delayed(Duration(milliseconds: 500)); |
|
|
|
|
|
|
|
|
|
|
|
// 检查蓝牙权限 |
|
|
|
|
|
PermissionStatus bluetoothStatus = await Permission.bluetooth.status; |
|
|
|
|
|
Logger.i(_tag, "iOS蓝牙权限当前状态: $bluetoothStatus"); |
|
|
|
|
|
|
|
|
|
|
|
if (bluetoothStatus.isPermanentlyDenied) { |
|
|
|
|
|
Logger.i(_tag, "iOS蓝牙权限处于永久拒绝状态,提示用户手动开启"); |
|
|
|
|
|
_showPermissionSettingsDialog('蓝牙权限被拒绝,请在设置中手动开启'); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 尝试重新请求权限 |
|
|
|
|
|
if (!bluetoothStatus.isGranted) { |
|
|
|
|
|
bluetoothStatus = await Permission.bluetooth.request(); |
|
|
|
|
|
Logger.i(_tag, "iOS蓝牙权限请求结果: $bluetoothStatus"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 尝试检查蓝牙状态,这会重新触发系统权限弹窗 |
|
|
|
|
|
try { |
|
|
|
|
|
bool isEnabled = await _bluetoothService.isBluetoothEnabled(); |
|
|
|
|
|
Logger.i(_tag, "iOS蓝牙状态: ${isEnabled ? '开启' : '关闭'}"); |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
Logger.e(_tag, "iOS蓝牙状态检查失败: ${e.toString()}"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 检查Companion功能(iOS 18+) |
|
|
|
|
|
try { |
|
|
|
|
|
bool isSupported = await _bleService.isCompanionSupported(); |
|
|
|
|
|
if (isSupported) { |
|
|
|
|
|
Logger.i(_tag, "iOS 18+ Companion功能可用,尝试初始化"); |
|
|
|
|
|
// 尝试预热AccessorySetupKit |
|
|
|
|
|
await _bleService.getPairedMacAddress(); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
Logger.w(_tag, "iOS Companion功能检查失败: ${e.toString()}"); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 重新检查权限 |
|
|
|
|
|
if (await _checkAndRequestPermissions()) { |
|
|
|
|
|
// 重新检查蓝牙状态 |
|
|
|
|
|
await _checkBluetoothAndRefresh(); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
Logger.e(_tag, '重新初始化蓝牙失败: ${e.toString()}'); |
|
|
|
|
|
} finally { |
|
|
|
|
|
isLoading.value = false; |
|
|
|
|
|
_updateStatusDescription(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -488,7 +601,7 @@ class PairingController extends GetxController { |
|
|
reinitializeBluetooth(); |
|
|
reinitializeBluetooth(); |
|
|
}); |
|
|
}); |
|
|
} catch (e) { |
|
|
} catch (e) { |
|
|
Logger.error('打开应用设置失败: ${e.toString()}'); |
|
|
Logger.e(_tag, '打开应用设置失败: ${e.toString()}'); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -501,38 +614,13 @@ class PairingController extends GetxController { |
|
|
|
|
|
|
|
|
/// 跳过连接 |
|
|
/// 跳过连接 |
|
|
void skipConnecting() async { |
|
|
void skipConnecting() async { |
|
|
// 启动BLE后台服务 |
|
|
// 即使没有设备连接,也启动BLE后台服务 |
|
|
await _startAgentService(); |
|
|
await _startAgentService(); |
|
|
_isNavigatingToHome = true; |
|
|
_isNavigatingToHome = true; |
|
|
Get.offAllNamed(Routes.home); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// 重新初始化蓝牙 |
|
|
// 记录跳过配对的日志 |
|
|
Future<void> reinitializeBluetooth() async { |
|
|
Logger.i(_tag, '用户跳过设备配对,直接跳转到主页'); |
|
|
try { |
|
|
|
|
|
isLoading.value = true; |
|
|
|
|
|
statusDescription.value = '正在重新初始化蓝牙...'; |
|
|
|
|
|
|
|
|
|
|
|
// iOS上尝试重置权限状态 |
|
|
Get.offAllNamed(Routes.home); |
|
|
if (Platform.isIOS) { |
|
|
|
|
|
await Future.delayed(Duration(milliseconds: 500)); |
|
|
|
|
|
if (await Permission.bluetooth.isPermanentlyDenied) { |
|
|
|
|
|
Logger.info("iOS蓝牙权限仍处于永久拒绝状态,尝试直接使用蓝牙功能"); |
|
|
|
|
|
// 在永久拒绝状态下,尝试使用蓝牙功能,iOS可能会再次弹出系统权限请求 |
|
|
|
|
|
_bluetoothService.isBluetoothEnabled(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 重新检查权限 |
|
|
|
|
|
if (await _checkAndRequestPermissions()) { |
|
|
|
|
|
// 重新检查蓝牙状态 |
|
|
|
|
|
await _checkBluetoothAndRefresh(); |
|
|
|
|
|
} |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
Logger.error('重新初始化蓝牙失败: ${e.toString()}'); |
|
|
|
|
|
} finally { |
|
|
|
|
|
isLoading.value = false; |
|
|
|
|
|
_updateStatusDescription(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |