diff --git a/Fix9_实时门禁监听修复验证.md b/Fix9_实时门禁监听修复验证.md new file mode 100644 index 0000000..d1a0faf --- /dev/null +++ b/Fix9_实时门禁监听修复验证.md @@ -0,0 +1,121 @@ +# Fix 9 - 实时门禁监听修复验证 + +## 问题回顾 +**原始问题**:当处于OrderSelectionActivity页面进行订单选择核销时,检测到A门打开了,但app没有立即关闭选择核销弹窗。 + +**根本原因**:之前只实现了静态检查(用户点击时检查),缺少实时监听门禁状态变化的机制。 + +## 修复方案 + +### 🔧 核心改动 + +#### 1. 实现 GateUnavailableListener 接口 +```java +public class OrderSelectionActivity extends AppCompatActivity implements GateABController.GateUnavailableListener +``` + +#### 2. 添加实时监听器注册 +```java +private void initGateStatusCheck() { + // 获取GateABController实例并设置监听器 + gateController = GateABController.getInstance(); + if (gateController != null) { + // 设置本 Activity 为门禁状态监听器 + gateController.setGateStateListener(this); + LogManager.logInfo(TAG, "Fix 9 - 门禁状态实时监听初始化完成"); + } +} +``` + +#### 3. 实现关键回调方法 +```java +@Override +public void onGateUnavailable(String reason) { + LogManager.logWarning(TAG, "Fix 9 - 检测到门禁不可用,立即关闭订单选择页面。原因: " + reason); + + runOnUiThread(() -> { + // 停止倒计时 + stopCountdown(); + // 设置结果为取消并关闭Activity + setResult(RESULT_CANCELED); + finish(); + }); +} +``` + +#### 4. 资源清理 +```java +@Override +protected void onDestroy() { + // Fix 9: 清理门禁状态监听器 + if (gateController != null) { + gateController.setGateStateListener(null); + } +} +``` + +### 🚀 工作流程 + +1. **Activity启动**:OrderSelectionActivity创建时注册为门禁状态监听器 +2. **实时监听**:GateABController实时监听UDP门禁状态变化 +3. **状态检测**:当A门或B门状态变为开启时,GateABController触发onGateUnavailable回调 +4. **立即响应**:OrderSelectionActivity接收回调后立即关闭Activity +5. **资源清理**:Activity销毁时清理监听器 + +### 📊 验证要点 + +#### 测试场景1:A门开启 +- **预期**:OrderSelectionActivity立即关闭 +- **验证**:日志中应显示"Fix 9 - 检测到门禁不可用,立即关闭订单选择页面" + +#### 测试场景2:B门开启 +- **预期**:OrderSelectionActivity立即关闭 +- **验证**:同上 + +#### 测试场景3:UDP连接断开 +- **预期**:根据场景判断是否关闭(离场设备可能不关闭) +- **验证**:查看VenueSceneUtils.isLeaveScene()的判断逻辑 + +#### 测试场景4:门禁状态恢复正常 +- **预期**:如果Activity已关闭,不会重新打开 +- **验证**:onGateAvailable被调用但Activity已销毁 + +### 🔍 关键技术点 + +1. **多层检查机制**: + - 静态检查(用户点击时) + - 实时监听(状态变化时) + +2. **线程安全**: + - 使用runOnUiThread确保UI操作在主线程执行 + +3. **资源管理**: + - 注册监听器时保存引用 + - onDestroy时清理监听器 + +4. **异常处理**: + - 所有关键操作都有try-catch保护 + +### ✅ 修复验证 + +根据用户提供的日志: +``` +2025-09-14 19:46:58.397 GateUnavailableDialog: 更新门状态异常弹窗内容: 检测到A门开启,请先关闭A门 +2025-09-14 19:46:58.399 GateUnavailableDialog: 弹窗已显示,仅更新内容 +``` + +**修复前**:只有GateUnavailableDialog更新了内容,OrderSelectionActivity没有响应 +**修复后**:OrderSelectionActivity会通过onGateUnavailable回调立即关闭 + +### 🎯 预期效果 + +当用户在订单选择页面时,如果A门打开: +1. GateABController检测到A门状态变化 +2. 触发updateGateState方法 +3. 调用OrderSelectionActivity的onGateUnavailable +4. OrderSelectionActivity立即关闭 +5. 用户返回到主界面,看到门禁不可用弹窗 + +## 总结 + +Fix 9 现在提供了完整的实时门禁状态监听机制,确保当门禁状态在OrderSelectionActivity显示期间发生异常时,能够立即响应并关闭Activity,从而提升用户体验和系统安全性。 \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java b/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java index 548fd6a..1c30833 100644 --- a/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java @@ -27,6 +27,7 @@ import com.ouxuan.oxface.data.LoginDataManager; import com.ouxuan.oxface.data.DeviceSelectDataManager; // 添加设备数据管理器导入 import com.ouxuan.oxface.abgate.GateUnavailableDialog; // 门禁不可用弹窗 import com.ouxuan.oxface.utils.VenueSceneUtils; // 场景工具类 +import com.ouxuan.oxface.device.GateABController; // AB门控制器 import com.blankj.utilcode.util.NetworkUtils; // 网络工具类 import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.CircleCrop; @@ -41,7 +42,7 @@ import java.util.Locale; * 订单核销选择页面 * 用于显示人脸验证后返回的订单列表,供用户选择要核销的订单 */ -public class OrderSelectionActivity extends AppCompatActivity { +public class OrderSelectionActivity extends AppCompatActivity implements GateABController.GateUnavailableListener { private static final String TAG = "OrderSelectionActivity"; public static final String EXTRA_ORDER_DATA = "order_data"; @@ -70,6 +71,7 @@ public class OrderSelectionActivity extends AppCompatActivity { // 门禁状态检查相关变量 private GateUnavailableDialog gateUnavailableDialog; + private GateABController gateController; @Override protected void onCreate(Bundle savedInstanceState) { @@ -587,6 +589,12 @@ public class OrderSelectionActivity extends AppCompatActivity { super.onDestroy(); stopCountdown(); + // Fix 9: 清理门禁状态监听器 + if (gateController != null) { + gateController.setGateStateListener(null); + LogManager.logInfo(TAG, "Fix 9 - 已清理门禁状态监听器"); + } + // 释放门禁弹窗资源 if (gateUnavailableDialog != null) { gateUnavailableDialog.release(); @@ -689,11 +697,23 @@ public class OrderSelectionActivity extends AppCompatActivity { /** * 初始化门禁状态检查 + * Fix 9: 添加实时门禁状态监听机制 */ private void initGateStatusCheck() { try { // 初始化门禁不可用弹窗实例(仅用于检查,不显示) gateUnavailableDialog = new GateUnavailableDialog(this); + + // 获取GateABController实例并设置监听器 + gateController = GateABController.getInstance(); + if (gateController != null) { + // 设置本 Activity 为门禁状态监听器 + gateController.setGateStateListener(this); + LogManager.logInfo(TAG, "Fix 9 - 门禁状态实时监听初始化完成"); + } else { + LogManager.logWarning(TAG, "GateABController实例为空,无法设置监听器"); + } + LogManager.logInfo(TAG, "门禁状态检查初始化完成"); } catch (Exception e) { LogManager.logError(TAG, "门禁状态检查初始化失败", e); @@ -756,6 +776,63 @@ public class OrderSelectionActivity extends AppCompatActivity { } } + // ==================== GateUnavailableListener 接口实现 ==================== + + /** + * Fix 9: 门禁状态变化时触发 + * 这是 GateABStateListener 的基础方法 + */ + @Override + public void onGateStateChanged(GateABController.GateABState state) { + LogManager.logInfo(TAG, "Fix 9 - 门禁状态变化: " + state.toString()); + } + + /** + * Fix 9: 门禁变为不可用状态时触发 - 立即关闭Activity + * 这是实现门禁实时检查的核心方法 + */ + @Override + public void onGateUnavailable(String reason) { + LogManager.logWarning(TAG, "Fix 9 - 检测到门禁不可用,立即关闭订单选择页面。原因: " + reason); + + // 在主线程中执行关闭操作 + runOnUiThread(() -> { + try { + // 停止倒计时 + stopCountdown(); + + // 设置结果为取消并关闭Activity + setResult(RESULT_CANCELED); + finish(); + + LogManager.logInfo(TAG, "Fix 9 - 订单选择页面已关闭"); + } catch (Exception e) { + LogManager.logError(TAG, "Fix 9 - 关闭Activity时发生异常", e); + } + }); + } + + /** + * Fix 9: 门禁恢复可用状态时触发 + * 当前Activity关闭后不再需要处理此事件 + */ + @Override + public void onGateAvailable() { + LogManager.logInfo(TAG, "Fix 9 - 门禁恢复可用状态"); + // 订单选择页面不需要响应门禁恢复事件,因为一旦检测到异常就会关闭页面 + } + + /** + * Fix 9: 门状态实时更新时触发(用于更新弹窗中的门状态显示) + * 订单选择页面主要关心门禁异常检测,状态更新仅用于日志记录 + */ + @Override + public void onGateStatusUpdate(boolean gateAOpen, boolean gateBOpen, boolean udpConnected) { + LogManager.logDebug(TAG, "Fix 9 - 门状态更新: A门=" + (gateAOpen ? "开启" : "关闭") + + ", B门=" + (gateBOpen ? "开启" : "关闭") + + ", UDP=" + (udpConnected ? "正常" : "异常")); + } + @Override public void onBackPressed() { super.onBackPressed();