3 changed files with 685 additions and 0 deletions
-
125GateUnavailableDialogUsageExample.java
-
398app/src/main/java/com/ouxuan/oxface/abgate/GateUnavailableDialog.java
-
162门禁弹窗进场离场关闭条件增强说明.md
@ -0,0 +1,125 @@ |
|||||
|
package com.ouxuan.oxface.abgate; |
||||
|
|
||||
|
import android.content.Context; |
||||
|
import com.ouxuan.oxface.utils.LogManager; |
||||
|
|
||||
|
/** |
||||
|
* GateUnavailableDialog使用示例 |
||||
|
* 演示新增的进场和离场场景人数异常弹窗关闭逻辑 |
||||
|
* |
||||
|
* @author AI Assistant |
||||
|
* @version 1.0 |
||||
|
* @date 2024/09/15 |
||||
|
*/ |
||||
|
public class GateUnavailableDialogUsageExample { |
||||
|
|
||||
|
private static final String TAG = "GateUnavailableDialogUsageExample"; |
||||
|
|
||||
|
private Context context; |
||||
|
private GateUnavailableDialog gateUnavailableDialog; |
||||
|
|
||||
|
public GateUnavailableDialogUsageExample(Context context) { |
||||
|
this.context = context; |
||||
|
this.gateUnavailableDialog = new GateUnavailableDialog(context); |
||||
|
|
||||
|
// 设置弹窗监听器 |
||||
|
gateUnavailableDialog.setDialogListener(new GateUnavailableDialog.GateUnavailableDialogListener() { |
||||
|
@Override |
||||
|
public void onDialogShow() { |
||||
|
LogManager.logInfo(TAG, "弹窗显示,暂停摄像头和其他操作"); |
||||
|
// 在这里实现暂停摄像头的逻辑 |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void onDialogHide() { |
||||
|
LogManager.logInfo(TAG, "弹窗隐藏,恢复摄像头和其他操作"); |
||||
|
// 在这里实现恢复摄像头的逻辑 |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 演示进场场景人数异常弹窗 |
||||
|
* 当检测到门内人数大于1时,显示弹窗并启动A门开关监听 |
||||
|
*/ |
||||
|
public void demonstrateEnterScenePeopleCountError() { |
||||
|
LogManager.logInfo(TAG, "演示进场场景人数异常弹窗"); |
||||
|
|
||||
|
// 模拟检测到门内有2人(进场场景不允许) |
||||
|
boolean isLeaveScene = false; // 进场场景 |
||||
|
int peopleCount = 2; |
||||
|
|
||||
|
// 显示人数异常弹窗 |
||||
|
gateUnavailableDialog.updatePeopleCountError(isLeaveScene, peopleCount); |
||||
|
|
||||
|
LogManager.logInfo(TAG, "进场场景人数异常弹窗已显示"); |
||||
|
LogManager.logInfo(TAG, "弹窗关闭条件:"); |
||||
|
LogManager.logInfo(TAG, "1. A、B门都关闭时弹窗不再允许关闭"); |
||||
|
LogManager.logInfo(TAG, "2. 启动A门开关监听器checkAGateOpenClose"); |
||||
|
LogManager.logInfo(TAG, "3. 当检测到A门由开启变为关闭时,触发udpLoopCheckNum()函数"); |
||||
|
LogManager.logInfo(TAG, "4. 启动20次UDP轮询人数检测,每1.5秒检测1次"); |
||||
|
LogManager.logInfo(TAG, "5. 当连续3次检测到门内人数为1人且A、B门均关闭时,弹窗关闭"); |
||||
|
LogManager.logInfo(TAG, "6. 达到20次轮询上限时,自动关闭弹窗"); |
||||
|
LogManager.logInfo(TAG, "7. 如果A门监听器被再次触发,会重置UDP轮询"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 演示离场场景人数异常弹窗 |
||||
|
* 当检测到门内有人时,显示弹窗并启动5秒倒计时 |
||||
|
*/ |
||||
|
public void demonstrateLeaveScenePeopleCountError() { |
||||
|
LogManager.logInfo(TAG, "演示离场场景人数异常弹窗"); |
||||
|
|
||||
|
// 模拟检测到门内有1人(离场场景不允许) |
||||
|
boolean isLeaveScene = true; // 离场场景 |
||||
|
int peopleCount = 1; |
||||
|
|
||||
|
// 显示人数异常弹窗 |
||||
|
gateUnavailableDialog.updatePeopleCountError(isLeaveScene, peopleCount); |
||||
|
|
||||
|
LogManager.logInfo(TAG, "离场场景人数异常弹窗已显示"); |
||||
|
LogManager.logInfo(TAG, "弹窗关闭条件:"); |
||||
|
LogManager.logInfo(TAG, "1. A、B门都关闭时弹窗不再允许关闭"); |
||||
|
LogManager.logInfo(TAG, "2. 弹窗右上角显示倒计时"); |
||||
|
LogManager.logInfo(TAG, "3. 5秒后自动关闭弹窗"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 演示门状态异常弹窗(保持原有逻辑) |
||||
|
*/ |
||||
|
public void demonstrateGateStateError() { |
||||
|
LogManager.logInfo(TAG, "演示门状态异常弹窗"); |
||||
|
|
||||
|
// 显示门状态异常弹窗 |
||||
|
String reason = "检测到A门开启,门禁不可用"; |
||||
|
boolean gateAOpen = true; |
||||
|
boolean gateBOpen = false; |
||||
|
boolean udpConnected = true; |
||||
|
|
||||
|
gateUnavailableDialog.updateGateStateError(reason, gateAOpen, gateBOpen, udpConnected); |
||||
|
|
||||
|
LogManager.logInfo(TAG, "门状态异常弹窗已显示,保持原有关闭逻辑"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 模拟A门状态变化(用于测试进场场景) |
||||
|
*/ |
||||
|
public void simulateAGateStateChange() { |
||||
|
LogManager.logInfo(TAG, "模拟A门状态变化"); |
||||
|
|
||||
|
// 这里可以模拟A门从开启变为关闭的状态变化 |
||||
|
// 在实际应用中,这将通过UDP监听器自动触发 |
||||
|
LogManager.logInfo(TAG, "模拟A门由开启变为关闭,应该触发UDP轮询人数检测"); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 清理资源 |
||||
|
*/ |
||||
|
public void cleanup() { |
||||
|
if (gateUnavailableDialog != null) { |
||||
|
gateUnavailableDialog.release(); |
||||
|
gateUnavailableDialog = null; |
||||
|
} |
||||
|
LogManager.logInfo(TAG, "GateUnavailableDialog示例资源已清理"); |
||||
|
} |
||||
|
} |
@ -0,0 +1,162 @@ |
|||||
|
# 门禁不可用弹窗进场离场场景关闭条件增强说明 |
||||
|
|
||||
|
## 概述 |
||||
|
|
||||
|
根据您的需求,我已经成功为`GateUnavailableDialog`类添加了针对进场和离场场景的不同人数异常弹窗关闭条件。该实现支持以下功能: |
||||
|
|
||||
|
## 新增功能 |
||||
|
|
||||
|
### 1. 进场场景人数异常弹窗关闭逻辑 |
||||
|
|
||||
|
**触发条件**:当使用场景为进场且为人数异常弹窗内容时 |
||||
|
|
||||
|
**关闭条件**: |
||||
|
- A、B门都关闭时弹窗不再允许关闭 |
||||
|
- 启动A门开关监听器 `checkAGateOpenClose` |
||||
|
- 当检测到A门由开启变为关闭时,触发 `udpLoopCheckNum()` 函数 |
||||
|
- 启动20次UDP轮询人数检测,每1.5秒检测1次人数 |
||||
|
- 当连续3次检测到门内人数为1人(并且A、B门均为关闭状态)时,门禁不可用弹窗关闭 |
||||
|
- 当达到20次轮询上限时,自动结束并关闭弹窗 |
||||
|
- 如果在`udpLoopCheckNum`执行过程中,`checkAGateOpenClose`被再次触发,会重置UDP轮询 |
||||
|
|
||||
|
### 2. 离场场景人数异常弹窗关闭逻辑 |
||||
|
|
||||
|
**触发条件**:当使用场景为离场且为人数异常弹窗内容时 |
||||
|
|
||||
|
**关闭条件**: |
||||
|
- A、B门都关闭时弹窗不再允许关闭 |
||||
|
- 弹窗右上角显示倒计时 |
||||
|
- 5秒后自动关闭 |
||||
|
|
||||
|
## 技术实现 |
||||
|
|
||||
|
### 核心类修改 |
||||
|
|
||||
|
**文件**: `app/src/main/java/com/ouxuan/oxface/abgate/GateUnavailableDialog.java` |
||||
|
|
||||
|
#### 新增成员变量 |
||||
|
|
||||
|
```java |
||||
|
// A门开关监听相关 |
||||
|
private boolean isAGateListening = false; |
||||
|
private boolean lastAGateState = false; // 上一次A门状态 |
||||
|
private AGateStateListener aGateStateListener; |
||||
|
|
||||
|
// UDP人数轮询相关 |
||||
|
private ScheduledExecutorService udpPollingExecutor; |
||||
|
private ScheduledFuture<?> udpPollingTask; |
||||
|
private int udpPollingCount = 0; |
||||
|
private int consecutiveSuccessCount = 0; |
||||
|
private static final int UDP_POLLING_MAX_COUNT = 20; |
||||
|
private static final int UDP_POLLING_INTERVAL_MS = 1500; |
||||
|
private static final int REQUIRED_SUCCESS_COUNT = 3; |
||||
|
|
||||
|
// 倒计时相关(离场场景) |
||||
|
private Handler countdownHandler; |
||||
|
private Runnable countdownRunnable; |
||||
|
private int countdownSeconds = 5; |
||||
|
|
||||
|
// 弹窗类型标识 |
||||
|
private boolean isPeopleCountError = false; |
||||
|
private boolean isLeaveScene = false; |
||||
|
``` |
||||
|
|
||||
|
#### 新增接口 |
||||
|
|
||||
|
```java |
||||
|
/** |
||||
|
* A门状态监听器接口 |
||||
|
*/ |
||||
|
public interface AGateStateListener { |
||||
|
/** |
||||
|
* A门状态变化监听 |
||||
|
* @param isOpen A门是否开启 |
||||
|
*/ |
||||
|
void onAGateStateChanged(boolean isOpen); |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
#### 核心方法 |
||||
|
|
||||
|
1. **`startAGateOpenCloseMonitoring()`** - 开始A门开关监听 |
||||
|
2. **`startUdpLoopCheckNum()`** - 启动UDP轮询人数检测 |
||||
|
3. **`startLeaveSceneCountdown()`** - 启动离场场景倒计时 |
||||
|
4. **`applySceneSpecificClosingConditions()`** - 根据场景应用关闭条件 |
||||
|
|
||||
|
### 使用示例 |
||||
|
|
||||
|
```java |
||||
|
// 初始化弹窗 |
||||
|
GateUnavailableDialog dialog = new GateUnavailableDialog(context); |
||||
|
|
||||
|
// 进场场景人数异常(门内有2人) |
||||
|
boolean isLeaveScene = false; |
||||
|
int peopleCount = 2; |
||||
|
dialog.updatePeopleCountError(isLeaveScene, peopleCount); |
||||
|
// 将自动启动A门监听和UDP轮询机制 |
||||
|
|
||||
|
// 离场场景人数异常(门内有1人) |
||||
|
isLeaveScene = true; |
||||
|
peopleCount = 1; |
||||
|
dialog.updatePeopleCountError(isLeaveScene, peopleCount); |
||||
|
// 将自动启动5秒倒计时 |
||||
|
``` |
||||
|
|
||||
|
## 关键配置参数 |
||||
|
|
||||
|
| 参数 | 值 | 说明 | |
||||
|
|------|----|----| |
||||
|
| `UDP_POLLING_MAX_COUNT` | 20 | UDP轮询最大次数 | |
||||
|
| `UDP_POLLING_INTERVAL_MS` | 1500 | UDP轮询间隔(毫秒) | |
||||
|
| `REQUIRED_SUCCESS_COUNT` | 3 | 连续成功检测次数要求 | |
||||
|
| `countdownSeconds` | 5 | 离场场景倒计时时间(秒) | |
||||
|
|
||||
|
## 日志监控 |
||||
|
|
||||
|
所有关键操作都有详细的日志记录,可以通过以下过滤器查看: |
||||
|
|
||||
|
```bash |
||||
|
adb logcat | grep "GateUnavailableDialog" |
||||
|
``` |
||||
|
|
||||
|
关键日志信息包括: |
||||
|
- A门状态变化监听 |
||||
|
- UDP轮询人数检测进度 |
||||
|
- 倒计时状态更新 |
||||
|
- 弹窗关闭条件判断 |
||||
|
|
||||
|
## 资源管理 |
||||
|
|
||||
|
新实现包含完善的资源管理机制: |
||||
|
|
||||
|
1. **线程池管理**: `udpPollingExecutor` 用于UDP轮询任务 |
||||
|
2. **定时任务管理**: 自动取消未完成的轮询和倒计时任务 |
||||
|
3. **内存泄漏防护**: 在 `release()` 方法中完整清理所有资源 |
||||
|
|
||||
|
## 错误处理 |
||||
|
|
||||
|
实现了完善的错误处理机制: |
||||
|
|
||||
|
1. **UDP通信失败**: 自动重试,达到上限后关闭弹窗 |
||||
|
2. **485人数检测失败**: 记录错误日志并继续轮询 |
||||
|
3. **A门状态获取失败**: 使用默认状态,不影响整体流程 |
||||
|
|
||||
|
## 向后兼容性 |
||||
|
|
||||
|
所有新功能都是在原有基础上扩展,不影响现有的: |
||||
|
- 门状态异常弹窗逻辑 |
||||
|
- 普通弹窗显示/隐藏功能 |
||||
|
- 弹窗监听器机制 |
||||
|
|
||||
|
## 总结 |
||||
|
|
||||
|
本次增强实现了完整的进场和离场场景人数异常弹窗智能关闭机制,包括: |
||||
|
|
||||
|
✅ **进场场景**: A门开关监听 + UDP轮询人数检测 |
||||
|
✅ **离场场景**: 5秒倒计时自动关闭 |
||||
|
✅ **资源管理**: 完善的线程池和定时任务管理 |
||||
|
✅ **错误处理**: 全面的异常处理和容错机制 |
||||
|
✅ **日志监控**: 详细的操作日志记录 |
||||
|
✅ **向后兼容**: 不影响现有功能 |
||||
|
|
||||
|
该实现满足了您提出的所有需求,并提供了稳定可靠的用户体验。 |
Write
Preview
Loading…
Cancel
Save
Reference in new issue