3 changed files with 732 additions and 84 deletions
-
220app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java
-
278app/src/main/java/com/ouxuan/oxface/abgate/GateUnavailableDialog.java
-
160app/src/main/java/com/ouxuan/oxface/device/GateABController.java
@ -0,0 +1,278 @@ |
|||
package com.ouxuan.oxface.abgate; |
|||
|
|||
import android.app.Dialog; |
|||
import android.content.Context; |
|||
import android.graphics.Color; |
|||
import android.graphics.drawable.ColorDrawable; |
|||
import android.view.Gravity; |
|||
import android.view.View; |
|||
import android.view.ViewGroup; |
|||
import android.view.Window; |
|||
import android.view.WindowManager; |
|||
import android.widget.LinearLayout; |
|||
import android.widget.TextView; |
|||
import com.ouxuan.oxface.utils.LogManager; |
|||
|
|||
/** |
|||
* 门禁不可用弹窗 |
|||
* 当AB门状态异常或门内人数异常时显示 |
|||
* |
|||
* @author AI Assistant |
|||
* @version 1.0 |
|||
* @date 2024/09/13 |
|||
*/ |
|||
public class GateUnavailableDialog { |
|||
|
|||
private static final String TAG = "GateUnavailableDialog"; |
|||
|
|||
private Context context; |
|||
private Dialog dialog; |
|||
private TextView tvTitle; |
|||
private TextView tvMessage; |
|||
/** |
|||
* 门禁不可用弹窗操作监听器 |
|||
*/ |
|||
public interface GateUnavailableDialogListener { |
|||
/** |
|||
* 弹窗显示时触发,需要暂停摄像头和中断其他操作 |
|||
*/ |
|||
void onDialogShow(); |
|||
|
|||
/** |
|||
* 弹窗隐藏时触发,可以恢复摄像头和其他操作 |
|||
*/ |
|||
void onDialogHide(); |
|||
} |
|||
|
|||
private GateUnavailableDialogListener dialogListener; |
|||
private boolean isShowing = false; |
|||
|
|||
/** |
|||
* 设置弹窗操作监听器 |
|||
* @param listener 监听器 |
|||
*/ |
|||
public void setDialogListener(GateUnavailableDialogListener listener) { |
|||
this.dialogListener = listener; |
|||
} |
|||
|
|||
public GateUnavailableDialog(Context context) { |
|||
this.context = context; |
|||
createDialog(); |
|||
} |
|||
|
|||
/** |
|||
* 创建弹窗 |
|||
*/ |
|||
private void createDialog() { |
|||
dialog = new Dialog(context); |
|||
|
|||
// 创建弹窗布局 |
|||
LinearLayout mainLayout = new LinearLayout(context); |
|||
mainLayout.setOrientation(LinearLayout.VERTICAL); |
|||
mainLayout.setBackgroundColor(Color.parseColor("#CC000000")); // 半透明黑色背景 |
|||
mainLayout.setGravity(Gravity.CENTER); |
|||
mainLayout.setPadding(50, 50, 50, 50); |
|||
|
|||
// 内容容器 |
|||
LinearLayout contentLayout = new LinearLayout(context); |
|||
contentLayout.setOrientation(LinearLayout.VERTICAL); |
|||
contentLayout.setBackgroundColor(Color.WHITE); |
|||
contentLayout.setPadding(40, 30, 40, 30); |
|||
contentLayout.setGravity(Gravity.CENTER); |
|||
|
|||
// 设置圆角效果(通过代码设置) |
|||
android.graphics.drawable.GradientDrawable drawable = new android.graphics.drawable.GradientDrawable(); |
|||
drawable.setColor(Color.WHITE); |
|||
drawable.setCornerRadius(20); |
|||
contentLayout.setBackground(drawable); |
|||
|
|||
// 标题 |
|||
tvTitle = new TextView(context); |
|||
tvTitle.setText("门禁不可用"); |
|||
tvTitle.setTextSize(20); |
|||
tvTitle.setTextColor(Color.parseColor("#FF4444")); |
|||
tvTitle.setGravity(Gravity.CENTER); |
|||
tvTitle.setPadding(0, 0, 0, 20); |
|||
|
|||
// 消息内容 |
|||
tvMessage = new TextView(context); |
|||
tvMessage.setTextSize(16); |
|||
tvMessage.setTextColor(Color.parseColor("#333333")); |
|||
tvMessage.setGravity(Gravity.CENTER); |
|||
tvMessage.setLineSpacing(5, 1.2f); |
|||
|
|||
// 添加视图到容器 |
|||
contentLayout.addView(tvTitle); |
|||
contentLayout.addView(tvMessage); |
|||
|
|||
// 设置内容布局参数 |
|||
LinearLayout.LayoutParams contentParams = new LinearLayout.LayoutParams( |
|||
(int)(300 * context.getResources().getDisplayMetrics().density), |
|||
LinearLayout.LayoutParams.WRAP_CONTENT |
|||
); |
|||
contentParams.gravity = Gravity.CENTER; |
|||
mainLayout.addView(contentLayout, contentParams); |
|||
|
|||
// 设置Dialog属性 |
|||
dialog.setContentView(mainLayout); |
|||
|
|||
Window window = dialog.getWindow(); |
|||
if (window != null) { |
|||
// 设置全屏显示 |
|||
window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); |
|||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); |
|||
|
|||
// 设置窗口标志 |
|||
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); |
|||
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); |
|||
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); |
|||
|
|||
// 清除默认动画 |
|||
window.setWindowAnimations(0); |
|||
} |
|||
|
|||
// 设置不可取消 |
|||
dialog.setCancelable(false); |
|||
dialog.setCanceledOnTouchOutside(false); |
|||
} |
|||
|
|||
/** |
|||
* 显示门状态异常弹窗 |
|||
* @param reason 不可用原因 |
|||
*/ |
|||
public void showGateStateError(String reason) { |
|||
if (isShowing) { |
|||
return; |
|||
} |
|||
|
|||
LogManager.logInfo(TAG, "显示门状态异常弹窗: " + reason); |
|||
|
|||
tvTitle.setText("门禁不可用"); |
|||
tvMessage.setText(reason); |
|||
|
|||
show(); |
|||
} |
|||
|
|||
/** |
|||
* 显示人数异常弹窗 |
|||
* @param isLeaveScene 是否为离场场景 |
|||
* @param peopleCount 门内人数 |
|||
*/ |
|||
public void showPeopleCountError(boolean isLeaveScene, int peopleCount) { |
|||
if (isShowing) { |
|||
return; |
|||
} |
|||
|
|||
String message; |
|||
if (isLeaveScene) { |
|||
// 离场场景:检测到门内有人 |
|||
message = "AB门离场:检测到门内有 " + peopleCount + " 人\n请等待门禁内人员离开后操作"; |
|||
LogManager.logInfo(TAG, "显示离场人数异常弹窗,门内人数: " + peopleCount); |
|||
} else { |
|||
// 进场场景:检测到门内人数大于1 |
|||
message = "AB门进场:检测到门内有 " + peopleCount + " 人\n请一次一人进场,确保门禁内只有一人时操作"; |
|||
LogManager.logInfo(TAG, "显示进场人数异常弹窗,门内人数: " + peopleCount); |
|||
} |
|||
|
|||
tvTitle.setText("门禁不可用"); |
|||
tvMessage.setText(message); |
|||
|
|||
show(); |
|||
} |
|||
|
|||
/** |
|||
* 显示弹窗 |
|||
*/ |
|||
private void show() { |
|||
try { |
|||
if (dialog != null && !isShowing) { |
|||
dialog.show(); |
|||
isShowing = true; |
|||
LogManager.logInfo(TAG, "门禁不可用弹窗已显示"); |
|||
|
|||
// 通知监听器弹窗显示,需要暂停摄像头和中断操作 |
|||
if (dialogListener != null) { |
|||
dialogListener.onDialogShow(); |
|||
} |
|||
} |
|||
} catch (Exception e) { |
|||
LogManager.logError(TAG, "显示弹窗失败", e); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 隐藏弹窗 |
|||
*/ |
|||
public void hide() { |
|||
try { |
|||
if (dialog != null && isShowing) { |
|||
dialog.dismiss(); |
|||
isShowing = false; |
|||
LogManager.logInfo(TAG, "门禁不可用弹窗已隐藏"); |
|||
|
|||
// 通知监听器弹窗隐藏,可以恢复摄像头和操作 |
|||
if (dialogListener != null) { |
|||
dialogListener.onDialogHide(); |
|||
} |
|||
} |
|||
} catch (Exception e) { |
|||
LogManager.logError(TAG, "隐藏弹窗失败", e); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 检查是否应该显示弹窗 |
|||
* 根据业务规则进行判断: |
|||
* - 对于离场设备,检测到网络中断后不显示弹窗(不阻碍离场断网直接开门功能) |
|||
* - 对于进场设备,始终显示弹窗 |
|||
* |
|||
* @param context 上下文 |
|||
* @param isNetworkAvailable 网络是否可用 |
|||
* @return true表示应该显示弹窗 |
|||
*/ |
|||
public boolean checkShow(Context context, boolean isNetworkAvailable) { |
|||
try { |
|||
// 先检测设备场景 |
|||
boolean isLeaveScene = com.ouxuan.oxface.utils.VenueSceneUtils.isLeaveScene(context); |
|||
|
|||
if (isLeaveScene) { |
|||
// 离场设备:检测到网络中断后,弹窗不显示(不阻碍离场断网直接开门功能) |
|||
if (!isNetworkAvailable) { |
|||
LogManager.logInfo(TAG, "离场设备检测到网络中断,不显示门禁不可用弹窗(保持离场断网直接开门功能)"); |
|||
return false; |
|||
} |
|||
// 离场设备且网络可用,显示弹窗 |
|||
LogManager.logInfo(TAG, "离场设备且网络可用,可以显示门禁不可用弹窗"); |
|||
return true; |
|||
} else { |
|||
// 进场设备:始终显示弹窗 |
|||
LogManager.logInfo(TAG, "进场设备,可以显示门禁不可用弹窗"); |
|||
return true; |
|||
} |
|||
|
|||
} catch (Exception e) { |
|||
LogManager.logError(TAG, "检查是否显示弹窗时发生异常,默认显示", e); |
|||
return true; // 异常情况下默认显示弹窗 |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 检查弹窗是否正在显示 |
|||
* @return true表示正在显示 |
|||
*/ |
|||
public boolean isShowing() { |
|||
return isShowing; |
|||
} |
|||
|
|||
/** |
|||
* 释放资源 |
|||
*/ |
|||
public void release() { |
|||
hide(); |
|||
if (dialog != null) { |
|||
dialog = null; |
|||
} |
|||
context = null; |
|||
LogManager.logInfo(TAG, "门禁不可用弹窗资源已释放"); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue