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