diff --git a/app/src/main/java/com/ouxuan/oxface/device/GateABController.java b/app/src/main/java/com/ouxuan/oxface/device/GateABController.java index dd4fb31..ac0e7a1 100644 --- a/app/src/main/java/com/ouxuan/oxface/device/GateABController.java +++ b/app/src/main/java/com/ouxuan/oxface/device/GateABController.java @@ -947,6 +947,7 @@ public class GateABController { /** * 更新AB门状态 + * Fix 9.2: 当需要弹出门禁不可用弹窗时,确保先关闭OrderSelectionActivity,再显示弹窗 * @param gateAOpen A门是否开启 * @param gateBOpen B门是否开启 * @param udpConnected UDP连接状态 @@ -994,41 +995,32 @@ public class GateABController { LogManager.logInfo(TAG, "更新AB门状态: " + currentGateState.toString()); - // 如果状态发生变化且有监听器,通知监听器 - if (stateChanged && gateStateListener != null) { - final boolean finalShouldShowDialog = shouldShowDialog; - final boolean shouldHideDialog = oldShouldShow && !newShouldShow; + // Fix 9.2: 当需要显示门禁不可用弹窗时,先通过广播关闭OrderSelectionActivity,再处理弹窗 + if (shouldShowDialog && context != null) { + LogManager.logInfo(TAG, "Fix 9.2 - 检测到需要弹出门禁不可用弹窗,先发送广播关闭OrderSelectionActivity"); - syncHandler.post(() -> { - gateStateListener.onGateStateChanged(currentGateState); - - if (gateStateListener instanceof GateUnavailableListener) { - GateUnavailableListener unavailableListener = (GateUnavailableListener) gateStateListener; - - // 先触发门状态实时更新回调(用于更新弹窗中的门状态显示) - unavailableListener.onGateStatusUpdate(currentGateState.gateAOpen, - currentGateState.gateBOpen, - currentGateState.udpConnected); - - // 如果需要显示弹窗,触发不可用回调 - if (finalShouldShowDialog) { - unavailableListener.onGateUnavailable(currentGateState.getUnavailableReason()); - } - // 如果需要隐藏弹窗(门状态恢复正常),触发可用回调 - else if (shouldHideDialog) { - LogManager.logInfo(TAG, "触发门禁恢复可用回调,隐藏弹窗并恢复摄像头"); - unavailableListener.onGateAvailable(); - } - // 特别处理:如果A门和B门都关闭,且有弹窗正在显示,应该关闭弹窗 - else if (!currentGateState.gateAOpen && !currentGateState.gateBOpen && currentGateState.udpConnected) { - LogManager.logInfo(TAG, "A门和B门都关闭,触发门禁恢复可用回调"); - unavailableListener.onGateAvailable(); - } - } - }); + // 发送广播通知所有OrderSelectionActivity立即关闭 + android.content.Intent intent = new android.content.Intent("com.ouxuan.oxface.ACTION_GATE_UNAVAILABLE"); + intent.putExtra("reason", currentGateState.getUnavailableReason()); + intent.putExtra("gateAOpen", currentGateState.gateAOpen); + intent.putExtra("gateBOpen", currentGateState.gateBOpen); + intent.putExtra("udpConnected", currentGateState.udpConnected); + context.sendBroadcast(intent); + + // 延迟100ms后再处理主页面的弹窗显示,确保OrderSelectionActivity有时间关闭 + syncHandler.postDelayed(() -> { + LogManager.logInfo(TAG, "Fix 9.2 - 延迟后处理门禁不可用弹窗显示"); + notifyGateStateListener(true, false); // 处理弹窗显示 + }, 100); + } + + // 处理其他状态变化(非弹窗显示场景) + if (stateChanged && gateStateListener != null && !shouldShowDialog) { + final boolean shouldHideDialog = oldShouldShow && !newShouldShow; + notifyGateStateListener(false, shouldHideDialog); } // 即使状态没有变化,也要触发实时状态更新(用于更新弹窗显示) - else if (gateStateListener instanceof GateUnavailableListener) { + else if (gateStateListener instanceof GateUnavailableListener && !shouldShowDialog) { GateUnavailableListener unavailableListener = (GateUnavailableListener) gateStateListener; syncHandler.post(() -> { unavailableListener.onGateStatusUpdate(currentGateState.gateAOpen, @@ -1039,6 +1031,45 @@ public class GateABController { } /** + * Fix 9.2: 通知门禁状态监听器 + * @param shouldShowDialog 是否需要显示弹窗 + * @param shouldHideDialog 是否需要隐藏弹窗 + */ + private void notifyGateStateListener(final boolean shouldShowDialog, final boolean shouldHideDialog) { + if (gateStateListener == null) { + return; + } + + syncHandler.post(() -> { + gateStateListener.onGateStateChanged(currentGateState); + + if (gateStateListener instanceof GateUnavailableListener) { + GateUnavailableListener unavailableListener = (GateUnavailableListener) gateStateListener; + + // 先触发门状态实时更新回调(用于更新弹窗中的门状态显示) + unavailableListener.onGateStatusUpdate(currentGateState.gateAOpen, + currentGateState.gateBOpen, + currentGateState.udpConnected); + + // 如果需要显示弹窗,触发不可用回调 + if (shouldShowDialog) { + unavailableListener.onGateUnavailable(currentGateState.getUnavailableReason()); + } + // 如果需要隐藏弹窗(门状态恢复正常),触发可用回调 + else if (shouldHideDialog) { + LogManager.logInfo(TAG, "触发门禁恢复可用回调,隐藏弹窗并恢复摄像头"); + unavailableListener.onGateAvailable(); + } + // 特别处理:如果A门和B门都关闭,且有弹窗正在显示,应该关闭弹窗 + else if (!currentGateState.gateAOpen && !currentGateState.gateBOpen && currentGateState.udpConnected) { + LogManager.logInfo(TAG, "A门和B门都关闭,触发门禁恢复可用回调"); + unavailableListener.onGateAvailable(); + } + } + }); + } + + /** * 门禁不可用监听器接口 * 扩展GateABStateListener,增加弹窗触发功能 */ 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 1c30833..0682898 100644 --- a/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/orderOX/OrderSelectionActivity.java @@ -41,8 +41,9 @@ import java.util.Locale; /** * 订单核销选择页面 * 用于显示人脸验证后返回的订单列表,供用户选择要核销的订单 + * Fix 9.2: 改用广播方式接收门禁状态变化通知,不再实现GateUnavailableListener接口 */ -public class OrderSelectionActivity extends AppCompatActivity implements GateABController.GateUnavailableListener { +public class OrderSelectionActivity extends AppCompatActivity { private static final String TAG = "OrderSelectionActivity"; public static final String EXTRA_ORDER_DATA = "order_data"; @@ -64,6 +65,9 @@ public class OrderSelectionActivity extends AppCompatActivity implements GateABC // 强制关闭广播接收器 private BroadcastReceiver forceCloseReceiver; + // Fix 9.2: 门禁不可用广播接收器 + private BroadcastReceiver gateUnavailableReceiver; + // 登录数据管理器 private LoginDataManager loginDataManager; // 设备数据管理器 @@ -106,6 +110,9 @@ public class OrderSelectionActivity extends AppCompatActivity implements GateABC // 注册强制关闭广播接收器 registerForceCloseReceiver(); + // Fix 9.2: 注册门禁不可用广播接收器 + registerGateUnavailableReceiver(); + LogManager.logInfo(TAG, "订单选择页面启动成功"); } @@ -589,11 +596,7 @@ public class OrderSelectionActivity extends AppCompatActivity implements GateABC super.onDestroy(); stopCountdown(); - // Fix 9: 清理门禁状态监听器 - if (gateController != null) { - gateController.setGateStateListener(null); - LogManager.logInfo(TAG, "Fix 9 - 已清理门禁状态监听器"); - } + // Fix 9.2: 不再需要清理门禁状态监听器(已改用广播方式) // 释放门禁弹窗资源 if (gateUnavailableDialog != null) { @@ -610,6 +613,15 @@ public class OrderSelectionActivity extends AppCompatActivity implements GateABC } } + // Fix 9.2: 取消注册门禁不可用广播接收器 + if (gateUnavailableReceiver != null) { + try { + unregisterReceiver(gateUnavailableReceiver); + } catch (Exception e) { + LogManager.logError(TAG, "Fix 9.2 - 取消注册门禁不可用广播接收器失败", e); + } + } + // 发送广播通知OXFaceOnlineActivity恢复摄像头预览 try { Intent intent = new Intent("com.ouxuan.oxface.ACTION_RESUME_CAMERA"); @@ -643,6 +655,47 @@ public class OrderSelectionActivity extends AppCompatActivity implements GateABC } /** + * Fix 9.2: 注册门禁不可用广播接收器 + */ + private void registerGateUnavailableReceiver() { + gateUnavailableReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if ("com.ouxuan.oxface.ACTION_GATE_UNAVAILABLE".equals(intent.getAction())) { + String reason = intent.getStringExtra("reason"); + boolean gateAOpen = intent.getBooleanExtra("gateAOpen", false); + boolean gateBOpen = intent.getBooleanExtra("gateBOpen", false); + boolean udpConnected = intent.getBooleanExtra("udpConnected", true); + + LogManager.logWarning(TAG, "Fix 9.2 - 接收到门禁不可用广播,立即关闭订单选择页面。原因: " + reason + + ", A门: " + (gateAOpen ? "开启" : "关闭") + + ", B门: " + (gateBOpen ? "开启" : "关闭") + + ", UDP: " + (udpConnected ? "正常" : "异常")); + + // 立即关闭Activity + try { + // 停止倒计时 + stopCountdown(); + + // 设置结果为取消并关闭Activity + setResult(RESULT_CANCELED); + finish(); + + LogManager.logInfo(TAG, "Fix 9.2 - 订单选择页面已关闭(广播方式)"); + } catch (Exception e) { + LogManager.logError(TAG, "Fix 9.2 - 关闭Activity时发生异常", e); + } + } + } + }; + + IntentFilter filter = new IntentFilter(); + filter.addAction("com.ouxuan.oxface.ACTION_GATE_UNAVAILABLE"); + registerReceiver(gateUnavailableReceiver, filter); + LogManager.logInfo(TAG, "Fix 9.2 - 门禁不可用广播接收器已注册"); + } + + /** * 更新店铺信息(店铺名称和Logo) */ private void updateStoreInfo() { @@ -697,22 +750,16 @@ public class OrderSelectionActivity extends AppCompatActivity implements GateABC /** * 初始化门禁状态检查 - * Fix 9: 添加实时门禁状态监听机制 + * Fix 9.2: 只保留静态检查功能,不再注册监听器(改用广播方式) */ private void initGateStatusCheck() { try { // 初始化门禁不可用弹窗实例(仅用于检查,不显示) gateUnavailableDialog = new GateUnavailableDialog(this); - // 获取GateABController实例并设置监听器 + // 获取GateABController实例(不再设置监听器) gateController = GateABController.getInstance(); - if (gateController != null) { - // 设置本 Activity 为门禁状态监听器 - gateController.setGateStateListener(this); - LogManager.logInfo(TAG, "Fix 9 - 门禁状态实时监听初始化完成"); - } else { - LogManager.logWarning(TAG, "GateABController实例为空,无法设置监听器"); - } + LogManager.logInfo(TAG, "Fix 9.2 - 门禁状态静态检查初始化完成,将通过广播接收实时通知"); LogManager.logInfo(TAG, "门禁状态检查初始化完成"); } catch (Exception e) { @@ -776,62 +823,7 @@ public class OrderSelectionActivity extends AppCompatActivity implements GateABC } } - // ==================== 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() {