package com.shlb.comb.activity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.text.Html; import android.widget.Toast; import com.shlb.comb.R; import com.shlb.comb.base.BaseActivity; import com.shlb.comb.event.UpdateEvent; import com.shlb.comb.manager.BleGlobalManager; import com.shlb.comb.util.CMD; import com.shlb.comb.util.CRCutil; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; public class AdvancedSettingActivity extends BaseActivity { private EditText et_mainboard_version; private Button btn_mainboard_read; private EditText et_display_version; private Button btn_display_read; private Button btn_start_addressing; private Button btn_end_addressing; private Button btn_clear_log; private TextView tv_log; private TextView tv_right_text; private TextView tv_mainboard_status; private TextView tv_sensor_status; private StringBuilder logBuilder = new StringBuilder(); private String currentExecutingCmd = ""; private View currentOperatingButton; @Override protected void contentView() { setContentView(R.layout.activity_advanced_setting); } @Override protected void initView() { super.initHead(); if (tv_center != null) { tv_center.setText("高级设置"); } if (iv_left != null) { iv_left.setImageResource(R.mipmap.icon_back); } et_mainboard_version = findViewById(R.id.et_mainboard_version); btn_mainboard_read = findViewById(R.id.btn_mainboard_read); et_display_version = findViewById(R.id.et_display_version); btn_display_read = findViewById(R.id.btn_display_read); btn_start_addressing = findViewById(R.id.btn_start_addressing); btn_end_addressing = findViewById(R.id.btn_end_addressing); btn_clear_log = findViewById(R.id.btn_clear_log); tv_log = findViewById(R.id.tv_log); tv_right_text = findViewById(R.id.tv_right_text); tv_mainboard_status = findViewById(R.id.tv_mainboard_status); tv_sensor_status = findViewById(R.id.tv_sensor_status); // Initialize log logBuilder.append("日志记录:
"); tv_log.setText(Html.fromHtml(logBuilder.toString())); } @Override protected void initData() { updateBluetoothStatus(); if (BleGlobalManager.getInstance().isConnected()) { sendCmdWithCrc(CMD.ENTER_SETTING); triggerAutoRead(); } } @Override protected void onDestroy() { if (BleGlobalManager.getInstance().isConnected()) { sendCmdWithCrc(CMD.EXIT_SETTING); } super.onDestroy(); } @Override protected void initEvent() { View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { int id = v.getId(); String action = ""; if (id == R.id.btn_mainboard_read) { currentOperatingButton = btn_mainboard_read; updateButtonState(currentOperatingButton, false); action = "读取主板版本"; currentExecutingCmd = CMD.READ_BOARD_VERSION; sendCmdWithCrc(CMD.READ_BOARD_VERSION); } else if (id == R.id.btn_display_read) { currentOperatingButton = btn_display_read; updateButtonState(currentOperatingButton, false); action = "读取传感器版本"; currentExecutingCmd = CMD.READ_SENSOR_VERSION; sendCmdWithCrc(CMD.READ_SENSOR_VERSION); } else if (id == R.id.btn_start_addressing) { currentOperatingButton = btn_start_addressing; updateButtonState(currentOperatingButton, false); action = "开始编址"; currentExecutingCmd = CMD.WRITE_START_ADDRESS; sendCmdWithCrc(CMD.WRITE_START_ADDRESS); } else if (id == R.id.btn_end_addressing) { currentOperatingButton = btn_end_addressing; updateButtonState(currentOperatingButton, false); action = "结束编址"; currentExecutingCmd = CMD.WRITE_END_ADDRESS; sendCmdWithCrc(CMD.WRITE_END_ADDRESS); } else if (id == R.id.btn_clear_log) { logBuilder.setLength(0); logBuilder.append("日志记录:
"); tv_log.setText(Html.fromHtml(logBuilder.toString())); } if (!action.isEmpty() && id != R.id.btn_start_addressing && id != R.id.btn_end_addressing) { // Toast.makeText(AdvancedSettingActivity.this, action, Toast.LENGTH_SHORT).show(); // addLog(action); } } }; btn_mainboard_read.setOnClickListener(listener); btn_display_read.setOnClickListener(listener); btn_start_addressing.setOnClickListener(listener); btn_end_addressing.setOnClickListener(listener); btn_clear_log.setOnClickListener(listener); } private void addLog(String message) { appendLog(message, null); } private String getCmdDescription(String hex) { if (hex == null) return ""; // 发送指令匹配 if (hex.startsWith(CMD.ENTER_SETTING)) return "-进入设定"; if (hex.startsWith(CMD.EXIT_SETTING)) return "-退出设定"; if (hex.startsWith(CMD.READ_BOARD_VERSION)) return "-读取主板版本"; if (hex.startsWith(CMD.READ_SENSOR_VERSION)) return "-读取传感器版本"; if (hex.startsWith(CMD.WRITE_START_ADDRESS)) return "-开始编址"; if (hex.startsWith(CMD.WRITE_END_ADDRESS)) return "-结束编址"; // 接收数据匹配 // 读取主板版本返回 (A55A03 0A ...) if (hex.startsWith("A55A030A")) return "-读取主板版本"; // 读取传感器版本返回 (A55A03 0B ...) if (hex.startsWith("A55A030B")) return "-读取传感器版本"; // 写入返回 (A55A06开头) if (hex.startsWith("A55A06") && hex.length() >= 12) { return "-写入返回"; } return ""; } private void appendLog(String msg, Boolean isSent) { String time = com.blankj.utilcode.util.TimeUtils.getNowString(new java.text.SimpleDateFormat("HH:mm:ss.SSS")); String displayMsg = msg; String cmdDesc = ""; // 如果是 hex 指令 (纯 0-9 A-F a-f),加空格格式化 if (msg.matches("^[0-9A-Fa-f]+$")) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < msg.length(); i += 2) { if (i + 2 <= msg.length()) { sb.append(msg.substring(i, i + 2)).append(" "); } else { sb.append(msg.substring(i)); } } displayMsg = sb.toString().trim(); // 获取指令描述 cmdDesc = getCmdDescription(msg); } String logLine; if (isSent != null) { String color = isSent ? "#1890ff" : "#05aa87"; // Blue for sent, Green for received // 拼接到前缀后面: "发送-读站号: " 或 "收到-读站号: " String prefix = (isSent ? "发送" : "收到") + cmdDesc + ": "; logLine = time + " " + prefix + displayMsg + "
"; } else { // System/Local log (Black) logLine = time + " " + displayMsg + "
"; } logBuilder.append(logLine); if (tv_log != null) { tv_log.setText(Html.fromHtml(logBuilder.toString())); } } private void updateBluetoothStatus() { if (tv_right_text == null) return; if (BleGlobalManager.getInstance().isConnected()) { String name = "未知设备"; if (BleGlobalManager.getInstance().getBluetoothLeDevice() != null) { String deviceName = BleGlobalManager.getInstance().getBluetoothLeDevice().getName(); if (deviceName != null && !deviceName.isEmpty()) { name = deviceName; } } tv_right_text.setText(name); } else { tv_right_text.setText("未连接"); } } private void triggerAutoRead() { showLoading("正在同步版本信息..."); // Reset status setLabelStatus(tv_mainboard_status, "", R.color.base_text); setLabelStatus(tv_sensor_status, "", R.color.base_text); // Read Mainboard new android.os.Handler().postDelayed(() -> { if (btn_mainboard_read != null) btn_mainboard_read.performClick(); }, 200); // Read Sensor new android.os.Handler().postDelayed(() -> { if (btn_display_read != null) btn_display_read.performClick(); }, 1200); // Hide loading new android.os.Handler().postDelayed(() -> hiddeLoading(), 2500); } private void setLabelStatus(TextView view, String text, int colorResId) { if (view != null) { view.setText(text); view.setTextColor(getResources().getColor(colorResId)); } } private void sendCmdWithCrc(String cmd) { if (!BleGlobalManager.getInstance().isConnected()) { Toast.makeText(this, "请先连接蓝牙", Toast.LENGTH_SHORT).show(); addLog("错误: 蓝牙未连接"); return; } byte[] cmdBytes = BleGlobalManager.hexStringToBytes(cmd); if (cmdBytes != null) { String crc = CRCutil.getCRC(cmdBytes); // Pad CRC to 4 chars if needed while (crc.length() < 4) { crc = "0" + crc; } String fullCmd = cmd + crc.toUpperCase(); appendLog(fullCmd, true); // true for sent (Blue) BleGlobalManager.getInstance().sendCmd(fullCmd); } else { addLog("错误: 指令转换失败"); } } private void updateButtonState(View btn, boolean enable) { if (btn == null) return; btn.setEnabled(enable); if (enable) { btn.getBackground().clearColorFilter(); } else { btn.getBackground().setColorFilter(android.graphics.Color.GRAY, android.graphics.PorterDuff.Mode.MULTIPLY); } } private void restoreCurrentButton() { if (currentOperatingButton != null) { updateButtonState(currentOperatingButton, true); currentOperatingButton = null; } } @Subscribe(threadMode = ThreadMode.MAIN) public void onEvent(UpdateEvent event) { if (event.getType() == UpdateEvent.Type.CONN_STATU) { updateBluetoothStatus(); if (event.getObj() instanceof Integer && (int) event.getObj() == android.bluetooth.BluetoothProfile.STATE_CONNECTED) { triggerAutoRead(); } } else if (event.getType() == UpdateEvent.Type.DEVICE_INFO) { String hex = event.getMsg(); appendLog(hex, false); // false for received (Green) parseAndRefresh(hex); } } private void parseAndRefresh(String hex) { if (hex == null) return; // 写入指令的返回 (A55A06开头) if (hex.startsWith("A55A06") && hex.length() >= 12) { restoreCurrentButton(); parseWriteResponse(hex); return; } // 读取指令的返回 (A55A03开头) if (hex.startsWith("A55A03") && hex.length() >= 8) { restoreCurrentButton(); parseReadResponse(hex); } } private void parseReadResponse(String hex) { try { // 命令类型: 第7-8位 (Index 6-8) String cmdType = hex.substring(6, 8); // 数据部分通常从第11-12位开始 (Index 10) // 假设版本号数据就在后面 String dataHex = ""; if (hex.length() > 10) { // 去掉CRC (最后4位)? 不确定长度,先取所有 // 暂时取 substring(10) 直到 length-4 (如果带CRC) // 简单起见,取 substring(10) dataHex = hex.substring(10); // 如果最后4位是CRC,可能需要去掉。通常 CRC 是最后4字符。 if (dataHex.length() > 4) { dataHex = dataHex.substring(0, dataHex.length() - 4); } } if ("0A".equals(cmdType)) { // 主板版本 String version = formatVersionHex(dataHex); if (et_mainboard_version != null) et_mainboard_version.setText(version); setLabelStatus(tv_mainboard_status, "(读取值)", R.color.base_color); addLog("读取主板版本成功: " + version); } else if ("0B".equals(cmdType)) { // 传感器版本 String version = formatVersionHex(dataHex); if (et_display_version != null) et_display_version.setText(version); setLabelStatus(tv_sensor_status, "(读取值)", R.color.base_color); addLog("读取传感器版本成功: " + version); } } catch (Exception e) { e.printStackTrace(); addLog("解析读取返回异常: " + e.getMessage()); } } private String formatVersionHex(String hex) { if (hex == null || hex.isEmpty()) return ""; StringBuilder sb = new StringBuilder(); for (int i = 0; i < hex.length(); i++) { sb.append(hex.charAt(i)); if (i % 2 == 1 && i < hex.length() - 1) { sb.append("-"); } } return sb.toString(); } private void parseWriteResponse(String hex) { try { // 写入指令的返回 (A55A06开头) if (hex.startsWith("A55A06") && hex.length() >= 12) { // 结果状态: 第11-12位 (Index 10-12) String statusHex = hex.substring(10, 12); boolean isSuccess = "01".equals(statusHex); if (!currentExecutingCmd.isEmpty()) { if (isSuccess) { if (currentExecutingCmd.startsWith(CMD.WRITE_START_ADDRESS)) { addLog("开始编址成功"); Toast.makeText(this, "开始编址成功", Toast.LENGTH_SHORT).show(); } else if (currentExecutingCmd.startsWith(CMD.WRITE_END_ADDRESS)) { addLog("结束编址成功"); Toast.makeText(this, "结束编址成功", Toast.LENGTH_SHORT).show(); } } else { addLog("操作失败: " + hex); Toast.makeText(this, "操作失败", Toast.LENGTH_SHORT).show(); } // Reset current command after handling currentExecutingCmd = ""; } } } catch (Exception e) { e.printStackTrace(); addLog("解析异常: " + e.getMessage()); } } }