Browse Source

feat(配对): 添加手动配对模式支持

- 新增手动配对模式控制变量 isManualMode 和 isReadyToStart
- 添加手动开始配对方法 startManualPairing 和重置方法 resetToManualMode
- 分离初始化逻辑到 _executeInitFlow 方法
- 更新配对视图以支持手动模式UI展示
- 添加开始配对按钮和重置按钮
newdev_shunjiawei
lxm 1 year ago
parent
commit
49bd4dcceb
  1. 58
      lib/modules/pairing/controllers/pairing_controller.dart
  2. 120
      lib/modules/pairing/views/pairing_view.dart

58
lib/modules/pairing/controllers/pairing_controller.dart

@ -36,6 +36,10 @@ class PairingController extends GetxController {
final _state = PairingState.init.obs;
PairingState get state => _state.value;
// ==================== 手动模式控制 ====================
final isManualMode = true.obs;
final isReadyToStart = false.obs;
// ==================== 状态数据 ====================
final statusDescription = ''.obs;
final actionButtonText = ''.obs;
@ -78,12 +82,32 @@ class PairingController extends GetxController {
_transition(PairingState.init);
}
/// 手动开始配对
Future<void> startManualPairing() async {
if (!isReadyToStart.value) return;
Logger.i(_tag, '用户手动启动配对流程');
isManualMode.value = false;
isReadyToStart.value = false;
// 开始执行配对流程
await _executeInitFlow();
}
/// 重新开始配对流程
Future<void> restart() async {
_cancelAllOperations();
_transition(PairingState.init);
}
/// 重置到手动模式
void resetToManualMode() {
_cancelAllOperations();
isManualMode.value = true;
isReadyToStart.value = true;
_transition(PairingState.init);
}
/// 处理按钮点击
void handleActionButtonTap() {
switch (state) {
@ -174,10 +198,24 @@ class PairingController extends GetxController {
// ==================== 状态处理方法 ====================
/// INIT: 初始化,检查权限
/// INIT: 初始化状态
Future<void> _enterInit() async {
Logger.i(_tag, '开始执行初始化流程');
Logger.i(_tag, '进入初始化状态');
if (isManualMode.value) {
// 手动模式:仅显示待机状态,不执行任何操作
isLoading.value = false;
statusDescription.value = '准备就绪';
isReadyToStart.value = true;
return;
}
// 自动模式:执行原有的初始化逻辑
await _executeInitFlow();
}
/// 执行初始化流程
Future<void> _executeInitFlow() async {
isLoading.value = true;
statusDescription.value = '正在初始化...';
@ -529,12 +567,6 @@ class PairingController extends GetxController {
}
// Android权限检查 - 使用 PermissionUtil
// final context = Get.context;
// if (context == null) {
// Logger.e(_tag, '无法获取有效上下文,跳过权限请求');
// return false;
// }
// 根据 Android 版本确定需要的权限
List<Permission> requiredPermissions = [
Permission.locationWhenInUse,
@ -551,7 +583,6 @@ class PairingController extends GetxController {
Logger.d(_tag, '正在请求 $permissionName 权限');
final granted = await PermissionUtil.instance.requestPermission(
// context: context,
permissionType: permission,
permissionName: permissionName,
explanationText: _getExplanationText(permission),
@ -646,7 +677,11 @@ class PairingController extends GetxController {
// 根据状态更新UI文本
switch (state) {
case PairingState.init:
statusDescription.value = '初始化中...';
if (isManualMode.value && isReadyToStart.value) {
statusDescription.value = '准备就绪';
} else {
statusDescription.value = '初始化中...';
}
break;
case PairingState.btReady:
statusDescription.value = '蓝牙已就绪';
@ -718,7 +753,8 @@ class PairingController extends GetxController {
/// 是否可以跳过配对
bool get canSkip =>
!isLoading.value &&
(state == PairingState.exitNoClassic ||
((isManualMode.value && isReadyToStart.value) || // 手动模式待机状态可以跳过
state == PairingState.exitNoClassic ||
state == PairingState.exitNotMatch ||
state == PairingState.exitTimeout);

120
lib/modules/pairing/views/pairing_view.dart

@ -99,6 +99,8 @@ class PairingView extends GetView<PairingController> {
return Obx(() {
final state = controller.state;
final isLoading = controller.isLoading.value;
final isReadyToStart = controller.isReadyToStart.value;
final isManualMode = controller.isManualMode.value;
// 根据状态决定动画颜色
Color primaryColor = Color(0xFF0066CC);
@ -115,6 +117,53 @@ class PairingView extends GetView<PairingController> {
secondaryColor = Colors.greenAccent;
}
// 手动模式待机状态的特殊处理
if (isManualMode && isReadyToStart) {
return Container(
width: 240.w,
height: 240.w,
child: Stack(
alignment: Alignment.center,
children: [
// 静态背景圆圈
Container(
width: 200.w,
height: 200.w,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
primaryColor.withOpacity(0.1),
secondaryColor.withOpacity(0.1),
],
),
shape: BoxShape.circle,
),
),
// 设备图标
Container(
width: 120.w,
height: 120.w,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [primaryColor, secondaryColor],
),
shape: BoxShape.circle,
),
child: Icon(
Icons.headphones,
color: Colors.white,
size: 60.w,
),
),
],
),
);
}
return Container(
width: 240.w,
height: 240.w,
@ -241,9 +290,9 @@ class PairingView extends GetView<PairingController> {
// 当前连接设备(有设备时才显示)
if (device != null &&
(state == PairingState.classicOk ||
state == PairingState.serverVerify ||
state == PairingState.pairing ||
state == PairingState.paired)) ...[
state == PairingState.serverVerify ||
state == PairingState.pairing ||
state == PairingState.paired)) ...[
SizedBox(height: 24.h),
_buildConnectedDevice(device, isDarkMode),
],
@ -254,10 +303,14 @@ class PairingView extends GetView<PairingController> {
// 根据状态获取副标题
String _getSubtitleForState(PairingState state) {
if (controller.isManualMode.value && controller.isReadyToStart.value) {
return '点击下方按钮开始配对您的DeapSound设备';
}
switch (state) {
case PairingState.init:
case PairingState.btReady:
return '正在准备配对环境...';
return controller.isManualMode.value ? '准备开始配对' : '正在准备配对环境...';
case PairingState.classicOk:
return '请先通过系统蓝牙连接DeapSound设备';
case PairingState.serverVerify:
@ -364,17 +417,50 @@ class PairingView extends GetView<PairingController> {
final showActionButton = controller.showActionButton;
final canSkip = controller.canSkip;
final actionButtonText = controller.actionButtonText.value;
final isReadyToStart = controller.isReadyToStart.value;
final isManualMode = controller.isManualMode.value;
return Container(
width: double.infinity,
child: Column(
children: [
// 主按钮 - 根据状态显示不同的按钮
if (showActionButton)
// 手动模式:显示开始配对按钮
if (isManualMode && isReadyToStart)
ElevatedButton(
onPressed: () => controller.startManualPairing(),
style: ElevatedButton.styleFrom(
backgroundColor: Color(0xFF0066CC),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 16.h),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16.r),
),
elevation: 0,
minimumSize: Size(double.infinity, 56.h),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.bluetooth_searching, size: 20.w),
SizedBox(width: 8.w),
Text(
'开始配对设备',
style: TextStyle(
fontSize: 16.sp,
fontWeight: FontWeight.w600,
),
),
],
),
),
// 原有的状态按钮(错误处理等)
if (showActionButton && !isManualMode)
ElevatedButton(
onPressed: () => controller.handleActionButtonTap(),
style: ElevatedButton.styleFrom(
backgroundColor: _getButtonColor(controller.state, isDarkMode),
backgroundColor:
_getButtonColor(controller.state, isDarkMode),
foregroundColor: Colors.white,
padding: EdgeInsets.symmetric(vertical: 16.h),
shape: RoundedRectangleBorder(
@ -392,7 +478,7 @@ class PairingView extends GetView<PairingController> {
),
),
// 只在可以跳过时显示跳过按钮
// 跳过按钮和重置按钮
if (canSkip) ...[
SizedBox(height: 12.h),
TextButton(
@ -411,6 +497,24 @@ class PairingView extends GetView<PairingController> {
),
),
],
// 添加重置按钮(在错误状态下)
if (!isManualMode &&
!controller.isLoading.value &&
controller.state.name.startsWith('exit')) ...[
SizedBox(height: 8.h),
TextButton(
onPressed: () => controller.resetToManualMode(),
style: TextButton.styleFrom(
foregroundColor: Colors.grey,
padding: EdgeInsets.symmetric(vertical: 8.h),
),
child: Text(
'重新配对',
style: TextStyle(fontSize: 14.sp),
),
),
],
],
),
);

Loading…
Cancel
Save