package com.shlb.comb.activity;
|
|
import android.app.AlertDialog;
|
import android.content.DialogInterface;
|
import android.text.Html;
|
import android.view.LayoutInflater;
|
import android.view.View;
|
import android.view.ViewGroup;
|
import android.widget.Button;
|
import android.widget.EditText;
|
import android.widget.ScrollView;
|
import android.widget.Spinner;
|
import android.widget.TextView;
|
import android.widget.Toast;
|
|
import androidx.annotation.NonNull;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.RecyclerView;
|
|
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButton;
|
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.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Locale;
|
|
public class ParameterSettingActivity extends BaseActivity {
|
|
// 阈值设定相关控件
|
private Spinner sp_threshold_mode;
|
private EditText et_threshold_value;
|
|
private Button btn_threshold_write;
|
|
// 灵敏度设定相关控件
|
private Spinner sp_sensitivity_mode;
|
private EditText et_sensitivity_value;
|
|
private Button btn_sensitivity_write;
|
|
// 自检和复位按钮
|
private Button btn_start_check;
|
private Button btn_end_check;
|
private Button btn_reset_mainboard;
|
private Button btn_reset_sensor;
|
|
// 日志和状态显示
|
private TextView tv_log;
|
private TextView tv_right_text;
|
private androidx.cardview.widget.CardView cvLog;
|
|
// 自检监测网格和日志控件
|
private RecyclerView rvGrid;
|
private QMUIRoundButton btnReadData;
|
private QMUIRoundButton btnClearLog;
|
private ScrollView svLog;
|
|
// 数据相关
|
private GridAdapter mAdapter;
|
private List<BoxStatus> boxStatusList = new ArrayList<>();
|
private StringBuilder logBuilder = new StringBuilder();
|
private boolean isSelfCheckMode = false; // 标记当前是否处于自检模式
|
private String pendingSettingCmd = ""; // 记录待处理的设定指令
|
private Button currentOperatingButton; // 当前正在操作的按钮
|
private String pendingToastMessage = null; // 待显示的Toast消息
|
|
private SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
|
|
@Override
|
protected void contentView() {
|
setContentView(R.layout.activity_parameter_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);
|
}
|
|
sp_threshold_mode = findViewById(R.id.sp_threshold_mode);
|
et_threshold_value = findViewById(R.id.et_threshold_value);
|
|
btn_threshold_write = findViewById(R.id.btn_threshold_write);
|
|
sp_sensitivity_mode = findViewById(R.id.sp_sensitivity_mode);
|
et_sensitivity_value = findViewById(R.id.et_sensitivity_value);
|
|
btn_sensitivity_write = findViewById(R.id.btn_sensitivity_write);
|
|
btn_start_check = findViewById(R.id.btn_start_check);
|
btn_end_check = findViewById(R.id.btn_end_check);
|
btn_reset_mainboard = findViewById(R.id.btn_reset_mainboard);
|
btn_reset_sensor = findViewById(R.id.btn_reset_sensor);
|
|
tv_log = findViewById(R.id.tv_log);
|
cvLog = findViewById(R.id.cv_log);
|
tv_right_text = findViewById(R.id.tv_right_text);
|
|
// 初始化自检监测相关控件
|
rvGrid = findViewById(R.id.rv_grid);
|
btnClearLog = findViewById(R.id.btn_clear_log);
|
svLog = findViewById(R.id.sv_log);
|
|
// 设置日志滚动视图的触摸监听,防止滑动冲突
|
if (svLog != null) {
|
svLog.setOnTouchListener((v, event) -> {
|
v.getParent().requestDisallowInterceptTouchEvent(true);
|
if ((event.getAction() & android.view.MotionEvent.ACTION_MASK) == android.view.MotionEvent.ACTION_UP) {
|
v.getParent().requestDisallowInterceptTouchEvent(false);
|
}
|
return false;
|
});
|
}
|
|
// 初始化日志内容
|
if (logBuilder.length() > 0) {
|
tv_log.setText(Html.fromHtml(logBuilder.toString()));
|
} else {
|
logBuilder.append("日志记录:<br>");
|
tv_log.setText(Html.fromHtml(logBuilder.toString()));
|
}
|
}
|
|
@Override
|
protected void initData() {
|
updateBluetoothStatus();
|
|
// 初始化30个格子的状态列表
|
boxStatusList.clear();
|
for (int i = 1; i <= 30; i++) {
|
boxStatusList.add(new BoxStatus(i));
|
}
|
|
// 设置网格布局:3行10列
|
rvGrid.setLayoutManager(new GridLayoutManager(this, 10));
|
mAdapter = new GridAdapter();
|
rvGrid.setAdapter(mAdapter);
|
|
// 如果蓝牙已连接,进入设定模式
|
if (BleGlobalManager.getInstance().isConnected()) {
|
sendCmdWithCrc(CMD.ENTER_SETTING);
|
}
|
}
|
|
@Override
|
protected void onResume() {
|
super.onResume();
|
// 根据系统设置控制日志显示
|
boolean isCmdLogEnabled = com.blankj.utilcode.util.SPUtils.getInstance().getBoolean("cmd_log_enabled", false);
|
if (cvLog != null) {
|
cvLog.setVisibility(isCmdLogEnabled ? View.VISIBLE : View.GONE);
|
}
|
}
|
|
@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_threshold_write) {
|
handleThresholdWrite();
|
} else if (id == R.id.btn_sensitivity_write) {
|
handleSensitivityWrite();
|
} else if (id == R.id.btn_start_check) {
|
if (BleGlobalManager.getInstance().isConnected()) {
|
currentOperatingButton = btn_start_check;
|
updateButtonState(currentOperatingButton, false);
|
action = "开始自检";
|
setAllGridGray();
|
sendCmdWithCrc(CMD.WRITE_START_CHECK);
|
isSelfCheckMode = true;
|
} else {
|
Toast.makeText(ParameterSettingActivity.this, "请先连接蓝牙", Toast.LENGTH_SHORT).show();
|
}
|
} else if (id == R.id.btn_end_check) {
|
if (BleGlobalManager.getInstance().isConnected()) {
|
currentOperatingButton = btn_end_check;
|
updateButtonState(currentOperatingButton, false);
|
action = "结束自检";
|
setAllGridGray();
|
sendCmdWithCrc(CMD.WRITE_END_CHECK);
|
isSelfCheckMode = false;
|
} else {
|
Toast.makeText(ParameterSettingActivity.this, "请先连接蓝牙", Toast.LENGTH_SHORT).show();
|
}
|
} else if (id == R.id.btn_reset_mainboard) {
|
currentOperatingButton = btn_reset_mainboard;
|
showResetConfirmDialog("确定要执行主板复位吗?", CMD.WRITE_BOARD_RESET);
|
} else if (id == R.id.btn_reset_sensor) {
|
currentOperatingButton = btn_reset_sensor;
|
showResetConfirmDialog("确定要执行传感器复位吗?", CMD.WRITE_SENSOR_RESET);
|
}
|
|
if (!action.isEmpty()) {
|
// Toast.makeText(ParameterSettingActivity.this, action, Toast.LENGTH_SHORT).show();
|
// appendLog(action);
|
}
|
}
|
};
|
|
|
btn_threshold_write.setOnClickListener(listener);
|
|
btn_sensitivity_write.setOnClickListener(listener);
|
btn_start_check.setOnClickListener(listener);
|
btn_end_check.setOnClickListener(listener);
|
btn_reset_mainboard.setOnClickListener(listener);
|
btn_reset_sensor.setOnClickListener(listener);
|
|
// 阈值模式选择监听,控制输入框是否可用
|
sp_threshold_mode.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() {
|
@Override
|
public void onItemSelected(android.widget.AdapterView<?> parent, View view, int position, long id) {
|
if (position == 0) {
|
// 一键设定,隐藏输入框 (使用INVISIBLE保留占位,防止按钮移位)
|
et_threshold_value.setVisibility(View.INVISIBLE);
|
et_threshold_value.setText("");
|
} else {
|
// 单层设定,显示输入框
|
et_threshold_value.setVisibility(View.VISIBLE);
|
int maxLayer = com.blankj.utilcode.util.SPUtils.getInstance().getInt("layer_count", 30);
|
et_threshold_value.setHint("1-" + maxLayer);
|
}
|
}
|
|
@Override
|
public void onNothingSelected(android.widget.AdapterView<?> parent) {
|
}
|
});
|
|
|
|
// 灵敏度模式选择监听,控制输入框是否可用
|
sp_sensitivity_mode.setOnItemSelectedListener(new android.widget.AdapterView.OnItemSelectedListener() {
|
@Override
|
public void onItemSelected(android.widget.AdapterView<?> parent, View view, int position, long id) {
|
// 0: 批量增加, 1: 批量减少, 2: 单层增加, 3: 单层减少
|
if (position == 0 || position == 1) {
|
// 批量操作,隐藏输入框
|
et_sensitivity_value.setVisibility(View.INVISIBLE);
|
et_sensitivity_value.setText("");
|
} else {
|
// 单层操作,显示输入框
|
et_sensitivity_value.setVisibility(View.VISIBLE);
|
int maxLayer = com.blankj.utilcode.util.SPUtils.getInstance().getInt("layer_count", 30);
|
et_sensitivity_value.setHint("1-" + maxLayer);
|
}
|
}
|
|
@Override
|
public void onNothingSelected(android.widget.AdapterView<?> parent) {
|
}
|
});
|
|
btnClearLog.setOnClickListener(v -> {
|
logBuilder.setLength(0);
|
logBuilder.append("日志记录:<br>");
|
tv_log.setText(Html.fromHtml(logBuilder.toString()));
|
});
|
}
|
|
private String getCmdDescription(String hex, Boolean isSent) {
|
if (hex == null) return "";
|
|
// 进入/退出设定模式指令特殊处理
|
if (hex.startsWith(CMD.ENTER_SETTING.substring(0, 8))) {
|
if (hex.startsWith(CMD.ENTER_SETTING)) return "-进入设定";
|
if (hex.startsWith(CMD.EXIT_SETTING)) return "-退出设定";
|
}
|
|
// 发送指令匹配
|
if (hex.startsWith(CMD.WRITE_THRESHOLD_SETTING)) return "-阈值设定";
|
if (hex.startsWith(CMD.WRITE_SENSITIVITY_SETTING)) return "-灵敏度设定";
|
if (hex.startsWith(CMD.WRITE_BOARD_RESET)) return "-主板复位";
|
if (hex.startsWith(CMD.WRITE_SENSOR_RESET)) return "-传感器复位";
|
if (hex.startsWith(CMD.WRITE_START_CHECK)) return "-开始自检";
|
if (hex.startsWith(CMD.WRITE_END_CHECK)) return "-结束自检";
|
if (hex.startsWith(CMD.READ_DATA.substring(0, 8))) return "-读数据";
|
|
// 接收数据匹配
|
if (hex.startsWith(CMD.WRITE_THRESHOLD_SETTING.substring(0, 8))) return "-阈值返回";
|
if (hex.startsWith(CMD.WRITE_SENSITIVITY_SETTING.substring(0, 8))) return "-灵敏度返回";
|
if (hex.startsWith(CMD.WRITE_BOARD_RESET.substring(0, 8))) return "-主板复位返回";
|
if (hex.startsWith(CMD.WRITE_SENSOR_RESET.substring(0, 8))) return "-传感器复位返回";
|
if (hex.startsWith(CMD.WRITE_START_CHECK.substring(0, 8))) return "-自检返回";
|
|
if (hex.startsWith(CMD.WRITE_SUFFIX)) return "-写入返回";
|
|
return "";
|
}
|
|
private void appendLog(String msg) {
|
appendLog(msg, null);
|
}
|
|
private void appendLog(String msg, Boolean isSent) {
|
String time = new SimpleDateFormat("HH:mm:ss.SSS", Locale.getDefault()).format(new Date());
|
|
String displayMsg = msg;
|
String cmdDesc = "";
|
|
// 如果是十六进制指令,每两位加一个空格格式化显示
|
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, isSent);
|
}
|
|
String logLine;
|
if (isSent != null) {
|
// 发送指令用蓝色,接收数据用绿色
|
String color = isSent ? "#1890ff" : "#05aa87";
|
String prefix = (isSent ? "发送" : "收到") + cmdDesc + ": ";
|
logLine = time + " <font color='" + color + "'>" + prefix + displayMsg + "</font><br>";
|
} else {
|
// 普通日志
|
logLine = time + " " + displayMsg + "<br>";
|
}
|
|
logBuilder.append(logLine);
|
|
// 更新日志显示并自动滚动到底部
|
if (tv_log != null) {
|
tv_log.setText(Html.fromHtml(logBuilder.toString()));
|
if (svLog != null) {
|
svLog.post(() -> svLog.fullScroll(View.FOCUS_DOWN));
|
}
|
}
|
}
|
|
// 兼容旧代码的日志方法
|
private void addLog(String message) {
|
appendLog(message);
|
}
|
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
public void onEvent(UpdateEvent event) {
|
if (event.getType() == UpdateEvent.Type.CONN_STATU) {
|
updateBluetoothStatus();
|
} else if (event.getType() == UpdateEvent.Type.DEVICE_INFO) {
|
String hex = event.getMsg();
|
appendLog(hex, false); // false表示接收的数据,显示为绿色
|
parseAndRefresh(hex);
|
}
|
}
|
|
private void parseAndRefresh(String hex) {
|
if (hex == null) return;
|
|
// 处理写入指令的返回(A55A06开头)
|
if (hex.startsWith(CMD.WRITE_SUFFIX) && hex.length() >= 12) {
|
// 提取状态字节,01表示成功
|
String statusHex = hex.substring(10, 12);
|
boolean isSuccess = "01".equals(statusHex);
|
|
// 处理进入设定模式的返回
|
if (hex.startsWith(CMD.ENTER_SETTING.substring(0, 8))) {
|
if (isSuccess) {
|
appendLog("进入设定模式成功");
|
} else {
|
appendLog("进入设定模式失败");
|
}
|
return;
|
}
|
|
// 处理退出设定模式的返回
|
if (hex.startsWith(CMD.EXIT_SETTING.substring(0, 8))) {
|
appendLog("退出设定模式成功");
|
return;
|
}
|
|
// 处理阈值设定的返回
|
if (hex.startsWith(CMD.WRITE_THRESHOLD_SETTING.substring(0, 8))) {
|
if (isSuccess) {
|
appendLog("阈值写入成功");
|
pendingToastMessage = "阈值写入成功";
|
// 阈值写入成功后,等待500毫秒再读取数据
|
appendLog("500毫秒后读取阈值设定结果...");
|
new android.os.Handler().postDelayed(() -> {
|
sendCmdWithCrc(CMD.READ_DATA);
|
}, 500);
|
} else {
|
restoreCurrentButton();
|
appendLog("阈值写入失败");
|
Toast.makeText(this, "阈值写入失败", Toast.LENGTH_SHORT).show();
|
}
|
} else if (hex.startsWith(CMD.WRITE_SENSITIVITY_SETTING.substring(0, 8))) {
|
// 处理灵敏度设定的返回
|
if (isSuccess) {
|
appendLog("灵敏度写入成功");
|
pendingToastMessage = "灵敏度写入成功";
|
// 灵敏度写入成功后,等待500毫秒再读取数据
|
appendLog("500毫秒后读取灵敏度设定结果...");
|
new android.os.Handler().postDelayed(() -> {
|
sendCmdWithCrc(CMD.READ_DATA);
|
}, 500);
|
} else {
|
restoreCurrentButton();
|
appendLog("灵敏度写入失败");
|
Toast.makeText(this, "灵敏度写入失败", Toast.LENGTH_SHORT).show();
|
}
|
} else if (hex.startsWith(CMD.WRITE_BOARD_RESET.substring(0, 8))) {
|
// 处理主板/传感器复位的返回
|
// 判断是主板复位还是传感器复位
|
boolean isBoardReset = pendingSettingCmd.equals(CMD.WRITE_BOARD_RESET);
|
String name = isBoardReset ? "主板复位" : "传感器复位";
|
|
if (isSuccess) {
|
appendLog(name + "成功");
|
|
// 如果是主板复位成功,提示即将返回并跳转到实时监控页面
|
if (isBoardReset) {
|
Toast.makeText(this, "复位成功即将返回", Toast.LENGTH_SHORT).show();
|
appendLog("复位成功,2秒后返回实时监控页面...");
|
|
// 2秒后返回到实时监控页面
|
new android.os.Handler().postDelayed(() -> {
|
finish(); // 关闭当前页面,返回到实时监控页面
|
}, 2000);
|
} else {
|
// 传感器复位成功,提示并在500毫秒后读取数据
|
Toast.makeText(this, name + "成功", Toast.LENGTH_SHORT).show();
|
|
// 500毫秒后读取数据,通过现有的parseSelfCheckData解析
|
new android.os.Handler().postDelayed(() -> {
|
sendCmdWithCrc(CMD.READ_DATA);
|
}, 500);
|
}
|
} else {
|
restoreCurrentButton();
|
appendLog(name + "失败");
|
Toast.makeText(this, name + "失败", Toast.LENGTH_SHORT).show();
|
}
|
}
|
}
|
|
// 处理自检指令的返回结果
|
// 开始自检和结束自检的指令前缀相同,都是 CMD.WRITE_START_CHECK 的前8位
|
if (hex.startsWith(CMD.WRITE_START_CHECK.substring(0, 8)) && hex.length() >= 12) {
|
// 提取状态字节(第11-12位),01表示成功,其他表示失败
|
String statusHex = hex.substring(10, 12);
|
boolean isSuccess = "01".equals(statusHex);
|
// 根据当前模式判断操作名称
|
String opName = isSelfCheckMode ? "开始自检" : "结束自检";
|
|
if (isSuccess) {
|
appendLog(opName + "成功");
|
pendingToastMessage = opName + "成功";
|
|
// 根据不同的自检阶段,延迟不同时间后读取数据
|
if (isSelfCheckMode) {
|
// 开始自检成功后,等待 层数 * 1000 毫秒再读取数据
|
int layerCount = com.blankj.utilcode.util.SPUtils.getInstance().getInt("layer_count", 3);
|
long delay = layerCount * 1000L;
|
Toast.makeText(this, "开始自检,请等待" + layerCount + "秒", Toast.LENGTH_SHORT).show();
|
// 这个时间是为了让传感器完成自检动作
|
appendLog(delay + "毫秒后读取自检结果...");
|
new android.os.Handler().postDelayed(() -> {
|
sendCmdWithCrc(CMD.READ_DATA);
|
}, delay);
|
} else {
|
// 结束自检成功后,等待500毫秒再读取数据
|
// 这个时间是为了让设备状态稳定后再读取最终结果
|
appendLog("500毫秒后读取自检结果...");
|
new android.os.Handler().postDelayed(() -> {
|
sendCmdWithCrc(CMD.READ_DATA);
|
}, 500);
|
}
|
} else {
|
appendLog(opName + "失败");
|
Toast.makeText(this, opName + "失败", Toast.LENGTH_SHORT).show();
|
}
|
}
|
|
// 处理读取数据指令的返回结果,用于显示自检结果
|
// 数据格式:A55A0301... 至少需要26位十六进制字符
|
if (hex.startsWith(CMD.READ_DATA.substring(0, 8)) && hex.length() >= 26) {
|
restoreCurrentButton();
|
parseSelfCheckData(hex);
|
if (pendingToastMessage != null) {
|
Toast.makeText(this, pendingToastMessage, Toast.LENGTH_SHORT).show();
|
pendingToastMessage = null;
|
}
|
}
|
}
|
|
/**
|
* 解析自检数据并更新格子状态
|
* @param hex 接收到的十六进制数据
|
*/
|
private void parseSelfCheckData(String hex) {
|
try {
|
// 提取第11-18位(8个字符)作为第一部分数据
|
String part1Hex = hex.substring(10, 18);
|
long part1Bits = Long.parseLong(part1Hex, 16);
|
|
// 提取第19-26位(8个字符)作为第二部分数据
|
String part2Hex = hex.substring(18, 26);
|
long part2Bits = Long.parseLong(part2Hex, 16);
|
|
appendLog("自检数据解析: " + part1Hex + ", " + part2Hex);
|
|
boolean hasChange = false;
|
// 遍历所有格子,根据位数据判断自检结果
|
for (BoxStatus box : boxStatusList) {
|
int bitIndex = box.id - 1; // 格子ID从1开始,位索引从0开始
|
if (bitIndex >= 0 && bitIndex < 32) {
|
// 提取对应位的值
|
boolean bit1 = ((part1Bits >> bitIndex) & 1) == 1;
|
boolean bit2 = ((part2Bits >> bitIndex) & 1) == 1;
|
|
// 两个位都为1表示自检成功,否则失败
|
if (bit1 && bit2) {
|
box.checkResult = 1; // 成功,显示绿色
|
} else {
|
box.checkResult = 0; // 失败,显示红色
|
}
|
hasChange = true;
|
}
|
}
|
|
// 如果有数据变化,刷新界面
|
if (hasChange && mAdapter != null) {
|
mAdapter.notifyDataSetChanged();
|
appendLog("自检结果已更新");
|
}
|
|
} catch (Exception e) {
|
e.printStackTrace();
|
appendLog("自检数据解析异常: " + e.getMessage());
|
}
|
}
|
|
/**
|
* 发送带CRC校验的指令
|
* @param cmd 要发送的指令(不含CRC)
|
*/
|
private void sendCmdWithCrc(String cmd) {
|
if (!BleGlobalManager.getInstance().isConnected()) {
|
Toast.makeText(this, "请先连接蓝牙", Toast.LENGTH_SHORT).show();
|
appendLog("错误: 蓝牙未连接");
|
return;
|
}
|
|
byte[] cmdBytes = BleGlobalManager.hexStringToBytes(cmd);
|
if (cmdBytes != null) {
|
// 计算CRC校验码
|
String crc = CRCutil.getCRC(cmdBytes);
|
// CRC补齐到4位
|
while (crc.length() < 4) {
|
crc = "0" + crc;
|
}
|
String fullCmd = cmd + crc.toUpperCase();
|
|
appendLog(fullCmd, true); // true表示发送的指令,显示为蓝色
|
BleGlobalManager.getInstance().sendCmd(fullCmd);
|
} else {
|
appendLog("错误: 指令转换失败");
|
}
|
}
|
|
/**
|
* 处理阈值设定写入
|
*/
|
private void handleThresholdWrite() {
|
int position = sp_threshold_mode.getSelectedItemPosition();
|
String inputValue = et_threshold_value.getText().toString().trim();
|
String modeHex = "";
|
String valueHex = "";
|
|
if (position == 0) {
|
// 一键设定
|
modeHex = "00";
|
valueHex = "00";
|
} else if (position == 1) {
|
// 单层设定
|
modeHex = "01";
|
int maxLayer = com.blankj.utilcode.util.SPUtils.getInstance().getInt("layer_count", 30);
|
if (inputValue.isEmpty()) {
|
Toast.makeText(this, "请输入阈值(1-" + maxLayer + ")", Toast.LENGTH_SHORT).show();
|
return;
|
}
|
try {
|
int val = Integer.parseInt(inputValue);
|
if (val < 1 || val > maxLayer) {
|
Toast.makeText(this, "阈值范围1-" + maxLayer, Toast.LENGTH_SHORT).show();
|
return;
|
}
|
// 单层设定时,输入参数需要减1
|
valueHex = String.format("%02X", val - 1);
|
} catch (NumberFormatException e) {
|
Toast.makeText(this, "输入格式错误", Toast.LENGTH_SHORT).show();
|
return;
|
}
|
} else {
|
return;
|
}
|
|
// 构造指令:CMD.WRITE_THRESHOLD_SETTING + 模式 + 值
|
pendingSettingCmd = CMD.WRITE_THRESHOLD_SETTING + modeHex + valueHex;
|
if (BleGlobalManager.getInstance().isConnected()) {
|
currentOperatingButton = btn_threshold_write;
|
updateButtonState(currentOperatingButton, false);
|
setAllGridGray();
|
sendCmdWithCrc(pendingSettingCmd);
|
} else {
|
Toast.makeText(this, "请先连接蓝牙", Toast.LENGTH_SHORT).show();
|
}
|
}
|
|
/**
|
* 将所有格子设置为灰色(等待状态)
|
*/
|
private void setAllGridGray() {
|
for (BoxStatus box : boxStatusList) {
|
box.checkResult = 2; // 2表示等待状态,显示灰色
|
}
|
if (mAdapter != null) {
|
mAdapter.notifyDataSetChanged();
|
}
|
}
|
|
/**
|
* 处理灵敏度设定写入
|
*/
|
private void handleSensitivityWrite() {
|
int position = sp_sensitivity_mode.getSelectedItemPosition();
|
String inputValue = et_sensitivity_value.getText().toString().trim();
|
String modeHex = "";
|
String valueHex = "";
|
|
// 模式:0=批量增加(00), 1=批量减少(01), 2=单层增加(02), 3=单层减少(03)
|
if (position == 0) {
|
modeHex = "00";
|
valueHex = "00";
|
} else if (position == 1) {
|
modeHex = "01";
|
valueHex = "00";
|
} else if (position == 2) {
|
modeHex = "02";
|
} else if (position == 3) {
|
modeHex = "03";
|
} else {
|
return;
|
}
|
|
// 单层操作需要输入具体数值
|
if (position == 2 || position == 3) {
|
int maxLayer = com.blankj.utilcode.util.SPUtils.getInstance().getInt("layer_count", 30);
|
if (inputValue.isEmpty()) {
|
Toast.makeText(this, "请输入数值(1-" + maxLayer + ")", Toast.LENGTH_SHORT).show();
|
return;
|
}
|
try {
|
int val = Integer.parseInt(inputValue);
|
if (val < 1 || val > maxLayer) {
|
Toast.makeText(this, "数值范围1-" + maxLayer, Toast.LENGTH_SHORT).show();
|
return;
|
}
|
// 单层设定时,输入参数需要减1
|
valueHex = String.format("%02X", val - 1);
|
} catch (NumberFormatException e) {
|
Toast.makeText(this, "输入格式错误", Toast.LENGTH_SHORT).show();
|
return;
|
}
|
}
|
|
// 构造指令:CMD.WRITE_SENSITIVITY_SETTING + 模式 + 值
|
pendingSettingCmd = CMD.WRITE_SENSITIVITY_SETTING + modeHex + valueHex;
|
if (BleGlobalManager.getInstance().isConnected()) {
|
currentOperatingButton = btn_sensitivity_write;
|
updateButtonState(currentOperatingButton, false);
|
setAllGridGray();
|
sendCmdWithCrc(pendingSettingCmd);
|
} else {
|
Toast.makeText(this, "请先连接蓝牙", Toast.LENGTH_SHORT).show();
|
}
|
}
|
|
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 showResetConfirmDialog(String message, final String cmd) {
|
new AlertDialog.Builder(this)
|
.setTitle("提示")
|
.setMessage(message)
|
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
|
@Override
|
public void onClick(DialogInterface dialog, int which) {
|
if (BleGlobalManager.getInstance().isConnected()) {
|
updateButtonState(currentOperatingButton, false);
|
pendingSettingCmd = cmd;
|
sendCmdWithCrc(cmd);
|
} else {
|
Toast.makeText(ParameterSettingActivity.this, "请先连接蓝牙", Toast.LENGTH_SHORT).show();
|
}
|
}
|
})
|
.setNegativeButton("取消", null)
|
.show();
|
}
|
|
/**
|
* 格子状态数据类
|
*/
|
private static class BoxStatus {
|
int id; // 格子ID(1-30)
|
int checkResult = -1; // 自检结果:-1=未知(白色),0=失败(红色),1=成功(绿色),2=等待(灰色)
|
|
public BoxStatus(int id) {
|
this.id = id;
|
this.checkResult = -1;
|
}
|
}
|
|
private class GridAdapter extends RecyclerView.Adapter<GridAdapter.ViewHolder> {
|
|
@NonNull
|
@Override
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_grid_box, parent, false);
|
return new ViewHolder(view);
|
}
|
|
@Override
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
// 计算格子ID:3行10列,从左到右排列
|
// 第1行(位置0-9):1-10
|
// 第2行(位置10-19):11-20
|
// 第3行(位置20-29):21-30
|
int row = position / 10;
|
int col = position % 10;
|
int boxId = row * 10 + col + 1;
|
|
holder.tvBoxNumber.setText(String.valueOf(boxId));
|
|
// 查找对应格子的状态
|
BoxStatus status = null;
|
for (BoxStatus s : boxStatusList) {
|
if (s.id == boxId) {
|
status = s;
|
break;
|
}
|
}
|
|
// 根据自检结果设置背景颜色
|
if (status != null) {
|
if (status.checkResult == 1) {
|
// 自检成功,显示绿色
|
holder.viewBox.setBackgroundResource(R.drawable.bg_box_full);
|
holder.viewBox.getBackground().clearColorFilter();
|
} else if (status.checkResult == 0) {
|
// 自检失败,显示红色
|
holder.viewBox.setBackgroundResource(R.drawable.bg_box_error);
|
holder.viewBox.getBackground().clearColorFilter();
|
} else if (status.checkResult == 2) {
|
// 等待状态,显示灰色
|
holder.viewBox.setBackgroundResource(R.drawable.bg_box_empty);
|
holder.viewBox.getBackground().setColorFilter(android.graphics.Color.GRAY, android.graphics.PorterDuff.Mode.MULTIPLY);
|
} else {
|
// 未知状态,显示白色
|
holder.viewBox.setBackgroundResource(R.drawable.bg_box_empty);
|
holder.viewBox.getBackground().clearColorFilter();
|
}
|
}
|
}
|
|
@Override
|
public int getItemCount() {
|
return 30;
|
}
|
|
class ViewHolder extends RecyclerView.ViewHolder {
|
TextView tvBoxNumber;
|
View viewBox;
|
|
public ViewHolder(@NonNull View itemView) {
|
super(itemView);
|
tvBoxNumber = itemView.findViewById(R.id.tv_box_number);
|
viewBox = itemView.findViewById(R.id.view_box);
|
}
|
}
|
}
|
|
private void restoreCurrentButton() {
|
if (currentOperatingButton != null) {
|
updateButtonState(currentOperatingButton, true);
|
currentOperatingButton = null;
|
}
|
}
|
|
private void updateButtonState(Button btn, boolean enable) {
|
if (btn == null) return;
|
btn.setEnabled(enable);
|
if (enable) {
|
if (btn.getBackground() != null) {
|
btn.getBackground().clearColorFilter();
|
}
|
} else {
|
if (btn.getBackground() != null) {
|
btn.getBackground().setColorFilter(android.graphics.Color.GRAY, android.graphics.PorterDuff.Mode.MULTIPLY);
|
}
|
}
|
}
|
}
|