diff --git a/app/src/main/java/com/ouxuan/oxface/debug/Ox485DebugHelper.java b/app/src/main/java/com/ouxuan/oxface/debug/Ox485DebugHelper.java index a0b1b76..6bbbd4d 100644 --- a/app/src/main/java/com/ouxuan/oxface/debug/Ox485DebugHelper.java +++ b/app/src/main/java/com/ouxuan/oxface/debug/Ox485DebugHelper.java @@ -3,6 +3,8 @@ package com.ouxuan.oxface.debug; import com.ouxuan.oxface.device.Ox485; import com.ouxuan.oxface.utils.LogManager; +import java.io.File; + /** * Ox485调试助手 * 用于排查485通信问题 diff --git a/app/src/main/java/com/ouxuan/oxface/device/Ox485.java b/app/src/main/java/com/ouxuan/oxface/device/Ox485.java index 2d00cea..60c1f86 100644 --- a/app/src/main/java/com/ouxuan/oxface/device/Ox485.java +++ b/app/src/main/java/com/ouxuan/oxface/device/Ox485.java @@ -18,11 +18,11 @@ import java.util.concurrent.TimeUnit; * Ox485 串口通信模块 * 基于kongqw/SerialPortLibrary实现485通信功能 * 主要用于获取摄像头人数等485设备通信 - * 采用懒加载连接管理模式:首次使用时打开,保持连接状态,定时检查机制 + * 采用即用即连模式:每次请求时打开连接,完成后立即关闭,确保通信可靠性 * * @author AI Assistant - * @version 2.0 - * @date 2024/09/15 + * @version 3.0 - 即用即连模式 + * @date 2024/09/22 */ public class Ox485 { @@ -35,8 +35,7 @@ public class Ox485 { private static final String HEX_COMMAND_GET_PEOPLE_NUM = "0F030001000294E5"; private static final long TIMEOUT_485_MILLIS = 10000; // 10秒超时 - // 懒加载连接管理配置 - private static final long CONNECTION_CHECK_INTERVAL = 30000; // 30秒检查一次连接状态 + // 即用即连模式配置 private static final int MAX_RETRY_COUNT = 3; // 最大重试次数 private static final long RETRY_DELAY = 1000; // 重试延迟1秒 @@ -44,19 +43,10 @@ public class Ox485 { private static volatile Ox485 instance; // 485通信相关 - private SerialPortManager serialPortManager; private Handler mainHandler; private boolean gateCamera485OxOn = false; private Context context; - // 懒加载连接管理相关 - private boolean isSerialPortOpen = false; // 串口是否已打开 - private boolean isConnecting = false; // 是否正在连接中 - private Handler connectionCheckHandler; // 连接检查处理器 - private Runnable connectionCheckRunnable; // 连接检查任务 - private long lastSuccessTime = 0; // 最后一次成功通信时间 - private int currentRetryCount = 0; // 当前重试次数 - // 数据接收相关 private long lastRecvTime = 0; private Handler timeoutHandler; @@ -96,10 +86,7 @@ public class Ox485 { */ public void initialize(Context context) { this.context = context; - LogManager.logInfo(TAG, "15:45:22.734 Ox485 D Ox485模块初始化完成,采用懒加载连接管理模式"); - - // 启动定时连接检查 - startConnectionCheck(); + LogManager.logInfo(TAG, "Ox485模块初始化完成,采用即用即连模式"); } /** @@ -108,7 +95,7 @@ public class Ox485 { */ public void setGateCamera485OxOn(boolean enabled) { this.gateCamera485OxOn = enabled; - LogManager.logInfo(TAG, "15:45:22.734 Ox485 D 设置485模式开关: " + enabled); + LogManager.logInfo(TAG, "设置485模式开关: " + enabled); } /** @@ -272,21 +259,6 @@ public class Ox485 { } /** - * 关闭并清理串口资源 - * @param serialPortManager 串口管理器 - */ - private void closeAndCleanup(SerialPortManager serialPortManager) { - if (serialPortManager != null) { - try { - serialPortManager.closeSerialPort(); - LogManager.logInfo(TAG, "485串口已关闭并清理资源"); - } catch (Exception e) { - LogManager.logError(TAG, "关闭485串口时发生异常: " + e.getMessage(), e); - } - } - } - - /** * 设置超时处理 * @param serialPortManager 串口管理器 * @param callback 结果回调 @@ -351,7 +323,7 @@ public class Ox485 { // 提取第5个字节作为人数数据,使用位掩码确保为无符号整数 int peopleNum = arr[4] & 0xFF; - LogManager.logInfo(TAG, "15:45:22.734 Ox485 D 解析485人数成功: " + peopleNum); + LogManager.logInfo(TAG, "解析485人数成功: " + peopleNum); return peopleNum; } @@ -384,7 +356,7 @@ public class Ox485 { * 检查是否需要打开485串口 */ public void checkIsNeedOpen485() { - LogManager.logInfo(TAG, "检查485串口状态(懒加载模式)"); + LogManager.logInfo(TAG, "检查485串口状态(即用即连模式)"); String status = get485Status(); LogManager.logInfo(TAG, status); } @@ -396,22 +368,71 @@ public class Ox485 { public void send485HexCommand(String hexCommand) { LogManager.logInfo(TAG, "发送485 HEX命令: " + hexCommand); try { - if (!isSerialPortOpen) { - LogManager.logWarning(TAG, "串口未打开,无法发送命令"); + if (!gateCamera485OxOn) { + LogManager.logWarning(TAG, "485模式未开启,无法发送命令"); + return; + } + + // 创建临时串口管理器发送命令 + SerialPortManager serialPortManager = new SerialPortManager(); + File serialPortFile = new File(DEFAULT_SERIAL_PORT_PATH); + + if (!serialPortFile.exists()) { + LogManager.logWarning(TAG, "串口设备文件不存在: " + DEFAULT_SERIAL_PORT_PATH); + return; + } + + boolean openResult = serialPortManager.openSerialPort(serialPortFile, DEFAULT_BAUD_RATE); + if (!openResult) { + LogManager.logWarning(TAG, "打开串口失败: " + DEFAULT_SERIAL_PORT_PATH); return; } + serialPortManager.startReadThread(485); + serialPortManager.startSendThread(); + byte[] hexBytes = hexStringToByteArray(hexCommand); serialPortManager.sendBytes(hexBytes); LogManager.logInfo(TAG, "485命令发送完成"); + + // 发送完成后关闭连接 + closeAndCleanup(serialPortManager); + } catch (Exception e) { LogManager.logError(TAG, "发送485命令异常: " + e.getMessage(), e); } } /** + * 获取485串口状态(即用即连模式) + * @return 串口状态描述 + */ + public String get485Status() { + String status = "串口状态: 即用即连模式" + + ", 路径: " + DEFAULT_SERIAL_PORT_PATH + + ", 波特率: " + DEFAULT_BAUD_RATE + + ", 485模式: " + (gateCamera485OxOn ? "已启用" : "未启用"); + + LogManager.logInfo(TAG, status); + return status; + } + + /** + * 关闭485串口(兼容旧接口) + */ + public void close485SerialPort() { + LogManager.logInfo(TAG, "485串口即用即连模式无需手动关闭"); + } + + /** + * 释放资源 + */ + public void release() { + LogManager.logInfo(TAG, "释放Ox485资源(即用即连模式)"); + } + + /** * 485连接诊断方法 - * 用于排查485通信问题 */ public void diagnose485Connection() { LogManager.logInfo(TAG, "开始485连接诊断"); @@ -426,41 +447,18 @@ public class Ox485 { LogManager.logInfo(TAG, " - 文件大小: " + serialPortFile.length()); } - // 2. 检查串口管理器状态 - LogManager.logInfo(TAG, "诊断2 - 串口管理器状态:"); - LogManager.logInfo(TAG, " - 串口是否打开: " + (isSerialPortReallyOpen() ? "已打开" : "未打开")); - LogManager.logInfo(TAG, " - 内部连接状态: " + isSerialPortOpen); - LogManager.logInfo(TAG, " - 是否连接中: " + isConnecting); - - // 3. 检查485模式开关 - LogManager.logInfo(TAG, "诊断3 - 485配置:"); + // 2. 检查485配置 + LogManager.logInfo(TAG, "诊断2 - 485配置:"); LogManager.logInfo(TAG, " - 485模式开关: " + gateCamera485OxOn); LogManager.logInfo(TAG, " - 串口路径: " + DEFAULT_SERIAL_PORT_PATH); LogManager.logInfo(TAG, " - 波特率: " + DEFAULT_BAUD_RATE); - LogManager.logInfo(TAG, " - 停止位: " + DEFAULT_STOP_BITS); LogManager.logInfo(TAG, " - 查询命令: " + HEX_COMMAND_GET_PEOPLE_NUM); - // 4. 检查连接历史 - LogManager.logInfo(TAG, "诊断4 - 连接历史:"); - String lastSuccessStr = lastSuccessTime > 0 ? - new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new java.util.Date(lastSuccessTime)) : - "无"; - LogManager.logInfo(TAG, " - 最后成功时间: " + lastSuccessStr); - LogManager.logInfo(TAG, " - 当前重试次数: " + currentRetryCount); - LogManager.logInfo(TAG, " - 最大重试次数: " + MAX_RETRY_COUNT); - - // 5. 尝试重新建立连接进行测试 - LogManager.logInfo(TAG, "诊断5 - 连接测试:"); + // 3. 尝试通信测试 + LogManager.logInfo(TAG, "诊断3 - 通信测试:"); if (gateCamera485OxOn) { - LogManager.logInfo(TAG, " - 485模式已启用,尝试测试连接..."); + LogManager.logInfo(TAG, " - 485模式已启用,开始测试通信..."); - // 强制关闭现有连接 - if (isSerialPortOpen) { - LogManager.logInfo(TAG, " - 关闭现有连接进行重新测试"); - close485SerialPort(); - } - - // 尝试重新连接并发送测试命令 sendHex485ForPeopleNum(new PeopleNumCallback() { @Override public void onSuccess(int peopleNum) { @@ -473,45 +471,27 @@ public class Ox485 { } }); } else { - LogManager.logWarning(TAG, " - 485模式未启用,无法进行连接测试"); + LogManager.logWarning(TAG, " - 485模式未启用,无法进行通信测试"); } LogManager.logInfo(TAG, "485连接诊断完成"); } /** - * 获取485串口状态(即用即连模式) - * @return 串口状态描述 - */ - public String get485Status() { - String status = "串口状态: 即用即连模式" + - ", 路径: " + DEFAULT_SERIAL_PORT_PATH + - ", 波特率: " + DEFAULT_BAUD_RATE + - ", 485模式: " + (gateCamera485OxOn ? "已启用" : "未启用"); - - LogManager.logInfo(TAG, status); - return status; - } - - /** - * 关闭485串口(兼容旧接口) - */ - public void close485SerialPort() { - LogManager.logInfo(TAG, "485串口即用即连模式无需手动关闭"); - } - - /** - * 释放资源 + * 关闭并清理串口资源 + * @param serialPortManager 串口管理器 */ - public void release() { - LogManager.logInfo(TAG, "释放Ox485资源(即用即连模式)"); + private void closeAndCleanup(SerialPortManager serialPortManager) { + if (serialPortManager != null) { + try { + serialPortManager.closeSerialPort(); + LogManager.logInfo(TAG, "485串口已关闭并清理资源"); + } catch (Exception e) { + LogManager.logError(TAG, "关闭485串口时发生异常: " + e.getMessage(), e); + } + } } - // ========== 删除所有懒加载连接管理相关方法 ========== - // 删除initConnectionCheckTask、startConnectionCheck、stopConnectionCheck、 - // ensureConnection、createConnection、retryConnection、markSuccessfulCommunication、 - // isSerialPortReallyOpen等方法 - /** * HEX字符串转字节数组 * @param hexString HEX字符串