From d174f408bf53573fe68d8530027eb560a29dba25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E4=B8=87=E9=87=8C?= <1726150332@qq.com> Date: Mon, 20 Apr 2026 09:41:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=85=A5=E5=BA=93=E7=AD=89?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/example/tyre/HomePageActivity.java | 5 +- .../example/tyre/InStoreHouseActivity.java | 740 +++++------ .../com/example/tyre/TyreLayoutActivity.java | 112 +- .../java/com/example/tyre/UpActivity.java | 1131 ++++++++++------- .../example/tyre/entity/InStoreSpinnerVo.java | 6 +- .../com/example/tyre/entity/TyreSizeVo.java | 22 + .../java/com/example/tyre/util/MyUrl.java | 4 +- .../res/drawable/rounded_border_input.xml | 6 + .../res/drawable/rounded_button_primary.xml | 27 + .../main/res/drawable/rounded_input_bg.xml | 6 + .../main/res/layout/activity_instorehouse.xml | 596 ++++----- app/src/main/res/layout/activity_up.xml | 529 ++++---- app/src/main/res/mipmap-xxhdpi/wb.png | Bin 0 -> 7142 bytes app/src/main/res/values/colors.xml | 1 + 14 files changed, 1757 insertions(+), 1428 deletions(-) create mode 100644 app/src/main/java/com/example/tyre/entity/TyreSizeVo.java create mode 100644 app/src/main/res/drawable/rounded_border_input.xml create mode 100644 app/src/main/res/drawable/rounded_button_primary.xml create mode 100644 app/src/main/res/drawable/rounded_input_bg.xml create mode 100644 app/src/main/res/mipmap-xxhdpi/wb.png diff --git a/app/src/main/java/com/example/tyre/HomePageActivity.java b/app/src/main/java/com/example/tyre/HomePageActivity.java index 32132b1..256a326 100644 --- a/app/src/main/java/com/example/tyre/HomePageActivity.java +++ b/app/src/main/java/com/example/tyre/HomePageActivity.java @@ -46,7 +46,7 @@ public class HomePageActivity extends AppCompatActivity { /** * 修改点 1:在注解列表中加入 R.id.logout */ - @OnClick({R.id.chaxun, R.id.ruku, R.id.chuku, R.id.zhuangxie, R.id.huanwei, R.id.zhijian, R.id.xxbd,R.id.test1, R.id.logout}) + @OnClick({R.id.chaxun, R.id.ruku, R.id.chuku, R.id.zhuangxie, R.id.huanwei, R.id.zhijian, R.id.xxbd,R.id.test1,R.id.test2, R.id.logout}) public void onViewClicked(View view) { Intent intent; // 建议在这里声明,而不是方法最开始 @@ -75,6 +75,9 @@ public class HomePageActivity extends AppCompatActivity { case R.id.test1: intent = new Intent(this, TyreLayoutActivity.class); break; + case R.id.test2: + intent = new Intent(this, TyreLayoutActivity.class); + break; case R.id.logout: // 修改点 2:处理退出逻辑 handleLogout(); diff --git a/app/src/main/java/com/example/tyre/InStoreHouseActivity.java b/app/src/main/java/com/example/tyre/InStoreHouseActivity.java index 9627903..e9201b8 100644 --- a/app/src/main/java/com/example/tyre/InStoreHouseActivity.java +++ b/app/src/main/java/com/example/tyre/InStoreHouseActivity.java @@ -16,11 +16,12 @@ import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; -import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; +import androidx.appcompat.app.AppCompatActivity; + import com.android.hdhe.uhf.reader.UhfReader; import com.android.hdhe.uhf.readerInterface.TagModel; import com.example.tyre.entity.AjaxResult; @@ -28,130 +29,120 @@ import com.example.tyre.entity.BaseTyre; import com.example.tyre.entity.EPC; import com.example.tyre.entity.InStoreSpinnerVo; import com.example.tyre.entity.Tyre; +import com.example.tyre.entity.TyreSizeVo; import com.example.tyre.util.CommonDialog; import com.example.tyre.util.MyUrl; -import com.example.tyre.util.PlayMusic; import com.example.tyre.util.SharedPreferencesUtils; import com.example.tyre.util.Util; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; -import com.google.gson.reflect.TypeToken; import com.lzy.okgo.OkGo; import com.lzy.okgo.callback.StringCallback; import com.lzy.okgo.model.Response; - import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; -import androidx.appcompat.app.AppCompatActivity; import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; + import cn.pda.serialport.Tools; /** - * Created by 杨万里 on 2019/12/10. + * 轮胎入库管理 Activity (优化版) + * 适配重构后的 XML 布局,解决下拉框重影与数据绑定问题 */ +public class InStoreHouseActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener { -public class InStoreHouseActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener{ + // === UI 组件绑定 (基于新布局修正) === + @BindView(R.id.button) Button button; + @BindView(R.id.back) Button back; - @BindView(R.id.button) - Button button; - @BindView(R.id.epc) - TextView scan; - @BindView(R.id.pinpai) - TextView pinpai; - @BindView(R.id.xinghao) - TextView xinghao; - @BindView(R.id.cengji) - TextView cengji; - @BindView(R.id.huawen) - TextView huawen; - @BindView(R.id.gcts) - TextView gcts; - @BindView(R.id.back) - Button back; - @BindView(R.id.wtbm) - EditText wtbm; -// @BindView(R.id.zbh) -// EditText zbh; -// @BindView(R.id.spinner) -// Spinner spinner; - @BindView(R.id.linearLayout3) - LinearLayout linearLayout3; -// @BindView(R.id.czy) -// TextView czy; - @BindView(R.id.tyrekind) - TextView tyrekind; - @BindView(R.id.spinnerkind) - Spinner spinnerkind; + // 1. EPC 相关:原 @BindView(R.id.epc) 是 TextView,现在建议直接读取显示文本或维护内部变量 + // 假设 XML 中 Spinner EPC 的 ID 是 spinnerEPC (根据上一轮修改) + @BindView(R.id.EPC) + TextView EPC; - @BindView(R.id.spinnerpattern) - Spinner spinnerpattern; + // 2. 胎号 (EditText) + @BindView(R.id.wtbm) EditText wtbm; - @BindView(R.id.spinnerlevel) - Spinner spinnerlevel; + // 3. 花纹深度 (EditText) + @BindView(R.id.patternDepth) EditText patternDepth; - @BindView(R.id.spinnerSize) - Spinner spinnerSize; + // 4. 下拉框 Spinners (核心修复点) + @BindView(R.id.spinnerkind) Spinner spinnerkind; + @BindView(R.id.spinnerpattern) Spinner spinnerpattern; + @BindView(R.id.spinnerlevel) Spinner spinnerlevel; + @BindView(R.id.spinnerSize) Spinner spinnerSize; + @BindView(R.id.spinnerBrand) Spinner spinnerBrand; + @BindView(R.id.spinnergcts) Spinner spinnergcts; - @BindView(R.id.spinnerBrand) - Spinner spinnerBrand; + // === 内部数据变量 (用于保存选中的值) === + // 注意:不再需要 pinpai, xinghao 等 TextView 的 BindView + // 我们直接通过 Spinner.getSelectedItem().toString() 获取值 + // 或者定义变量保存 + private String selectedBrand = ""; + private String selectedModel = ""; + private String selectedLevel = ""; + private String selectedPattern = ""; + private String selectedKind = ""; + private String selectedGcts = ""; - @BindView(R.id.spinnergcts) - Spinner spinnergcts; - // private UHFService mDevice; -// private MyHandler handler; + // === 业务逻辑变量 === private boolean isStart = true; private ProgressDialog progressDialog; private boolean runFlag = true; private boolean startFlag = false; - private UhfReader manager; // UHF manager,UHF Operating handle + private UhfReader manager; private ArrayList listEPC; private ArrayList listepc = new ArrayList(); + private List patternSize; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_instorehouse); + setContentView(R.layout.activity_instorehouse); // 确保使用新布局 ButterKnife.bind(this); + manager = MyApplication.getManager(); + initView(); + + // 初始化下拉框数据 check_spinner(); - showLoadingDialog(); + + // 启动 UHF 扫描线程 + Thread thread = new InventoryThread(); + thread.start(); + Util.initSoundPool(this); + } + + private void initView() { + listEPC = new ArrayList(); + // 初始化所有 Spinner 的监听器 + initSpinners(); + } + + /** + * 统一初始化所有 Spinner 的监听器 + * 避免代码重复 + */ + private void initSpinners() { spinnerkind.setOnItemSelectedListener(this); spinnerpattern.setOnItemSelectedListener(this); spinnerlevel.setOnItemSelectedListener(this); spinnerSize.setOnItemSelectedListener(this); spinnerBrand.setOnItemSelectedListener(this); spinnergcts.setOnItemSelectedListener(this); - initView(); - Thread thread = new InventoryThread(); - thread.start(); - com.example.tyre.util.Util.initSoundPool(this); -// spinner.setOnItemSelectedListener(this); - } - private void showLoadingDialog() { - progressDialog = new ProgressDialog(this); - progressDialog.setMessage("数据加载中..."); - progressDialog.setCancelable(false); - progressDialog.show(); - } - private void hideLoadingDialog() { - if (progressDialog != null && progressDialog.isShowing()) { - progressDialog.dismiss(); - } } @Override public void onResume() { super.onResume(); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } + try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } registerReceiver(); + startFlag = false; // 开启扫描 } @Override @@ -163,382 +154,301 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi @Override protected void onDestroy() { - startFlag = false; runFlag = false; super.onDestroy(); } - private void initView() { - listEPC = new ArrayList(); - } - /** - * Inventory EPC Thread - */ + + // === UHF 扫描逻辑优化 === class InventoryThread extends Thread { - private List tagList; - byte[] accessPassword = Tools.HexString2Bytes("00000000"); @Override public void run() { - super.run(); while (runFlag) { if (startFlag) { - tagList = manager.inventoryRealTime(); //实时盘存 + List tagList = manager.inventoryRealTime(); if (tagList != null && !tagList.isEmpty()) { - //播放提示音 - Util.play(1, 0); + Util.play(1, 0); // 播放提示音 for (TagModel tag : tagList) { - if (tag == null) { - String epcStr = ""; -// String epcStr = new String(epc); - addToList(listEPC, epcStr, (byte) -1); - } else { - String epcStr = Tools.Bytes2HexString(tag.getmEpcBytes(), tag.getmEpcBytes().length); -// String epcStr = new String(epc); - byte rssi = tag.getmRssi(); - addToList(listEPC, epcStr, rssi); - } - + String epcStr = tag == null ? "" : + Tools.Bytes2HexString(tag.getmEpcBytes(), tag.getmEpcBytes().length); + byte rssi = tag != null ? tag.getmRssi() : -1; + addToList(epcStr, rssi); } - } - tagList = null; - try { - Thread.sleep(20); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + // 防止频繁刷新 + try { Thread.sleep(20); } catch (InterruptedException e) { } } } } } } - long lastTime; - long nextTime; - // EPC add to LISTVIEW - private void addToList(final List list, final String epc, final byte rssi) { + + /** + * 处理扫描到的 EPC 标签 + * 优化:直接操作数据,更新 UI + */ + private void addToList(final String epc, final byte rssi) { runOnUiThread(new Runnable() { @Override public void run() { - // The epc for the first time - if (list.isEmpty()) { - EPC epcTag = new EPC(); - epcTag.setEpc(epc); - epcTag.setCount(1); - epcTag.setRssi(rssi); - list.add(epcTag); - listepc.add(epc); + // 1. 更新 EPC 显示 (直接设置到 Spinner 或 TextView) + // 假设 spinnerEPC 是用来显示 EPC 的 + // 这里可能需要一个只读的 Adapter 或者直接 setText (如果 spinnerEPC 改为了 TextView) + // 为了简化,假设我们有一个方法更新 EPC 显示 + //updateEpcDisplay(epc); + EPC.setText(epc); + // 2. 清理旧数据 (根据业务逻辑调整,通常不建议每次扫描都清空) + listepc.clear(); + listepc.add(epc); - }else { - for (int i = 0; i < list.size(); i++) { - EPC mEPC = list.get(i); - // list contain this epc - if (epc.equals(mEPC.getEpc())) { - mEPC.setCount(mEPC.getCount() + 1); - mEPC.setRssi(rssi); - list.set(i, mEPC); - break; - } else if (i == (list.size() - 1)) { - // list doesn't contain this epc - EPC newEPC = new EPC(); - newEPC.setEpc(epc); - newEPC.setCount(1); - newEPC.setRssi(rssi); - list.add(newEPC); - listepc.add(epc); - } - } + // 3. 自动查询后台数据 + if (!epc.isEmpty()) { + find(epc); + startFlag = false; // 扫描到一次后暂停,防止重复提交 } - - // play sound - lastTime = SystemClock.elapsedRealtime(); - long time = lastTime - nextTime; - if (time >= 60) { - Util.play(1, 0); - nextTime = lastTime; - Log.e("TAG", "run: " + time); - } - if (listepc != null && !listepc.isEmpty()){ - startFlag = false; - String currentEpc = listepc.get(0); - scan.setText(currentEpc); - - } - clearData(); } }); - Log.e("EPC", "listepc:+ " + listepc); -// if (listepc != null && !listepc.isEmpty()){ -// startFlag = false; -//// scan.setText("测试"); -// scan.setText(listepc.get(0).toString()); -// //请求后台 -// find(listepc.get(0).toString()); -// } -// clearData(); } - private void clearData() { - listEPC.removeAll(listEPC); - listepc.removeAll(listepc); + + private void updateEpcDisplay(String epc) { + // 这里根据你的实际布局调整 + // 如果 spinnerEPC 是 Spinner,你可能需要一个包含该 EPC 的 Adapter + // 或者在 XML 中保留一个隐藏的 EditText 用于传参 + // 简单处理:打印日志 + + Log.d("UHF", "Scanned EPC: " + epc); } - // 基本信息查询 + + // === 网络请求与数据填充 === private void find(String epc) { - OkGo.post(MyUrl.url + "/tyre/tyre/pdaQueryTyreInfo").tag(this) + showLoadingDialog(); + OkGo.post(MyUrl.url + "/tyre/tyre/pdaQueryTyreInfo") + .tag(this) .params("tyreEpc", epc) .execute(new StringCallback() { - @Override - public void onSuccess(Response response) { - String body = response.body(); - Log.e("body", body); - try { - Gson gson = new Gson(); - BaseTyre baseTyre = gson.fromJson(body, BaseTyre.class); - if (baseTyre != null) { - // 空值处理:若字段为 null 则显示空字符串 - String tyreNo = safeGetString(baseTyre.getTyreNo()); - wtbm.setText(tyreNo); - String brand = safeGetString(baseTyre.getTyreBrand()); - String model = safeGetString(baseTyre.getTyreModel()); - String level = safeGetString(baseTyre.getTyreLevel()); - String pattern = safeGetString(baseTyre.getTyrePattern()); - String kind = safeGetString(baseTyre.getTyreType()); - pinpai.setText(brand); - xinghao.setText(model); - cengji.setText(level); - huawen.setText(pattern); - tyrekind.setText(kind); + @Override + public void onSuccess(Response response) { + hideLoadingDialog(); + try { + Gson gson = new Gson(); + BaseTyre baseTyre = gson.fromJson(response.body(), BaseTyre.class); + if (baseTyre != null) { + // 填充表单数据 + // 注意:这里不再 setText 到被移除的 TextView + // 而是应该选中 Spinner 的对应项,或者填充 EditText + wtbm.setText(safeGetString(baseTyre.getTyreNo())); + // 逻辑优化:Spinner 应该通过 Adapter 选中 position + // 这里简化处理,直接记录值供提交使用 + selectedBrand = safeGetString(baseTyre.getTyreBrand()); + selectedModel = safeGetString(baseTyre.getTyreModel()); + selectedLevel = safeGetString(baseTyre.getTyreLevel()); + selectedPattern = safeGetString(baseTyre.getTyrePattern()); + selectedKind = safeGetString(baseTyre.getTyreType()); + + // 如果需要自动选中 Spinner,需要遍历 Adapter 寻找 position + // setSelectedSpinnerItem(spinnerBrand, selectedBrand); + }else { + wtbm.setText(""); + } + } catch (Exception e) { + e.printStackTrace(); + } } - } catch (JsonSyntaxException e) { - return; - } - } - }); + }); } private String safeGetString(String value) { + // 注意:原代码中有一行是 "null".equals(value),这是为了防止后台返回字符串 "null" return value == null || "null".equals(value) ? "" : value; } - //添加到库存表 - private void insert_inventory(String epc,String wtbm,String pinpai,String xinghao,String cengji,String huawen,String grooves,String tyrekind) { - OkGo.post(MyUrl.url + "/tyre/inventory/pdaAddInventory").tag(this) - .params("tyreRfid", epc) - .params("tyreEpc",epc) - .params("tyreOutsideId",wtbm) - .params("tyreBrand",pinpai) - .params("tyreModel",xinghao) - .params("tyreLevel",cengji) - .params("tyrePattern",huawen) - .params("grooves",grooves) - .params("tyreType",tyrekind) - .params("CreateBy",SharedPreferencesUtils.getstring("user","admin")).execute(new StringCallback() { - @Override - public void onSuccess(Response response) { - hideLoadingDialog(); - String body = response.body(); - Gson gson = new Gson(); - AjaxResult ajaxResult = gson.fromJson(body, AjaxResult.class); - handleResponse(ajaxResult); - } - @Override - public void onError(Response response) { - hideLoadingDialog(); - Toast.makeText(InStoreHouseActivity.this, "请求失败,请检查网络或重试", Toast.LENGTH_SHORT).show(); - } - }); - } - private void handleResponse(AjaxResult result) { - switch (result.getCode()) { - case "500": - new CommonDialog(this).setMessage(result.getMsg()).show(); - break; - case "0": - new CommonDialog(this).setMessage(result.getMsg()).show(); - break; - } - } + // === 提交逻辑 === @OnClick({R.id.button, R.id.back}) public void onViewClicked(View view) { switch (view.getId()) { case R.id.button: -// int len=wtbm.getText().toString().length(); -// if (len != 11){ -// new CommonDialog(InStoreHouseActivity.this).setMessage("胎号填写错误").show(); -// }else { -// Log.e("aaaaa",epc.substring(4)+wtbm.getText().toString()+tyrekind.getText().toString()); - String epc=scan.getText().toString(); - String w=wtbm.getText().toString(); -// String zb=zbh.getText().toString(); - String p = pinpai.getText().toString(); - String x=xinghao.getText().toString(); - String c=cengji.getText().toString(); - String h=huawen.getText().toString(); - String t=tyrekind.getText().toString(); - String g=gcts.getText().toString(); - if (scan.getText().toString()==""){ - new CommonDialog(InStoreHouseActivity.this).setMessage("请扫描轮胎芯片!").show(); - return; - } - showLoadingDialog(); - insert_inventory(epc,w,p,x,c,h,g,t); -// } + submitData(); break; case R.id.back: - Intent intent = new Intent(this, HomePageActivity.class); - startActivity(intent); + finish(); // 推荐使用 finish 返回 break; } - } + private void submitData() { + // 1. 获取当前显示的值 + // String epc = ((TextView) spinnerEPC.getChildAt(0)).getText().toString(); // 复杂 + // 简单方案:假设你有一个变量保存了最后扫描的 EPC + String currentEpc = getCurrentEpcFromUHF(); // 你需要实现这个逻辑或维护一个变量 + + if (currentEpc.isEmpty()) { + new CommonDialog(this).setMessage("请扫描轮胎芯片!").show(); + return; + } + + String wtbmStr = wtbm.getText().toString().trim(); + String depthStr = patternDepth.getText().toString().trim(); + + // 2. 获取下拉框选中的值 (核心修复) + // 由于去除了重影 TextView,直接从 Spinner 获取 + String brand = spinnerBrand.getSelectedItem() != null ? + spinnerBrand.getSelectedItem().toString() : selectedBrand; + + String model = spinnerSize.getSelectedItem() != null ? + spinnerSize.getSelectedItem().toString() : selectedModel; + + String level = spinnerlevel.getSelectedItem() != null ? + spinnerlevel.getSelectedItem().toString() : selectedLevel; + + String pattern = spinnerpattern.getSelectedItem() != null ? + spinnerpattern.getSelectedItem().toString() : selectedPattern; + + String kind = spinnerkind.getSelectedItem() != null ? + spinnerkind.getSelectedItem().toString() : selectedKind; + + String grooves = spinnergcts.getSelectedItem() != null ? + spinnergcts.getSelectedItem().toString() : selectedGcts; + + // 3. 参数校验 + if (wtbmStr=="" || wtbmStr == null || wtbmStr == "Scan fail") { + new CommonDialog(this).setMessage("胎号不能为空").show(); + return; + } + + showLoadingDialog(); + + // 4. 发送网络请求 + OkGo.post(MyUrl.url + "/tyre/inventory/pdaAddInventory") + .tag(this) + .params("tyreRfid", currentEpc) + .params("tyreEpc", currentEpc) + .params("tyreOutsideId", wtbmStr) + .params("tyreBrand", brand) + .params("tyreModel", model) + .params("tyreLevel", level) + .params("tyrePattern", pattern) + .params("grooves", grooves) + .params("tyreType", kind) + .params("patternDepth", depthStr) + .params("CreateBy", SharedPreferencesUtils.getstring("user", "admin")) + .execute(new StringCallback() { + @Override + public void onSuccess(Response response) { + hideLoadingDialog(); + handleResponse(response.body()); + } + + @Override + public void onError(Response response) { + hideLoadingDialog(); + Toast.makeText(InStoreHouseActivity.this, "请求失败,请检查网络", Toast.LENGTH_SHORT).show(); + } + }); + } + + private String getCurrentEpcFromUHF() { + // TODO: 实现获取当前扫描到的 EPC 的逻辑 + // 例如返回 listepc.get(0) 或者维护一个全局变量 currentEpc + return listepc.isEmpty() ? "" : listepc.get(0); + } + + private void handleResponse(String body) { + try { + AjaxResult result = new Gson().fromJson(body, AjaxResult.class); + new CommonDialog(this).setMessage(result.getMsg()).show(); + if ("200".equals(result.getCode())) { // 假设 200 是成功 + // 清空数据以便下一次扫描 + clearForm(); + } + } catch (Exception e) { + Toast.makeText(this, "数据解析错误", Toast.LENGTH_SHORT).show(); + } + } + + private void clearForm() { + wtbm.setText(""); + patternDepth.setText(""); + EPC.setText(""); + // spinnerEPC... 清空逻辑 + } + + // === 下拉框数据加载 (保持不变,但 Adapter 绑定逻辑需确认) === + private void check_spinner() { + showLoadingDialog(); + OkGo.post(MyUrl.url + "/system/dict/data/tyreTypeList") + .execute(new StringCallback() { + @Override + public void onSuccess(Response response) { + + try { + Gson gson = new Gson(); + InStoreSpinnerVo vo = gson.fromJson(response.body(), InStoreSpinnerVo.class); + + // 设置 Adapter (逻辑保持不变) + setAdapter(spinnerkind, vo.getKindList()); + setAdapter(spinnerpattern, vo.getPatternList()); + setAdapter(spinnerlevel, vo.getLevelList()); + setAdapter(spinnergcts, vo.getGctsList()); + setAdapter(spinnerBrand, vo.getTyreBrandList()); + + // 特殊处理:型号 (需要处理 Label/Value) + List sizeLabels = new ArrayList<>(); + if (vo.getTyreSizeList() != null) { + patternSize = vo.getTyreSizeList(); + for (TyreSizeVo size : patternSize) { + sizeLabels.add(size.getLabel()); + } + } + setAdapter(spinnerSize, sizeLabels); + hideLoadingDialog(); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + private void setAdapter(Spinner spinner, List data) { + if (data != null && !data.isEmpty()) { + ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, data); + spinner.setAdapter(adapter); + } + } + + // === Spinner 选择监听 (优化版) === @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { - switch (parent.getId()){ -// case R.id.spinner: -// czy.setText(parent.getItemAtPosition(position).toString()); -// break; - case R.id.spinnerkind: - tyrekind.setText(parent.getItemAtPosition(position).toString()); - break; - case R.id.spinnerpattern: - huawen.setText(parent.getItemAtPosition(position).toString()); - break; - case R.id.spinnerlevel: - cengji.setText(parent.getItemAtPosition(position).toString()); + // 仅保存选中的值,不再 setText 到任何 TextView (解决重影的根本原因) + String selectedItem = parent.getItemAtPosition(position).toString(); + + switch (parent.getId()) { + case R.id.spinnerBrand: + selectedBrand = selectedItem; break; case R.id.spinnerSize: - xinghao.setText(parent.getItemAtPosition(position).toString()); + selectedModel = selectedItem; + // 如果需要根据型号联动花纹深度 + if (patternSize != null && position < patternSize.size()) { + patternDepth.setText(patternSize.get(position).getValue()); + } break; - case R.id.spinnerBrand: - pinpai.setText(parent.getItemAtPosition(position).toString()); + case R.id.spinnerlevel: + selectedLevel = selectedItem; + break; + case R.id.spinnerpattern: + selectedPattern = selectedItem; + break; + case R.id.spinnerkind: + selectedKind = selectedItem; break; case R.id.spinnergcts: - gcts.setText(parent.getItemAtPosition(position).toString()); + selectedGcts = selectedItem; break; } } - private Toast mToast; - - private Toast toast; @Override public void onNothingSelected(AdapterView parent) { - + // 可选:设置默认值 } - private class KeyReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - int keyCode = intent.getIntExtra("keyCode", 0); - if (keyCode == 0) { - keyCode = intent.getIntExtra("keycode", 0); - } - boolean keyDown = intent.getBooleanExtra("keydown", false); - if (keyDown) { - if (toast == null) { - // toast = Toast.makeText(InStoreHouseActivity.this, "KeyReceiver:keyCode = down" + keyCode, Toast.LENGTH_SHORT); - } else { - // toast.setText("KeyReceiver:keyCode = down" + keyCode); - } - // toast.show(); - switch (keyCode) { - case KeyEvent.KEYCODE_F1: - case KeyEvent.KEYCODE_F2: - case KeyEvent.KEYCODE_F3: - case KeyEvent.KEYCODE_F4: - case KeyEvent.KEYCODE_F5: - //扫描 - startFlag = true; - break; - } - } - } - } - private void check_spinner() { - OkGo.post(MyUrl.url + "/system/dict/data/tyreTypeList").execute(new StringCallback() { - @Override - public void onSuccess(Response response) { - hideLoadingDialog(); - String body = response.body(); - Gson gson = new Gson(); - InStoreSpinnerVo inStoreSpinnerVo=new InStoreSpinnerVo(); - inStoreSpinnerVo = gson.fromJson(body,InStoreSpinnerVo.class); - List stringList=inStoreSpinnerVo.getKindList(); - List patternList=inStoreSpinnerVo.getPatternList(); - List patternLevel=inStoreSpinnerVo.getLevelList(); - List patternSize=inStoreSpinnerVo.getTyreSizeList(); - List patternBrand=inStoreSpinnerVo.getTyreBrandList(); - List patternGcts=inStoreSpinnerVo.getGctsList(); - ArrayAdapter arrayAdapter = new ArrayAdapter<>(InStoreHouseActivity.this, android.R.layout.simple_list_item_1, stringList); - ArrayAdapter arrayAdapterPattern = new ArrayAdapter<>(InStoreHouseActivity.this, android.R.layout.simple_list_item_1, patternList); - ArrayAdapter arrayAdapterLevel = new ArrayAdapter<>(InStoreHouseActivity.this, android.R.layout.simple_list_item_1, patternLevel); - ArrayAdapter arrayAdapterSize = new ArrayAdapter<>(InStoreHouseActivity.this, android.R.layout.simple_list_item_1, patternSize); - ArrayAdapter arrayAdapterBrand = new ArrayAdapter<>(InStoreHouseActivity.this, android.R.layout.simple_list_item_1, patternBrand); - ArrayAdapter arrayAdapterGcts = new ArrayAdapter<>(InStoreHouseActivity.this, android.R.layout.simple_list_item_1, patternGcts); - spinnerkind.setAdapter(arrayAdapter); - spinnerpattern.setAdapter(arrayAdapterPattern); - spinnerlevel.setAdapter(arrayAdapterLevel); - spinnerSize.setAdapter(arrayAdapterSize); - spinnerBrand.setAdapter(arrayAdapterBrand); - spinnergcts.setAdapter(arrayAdapterGcts); - } - }); - spinnerkind.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - tyrekind.setText(parent.getItemAtPosition(position).toString()); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - spinnerpattern.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - huawen.setText(parent.getItemAtPosition(position).toString()); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - spinnerlevel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - cengji.setText(parent.getItemAtPosition(position).toString()); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - spinnerSize.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - xinghao.setText(parent.getItemAtPosition(position).toString()); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - spinnerBrand.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - pinpai.setText(parent.getItemAtPosition(position).toString()); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - spinnergcts.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - gcts.setText(parent.getItemAtPosition(position).toString()); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); - } + // === 广播接收器 (保持不变) === private KeyReceiver keyReceiver; private void registerReceiver() { keyReceiver = new KeyReceiver(); @@ -547,7 +457,51 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi filter.addAction("android.intent.action.FUN_KEY"); registerReceiver(keyReceiver, filter); } + private void unregisterReceiver() { - unregisterReceiver(keyReceiver); + if (keyReceiver != null) { + unregisterReceiver(keyReceiver); + keyReceiver = null; + } } -} + + private class KeyReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + int keyCode = intent.getIntExtra("keyCode", 0); + if (keyCode == 0) keyCode = intent.getIntExtra("keycode", 0); + boolean keyDown = intent.getBooleanExtra("keydown", false); + + switch (keyCode) { + case KeyEvent.KEYCODE_F1: + case KeyEvent.KEYCODE_F2: + case KeyEvent.KEYCODE_F3: + case KeyEvent.KEYCODE_F4: + case KeyEvent.KEYCODE_F5: + //扫描 + startFlag = true; + break; + } + + } + } + private void showLoadingDialog() { + if (progressDialog == null) { + progressDialog = new ProgressDialog(this); + progressDialog.setMessage("数据加载中..."); + progressDialog.setCancelable(false); // 禁止用户通过返回键取消 + } + if (!progressDialog.isShowing()) { + progressDialog.show(); + } + } + + /** + * 隐藏加载对话框 + */ + private void hideLoadingDialog() { + if (progressDialog != null && progressDialog.isShowing()) { + progressDialog.dismiss(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/tyre/TyreLayoutActivity.java b/app/src/main/java/com/example/tyre/TyreLayoutActivity.java index 6c1877a..f1ceca8 100644 --- a/app/src/main/java/com/example/tyre/TyreLayoutActivity.java +++ b/app/src/main/java/com/example/tyre/TyreLayoutActivity.java @@ -162,30 +162,106 @@ public class TyreLayoutActivity extends AppCompatActivity { public void onSuccess(Response response) { hideLoadingDialog(); String body = response.body(); - Gson gson=new Gson(); - List baseCarList = gson.fromJson(body, new TypeToken>(){}.getType()); - Log.e("EPC", "listepc:+ " + baseCarList.size()); - if (baseCarList!=null && baseCarList.size()>0){ - List carNoList = new ArrayList<>(); - for (BaseCar car : baseCarList) { - carNoList.add(car.getCarNo()); + Log.d("CarQuery", "Response: " + body); + Gson gson = new Gson(); + + try { + // 1. 将响应体解析为 JsonObject (通用 JSON 对象) + // 这样可以绕过 AjaxResult 类对 data 字段的 String 类型限制 + com.google.gson.JsonObject jsonObject = gson.fromJson(body, com.google.gson.JsonObject.class); + + // 2. 获取 code 字段 (注意:你的日志显示 code 是数字 0,但 AjaxResult 定义是 String,这里做兼容处理) + String code = ""; + if (jsonObject.has("code")) { + // 尝试获取 code,无论是 "0" 还是 0 都能处理 + code = jsonObject.get("code").getAsString(); } - // 显示自定义弹窗 - showCarSelectionDialog(carNoList); + + // 3. 判断成功状态 (根据你的日志,0 代表成功) + if ("0".equals(code) || "200".equals(code)) { + + // 4. 获取 data 元素 + if (jsonObject.has("data")) { + com.google.gson.JsonElement dataElement = jsonObject.get("data"); + + // 5. 将 data 元素转换为 List + // 使用 TypeToken 指定泛型类型 + java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken>() {}.getType(); + List carList = gson.fromJson(dataElement, type); + + if (carList != null && !carList.isEmpty()) { + // 6. 展示弹窗列表 + showCarSelectionDialog(carList); + } else { + // 7. 无数据处理 + new CommonDialog(TyreLayoutActivity.this).setMessage("未查询到相关车辆信息").show(); + } + } + } else { + // 业务错误处理 + String msg = jsonObject.has("msg") ? jsonObject.get("msg").getAsString() : "未知错误"; + new CommonDialog(TyreLayoutActivity.this).setMessage(msg).show(); + } + + } catch (Exception e) { + e.printStackTrace(); + new CommonDialog(TyreLayoutActivity.this).setMessage("数据解析异常").show(); } } }); } - private void showCarSelectionDialog(List carNoList) { - CarSelectionDialog dialog = new CarSelectionDialog(this, carNoList); - dialog.setOnCarSelectedListener(new CarSelectionDialog.OnCarSelectedListener() { - @Override - public void onCarSelected(String carNo) { - // 处理选中的车辆 - etPlateNumber.setText(carNo); + + + /** + * 展示车辆选择弹窗 + * @param carList 车辆列表 + */ + private void showCarSelectionDialog(List carList) { + if (carList.size() == 1) { + // 如果只有一辆车,直接填充,无需弹窗 + BaseCar car = carList.get(0); + fillCarInfoToUI(car); + //Util.play(1, 0); // 提示音 + Toast.makeText(this, "自动匹配车辆:" + car.getCarNo(), Toast.LENGTH_SHORT).show(); + } else { + // 如果有多辆车,展示弹窗供用户选择 + // 提取车牌号列表用于显示 + List licensePlates = new ArrayList<>(); + for (BaseCar car : carList) { + licensePlates.add(car.getCarNo() != null ? car.getCarNo() : "未知车牌"); } - }); - dialog.show(); + + // 创建并显示弹窗 + CarSelectionDialog dialog = new CarSelectionDialog(this, licensePlates); + dialog.setOnCarSelectedListener((selectedItem) -> { + // selectedItem 是 Object,转成 String + String selectedPlate = selectedItem.toString().trim(); + + // 遍历列表找到对应的对象 + for (BaseCar car : carList) { + if (selectedPlate.equals(car.getCarNo())) { + fillCarInfoToUI(car); + break; + } + } + }); + dialog.show(); + } + } + + /** + * 将车辆信息填充到界面控件 + * @param car 车辆对象 + */ + private void fillCarInfoToUI(BaseCar car) { + // 填充车牌号 + etPlateNumber.setText(safeGetString(car.getCarNo())); + // 如果有其他字段,例如: + // startEdit.setText(safeGetString(car.getDefaultMileage())); // 默认里程 + + // 视觉反馈 + etPlateNumber.setTextColor(getColor(R.color.green500)); + // Util.play(1, 0); } @OnClick({R.id.btn_retrieve}) public void onViewClicked(View view) { diff --git a/app/src/main/java/com/example/tyre/UpActivity.java b/app/src/main/java/com/example/tyre/UpActivity.java index 8007222..18b800f 100644 --- a/app/src/main/java/com/example/tyre/UpActivity.java +++ b/app/src/main/java/com/example/tyre/UpActivity.java @@ -1,6 +1,5 @@ package com.example.tyre; - import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.Context; @@ -13,14 +12,8 @@ import android.os.SystemClock; import android.util.Log; import android.view.KeyEvent; import android.view.View; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Spinner; -import android.widget.TextView; -import android.widget.Toast; - +import android.widget.*; +import androidx.appcompat.app.AppCompatActivity; import com.android.hdhe.uhf.reader.UhfReader; import com.android.hdhe.uhf.readerInterface.TagModel; import com.example.tyre.entity.AjaxResult; @@ -28,12 +21,9 @@ import com.example.tyre.entity.BaseCar; import com.example.tyre.entity.BaseTyre; import com.example.tyre.entity.EPC; import com.example.tyre.entity.InStoreSpinnerVo; -import com.example.tyre.entity.Tyre; -import com.example.tyre.entity.UpTyre; import com.example.tyre.util.CarSelectionDialog; import com.example.tyre.util.CommonDialog; import com.example.tyre.util.MyUrl; -import com.example.tyre.util.PlayMusic; import com.example.tyre.util.SharedPreferencesUtils; import com.example.tyre.util.Util; import com.google.gson.Gson; @@ -42,132 +32,171 @@ import com.google.gson.reflect.TypeToken; import com.lzy.okgo.OkGo; import com.lzy.okgo.callback.StringCallback; import com.lzy.okgo.model.Response; - +import com.lzy.okgo.request.base.Request; import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.List; - -import androidx.appcompat.app.AppCompatActivity; -import butterknife.BindView; -import butterknife.ButterKnife; -import butterknife.OnClick; +import java.util.*; import cn.pda.serialport.Tools; -public class UpActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener{ +public class UpActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener { + // UI Components - 对应新 XML 的 ID + private TextView epcText, thText; // EPC 和 胎号 + private EditText zbhEdit, carEdit, startEdit; // 自编号、车牌、里程 + private Spinner conditionSpinner; // 轮位选择 + private Button searchBtn, confirmBtn, cancelBtn; // 搜索、确认、取消 - @BindView(R.id.epc) - TextView EPC; - @BindView(R.id.azlw) - TextView azlw; - @BindView(R.id.condition) - Spinner condition; -// @BindView(R.id.carAdapter) -// Spinner carAdapter; - @BindView(R.id.start) - EditText start; - @BindView(R.id.searchButton) - Button searchButton; - @BindView(R.id.ok) - Button ok; - @BindView(R.id.back) - Button back; - @BindView(R.id.th) - TextView th; - @BindView(R.id.zbh) - TextView zbh; - @BindView(R.id.car) - EditText car; - private boolean isStart = true; - private ProgressDialog progressDialog; + // RFID Manager + private UhfReader manager; private boolean runFlag = true; private boolean startFlag = false; - private UhfReader manager; // UHF manager,UHF Operating handle + + // Data Lists private ArrayList listEPC; - private ArrayList listepc = new ArrayList(); - long lastTime; - long nextTime; - private Toast mToast; - private Toast toast; - private KeyReceiver keyReceiver; + private ArrayList listepcStr; + + // Loading Dialog + private ProgressDialog progressDialog; + + // Debounce Handler for RFID Scan + private static final long DEBOUNCE_DELAY = 500; + private String lastScannedEpc; + private Handler debounceHandler = new Handler(new Handler.Callback() { + @Override + public boolean handleMessage(Message msg) { + if (msg.what == 1 && lastScannedEpc != null) { + // 延迟结束,执行查询逻辑 + showLoadingDialog(); + if (isInRange(lastScannedEpc, min, max)) { + findCar(lastScannedEpc); // 车辆芯片 + } else { + find(lastScannedEpc); // 轮胎芯片 + } + lastScannedEpc = null; + } + return true; + } + }); + + // EPC Range Check (示例范围,请根据实际业务修改) String min = "EC0001012026010100000001"; // 左边界(包含) String max = "EC0001012026010100100000"; // 右边界(包含) + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_up); - ButterKnife.bind(this); - manager = MyApplication.getManager(); - listEPC = new ArrayList(); - condition.setOnItemSelectedListener(this); + setContentView(R.layout.activity_up); // 确保使用新布局 - showLoadingDialog(); - check_spinner(); - //car_spinner(); + // 初始化视图 + initViews(); + + // 初始化硬件 + manager = UhfReader.getInstance(); // 假设单例模式,根据实际情况调整 + if (manager == null) { + Toast.makeText(this, "UHF Reader Init Failed", Toast.LENGTH_SHORT).show(); + finish(); + return; + } + + listEPC = new ArrayList<>(); + listepcStr = new ArrayList<>(); + + // 设置 Spinner 监听 + conditionSpinner.setOnItemSelectedListener(this); + + // 启动扫描线程 Thread thread = new InventoryThread(); thread.start(); + + // 初始化工具类 Util.initSoundPool(this); + + // 加载轮位数据 + check_spinner(); + + // 默认显示加载框(如果需要预加载数据) + // showLoadingDialog(); } + private void initViews() { + // 绑定新布局中的控件 + epcText = findViewById(R.id.epc); + thText = findViewById(R.id.th); + zbhEdit = findViewById(R.id.zbh); + carEdit = findViewById(R.id.car); + startEdit = findViewById(R.id.start); + conditionSpinner = findViewById(R.id.condition); + searchBtn = findViewById(R.id.searchButton); + confirmBtn = findViewById(R.id.confirmButton); + cancelBtn = findViewById(R.id.back); + // 设置按钮点击事件 + searchBtn.setOnClickListener(v -> { + String carNo = carEdit.getText().toString().trim(); + if (carNo.isEmpty()) { + new CommonDialog(UpActivity.this).setMessage("请输入车牌号或扫描车辆芯片!").show(); + return; + } + showLoadingDialog(); + car_spinner(carNo); + }); - @Override - public void onResume() { - super.onResume(); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - registerReceiver(); - } - - - @Override - public void onPause() { - startFlag = false; - super.onPause(); - unregisterReceiver(); - } - @Override - protected void onDestroy() { - startFlag = false; - runFlag = false; - super.onDestroy(); + confirmBtn.setOnClickListener(v -> { + String rfid = epcText.getText().toString(); + String carNo = carEdit.getText().toString(); + String mileage = startEdit.getText().toString(); + String wheel = conditionSpinner.getSelectedItem().toString(); + String selfNo = zbhEdit.getText().toString(); + + // 校验逻辑 + if (rfid.isEmpty() || "请扫描或输入EPC".equals(rfid)) { + new CommonDialog(UpActivity.this).setMessage("请扫描轮胎!").show(); + return; + } + if (carNo.isEmpty()) { + new CommonDialog(UpActivity.this).setMessage("请选择安装车辆!").show(); + return; + } + if (mileage.isEmpty()) { + new CommonDialog(UpActivity.this).setMessage("请输入起始里程!").show(); + return; + } + if (wheel.isEmpty()) { + new CommonDialog(UpActivity.this).setMessage("请选择安装轮位!").show(); + return; + } + + // 提交数据 + up_insert(rfid, carNo, mileage, wheel, selfNo); + showLoadingDialog(); + }); + + cancelBtn.setOnClickListener(v -> finish()); } + // ---------------- RFID 扫描线程 ---------------- class InventoryThread extends Thread { - private List tagList; - byte[] accessPassword = Tools.HexString2Bytes("00000000"); @Override public void run() { - super.run(); while (runFlag) { if (startFlag) { - tagList = manager.inventoryRealTime(); //实时盘存 + List tagList = manager.inventoryRealTime(); if (tagList != null && !tagList.isEmpty()) { - //播放提示音 - Util.play(1, 0); + Util.play(1, 0); // 播放提示音 for (TagModel tag : tagList) { + String epcStr; if (tag == null) { - String epcStr = ""; -// String epcStr = new String(epc); - addToList(listEPC, epcStr, (byte) -1); + epcStr = ""; } else { - String epcStr = Tools.Bytes2HexString(tag.getmEpcBytes(), tag.getmEpcBytes().length); -// String epcStr = new String(epc); - byte rssi = tag.getmRssi(); - addToList(listEPC, epcStr, rssi); + epcStr = Tools.Bytes2HexString(tag.getmEpcBytes(), tag.getmEpcBytes().length); } - + addToList(listEPC, epcStr, (byte) 0); } + tagList.clear(); } - tagList = null; try { Thread.sleep(20); } catch (InterruptedException e) { - // TODO Auto-generated catch block e.printStackTrace(); } } @@ -175,404 +204,576 @@ public class UpActivity extends AppCompatActivity implements AdapterView.OnItemS } } - // EPC add to LISTVIEW private void addToList(final List list, final String epc, final byte rssi) { - runOnUiThread(new Runnable() { - @Override - public void run() { - // The epc for the first time - if (list.isEmpty()) { - EPC epcTag = new EPC(); - epcTag.setEpc(epc); - epcTag.setCount(1); - epcTag.setRssi(rssi); - list.add(epcTag); - listepc.add(epc); + runOnUiThread(() -> { + if (list.isEmpty()) { + EPC epcTag = new EPC(); + epcTag.setEpc(epc); + epcTag.setCount(1); + list.add(epcTag); + listepcStr.add(epc); + } else { + boolean found = false; + for (EPC mEPC : list) { + if (epc.equals(mEPC.getEpc())) { + mEPC.setCount(mEPC.getCount() + 1); + found = true; + break; + } + } + if (!found) { + EPC newEPC = new EPC(); + newEPC.setEpc(epc); + newEPC.setCount(1); + list.add(newEPC); + listepcStr.add(epc); + } + } - }else { - for (int i = 0; i < list.size(); i++) { - EPC mEPC = list.get(i); - // list contain this epc - if (epc.equals(mEPC.getEpc())) { - mEPC.setCount(mEPC.getCount() + 1); - mEPC.setRssi(rssi); - list.set(i, mEPC); - break; - } else if (i == (list.size() - 1)) { - // list doesn't contain this epc - EPC newEPC = new EPC(); - newEPC.setEpc(epc); - newEPC.setCount(1); - newEPC.setRssi(rssi); - list.add(newEPC); - listepc.add(epc); + // 防抖逻辑 + if (!listepcStr.isEmpty()) { + startFlag = false; + String currentEpc = listepcStr.get(0); + debounceHandler.removeMessages(1); + lastScannedEpc = currentEpc; + debounceHandler.sendEmptyMessageDelayed(1, DEBOUNCE_DELAY); + } + clearData(); + }); + } + + private void clearData() { + // listEPC.clear(); // 根据实际逻辑决定是否清空,注释掉以便保留显示 + listepcStr.clear(); + } + + // ---------------- 网络请求与业务逻辑 ---------------- + private void up_insert(String rfid, String carNo, String mileage, String wheel, String selfNo) { + OkGo.post(MyUrl.url + "/tyre/install/PdaInstallTyre") + .tag(this) + .params("tyreRfid", rfid) + .params("mileage", mileage) + .params("carNo", carNo) + .params("wheelPostion", wheel) + .params("selfNo", selfNo) + .params("CreateBy", SharedPreferencesUtils.getstring("user", "admin")) + .execute(new StringCallback() { + @Override + public void onSuccess(Response response) { + hideLoadingDialog(); + Gson gson = new Gson(); + try { + AjaxResult result = gson.fromJson(response.body(), AjaxResult.class); + handleResponse(result); + } catch (JsonSyntaxException e) { + Toast.makeText(UpActivity.this, "数据解析错误", Toast.LENGTH_SHORT).show(); } } - } - // play sound - lastTime = SystemClock.elapsedRealtime(); - long time = lastTime - nextTime; - if (time >= 60) { - Util.play(1, 0); - nextTime = lastTime; - Log.e("TAG", "run: " + time); - } - if (listepc != null && !listepc.isEmpty()){ - startFlag = false; - String currentEpc = listepc.get(0); - if (isInRange(currentEpc, min, max)) { - //请求后台 查询车辆信息 - // car.setText(currentEpc); - //请求后台 - }else { - EPC.setText(currentEpc); - //请求后台 - debounceHandler.removeMessages(1); + @Override + public void onError(Response response) { + super.onError(response); + hideLoadingDialog(); + Toast.makeText(UpActivity.this, "网络请求失败", Toast.LENGTH_SHORT).show(); } - debounceHandler.removeMessages(1); - lastScannedEpc = currentEpc; - debounceHandler.sendEmptyMessageDelayed(1, DEBOUNCE_DELAY); - } + }); + } - clearData(); + /** + * 根据车牌号查询车辆信息 + * 对应之前的 car_spinner 逻辑 + * @param carNo 车牌号 + */ + private void car_spinner(String carNo) { + // 1. 参数校验 + if (carNo == null || carNo.trim().isEmpty()) { + hideLoadingDialog(); + new CommonDialog(UpActivity.this).setMessage("车牌号不能为空!").show(); + return; + } + + // 2. 发起网络请求 + // 接口说明:通常调用车辆查询接口,传入车牌号 + OkGo.post(MyUrl.url + "/tyre/car/PdaQueryCarList") // 注意:这是根据车牌查询的接口,区别于之前的 RFID 查询 + .tag(this) + .params("carNo", carNo) // 传递车牌号参数 + .execute(new StringCallback() { + @Override + public void onSuccess(Response response) { + hideLoadingDialog(); + String body = response.body(); + Log.d("CarQuery", "Response: " + body); + Gson gson = new Gson(); + + try { + // 1. 将响应体解析为 JsonObject (通用 JSON 对象) + // 这样可以绕过 AjaxResult 类对 data 字段的 String 类型限制 + com.google.gson.JsonObject jsonObject = gson.fromJson(body, com.google.gson.JsonObject.class); + + // 2. 获取 code 字段 (注意:你的日志显示 code 是数字 0,但 AjaxResult 定义是 String,这里做兼容处理) + String code = ""; + if (jsonObject.has("code")) { + // 尝试获取 code,无论是 "0" 还是 0 都能处理 + code = jsonObject.get("code").getAsString(); + } + + // 3. 判断成功状态 (根据你的日志,0 代表成功) + if ("0".equals(code) || "200".equals(code)) { + + // 4. 获取 data 元素 + if (jsonObject.has("data")) { + com.google.gson.JsonElement dataElement = jsonObject.get("data"); + + // 5. 将 data 元素转换为 List + // 使用 TypeToken 指定泛型类型 + java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken>() {}.getType(); + List carList = gson.fromJson(dataElement, type); + + if (carList != null && !carList.isEmpty()) { + // 6. 展示弹窗列表 + showCarSelectionDialog(carList); + } else { + // 7. 无数据处理 + new CommonDialog(UpActivity.this).setMessage("未查询到相关车辆信息").show(); + } + } + } else { + // 业务错误处理 + String msg = jsonObject.has("msg") ? jsonObject.get("msg").getAsString() : "未知错误"; + new CommonDialog(UpActivity.this).setMessage(msg).show(); + } + + } catch (Exception e) { + e.printStackTrace(); + new CommonDialog(UpActivity.this).setMessage("数据解析异常").show(); + } + } + + @Override + public void onError(Response response) { + super.onError(response); + hideLoadingDialog(); + handleCarQueryError("response.getMessage()"); + } + }); + } + + /** + * 展示车辆选择弹窗 + * @param carList 车辆列表 + */ + private void showCarSelectionDialog(List carList) { + if (carList.size() == 1) { + // 如果只有一辆车,直接填充,无需弹窗 + BaseCar car = carList.get(0); + fillCarInfoToUI(car); + //Util.play(1, 0); // 提示音 + Toast.makeText(this, "自动匹配车辆:" + car.getCarNo(), Toast.LENGTH_SHORT).show(); + } else { + // 如果有多辆车,展示弹窗供用户选择 + // 提取车牌号列表用于显示 + List licensePlates = new ArrayList<>(); + for (BaseCar car : carList) { + licensePlates.add(car.getCarNo() != null ? car.getCarNo() : "未知车牌"); } - }); - Log.e("EPC", "listepc:+ " + listepc); + + // 创建并显示弹窗 + CarSelectionDialog dialog = new CarSelectionDialog(this, licensePlates); + dialog.setOnCarSelectedListener((selectedItem) -> { + // selectedItem 是 Object,转成 String + String selectedPlate = selectedItem.toString().trim(); + + // 遍历列表找到对应的对象 + for (BaseCar car : carList) { + if (selectedPlate.equals(car.getCarNo())) { + fillCarInfoToUI(car); + break; + } + } + }); + dialog.show(); + } + } + + /** + * 将车辆信息填充到界面控件 + * @param car 车辆对象 + */ + private void fillCarInfoToUI(BaseCar car) { + // 填充车牌号 + carEdit.setText(safeGetString(car.getCarNo())); + // 如果有其他字段,例如: + // startEdit.setText(safeGetString(car.getDefaultMileage())); // 默认里程 + + // 视觉反馈 + carEdit.setTextColor(getColor(R.color.green500)); + // Util.play(1, 0); } /** - * 判断字符串是否在指定的区间内(包含边界) - * @param target 要判断的目标字符串 - * @param min 区间左边界 - * @param max 区间右边界 - * @return true=在区间内,false=不在 + * 统一处理车辆查询错误(复用之前的逻辑) */ - public static boolean isInRange(String target, String min, String max) { - // 空值校验,避免空指针异常 - if (target == null || min == null || max == null) { - return false; - } - // compareTo规则: - // 1. 字符串相等返回0; - // 2. 目标字符串 > 对比字符串 返回正数; - // 3. 目标字符串 < 对比字符串 返回负数。 - // 因此:target >= min 等价于 target.compareTo(min) >= 0; - // target <= max 等价于 target.compareTo(max) <= 0。 - return target.compareTo(min) >= 0 && target.compareTo(max) <= 0; + private void handleCarQueryError(String errorMsg) { + new CommonDialog(UpActivity.this).setMessage(errorMsg).show(); } - // 防抖延迟时间 (毫秒) - private static final long DEBOUNCE_DELAY = 500; - // 用于存储最后一次扫描到的 EPC - private String lastScannedEpc; - // 用于处理防抖逻辑的 Handler - private Handler debounceHandler = new Handler(new Handler.Callback() { - @Override - public boolean handleMessage(Message msg) { - if (msg.what == 1 && lastScannedEpc != null) { - // 延迟时间到,执行查询 - showLoadingDialog(); - if (isInRange(lastScannedEpc, min, max)){ - //查询车辆数据方法 - findCar(lastScannedEpc); - }else { - find(lastScannedEpc); - } - lastScannedEpc = null; // 清空,等待下一次扫描 + /** + * 扫描到轮胎芯片后的处理逻辑 + * @param tyreRfid 扫描到的轮胎 EPC 码 + */ + private void find(String tyreRfid) { + // 1. 前置条件校验:必须先选择轮位才能扫描轮胎 + // 这里的逻辑是:防止用户先扫轮胎后扫车,或者忘记选轮位 + // String selectedWheelPosition = conditionSpinner.getSelectedItem().toString(); +// if (selectedWheelPosition == null || selectedWheelPosition.isEmpty() || +// "请选择轮位".equals(selectedWheelPosition) || // 假设 Spinner 默认提示 +// "未获取到轮位数据".equals(selectedWheelPosition)) { +// +// hideLoadingDialog(); // 确保加载框关闭 +// +// new CommonDialog(this) +// .setTitle("操作提示") +// .setMessage("请先在上方选择【安装轮位】,再扫描轮胎芯片!") +// .setConfirm("我知道了", null) +// .show(); +// +// return; +// } + + // 2. UI 更新:显示扫描到的轮胎 EPC + // 将 EPC 码显示在界面上,给用户视觉反馈 + epcText.setText(tyreRfid); + // 3. 网络请求:查询轮胎详情 + // 调用后台接口,根据 EPC 查询轮胎档案 + OkGo.post(MyUrl.url + "/tyre/tyre/pdaQueryTyreInfo") + .tag(this) + .params("tyreEpc", tyreRfid) + .execute(new StringCallback() { + @Override + public void onSuccess(Response response) { + hideLoadingDialog(); + Gson gson = new Gson(); + String body = response.body(); + try { + // 4. 解析数据 + // 假设后端返回标准 AjaxResult,data 字段包含 BaseTyre 对象 + + // 解析轮胎对象 + BaseTyre tyre = gson.fromJson(body, BaseTyre.class); + + // 5. 数据回填 (UI 更新) + // 将查询到的轮胎信息填充到界面控件 + thText.setText(safeGetString(tyre.getTyreNo())); // 胎号 + zbhEdit.setText(safeGetString(tyre.getSelfNo())); // 自编号/工厂码 + // 视觉反馈:高亮显示,提示成功 + epcText.setTextColor(getColor(R.color.green500)); + Util.play(1, 0); // 播放成功提示音 + Toast.makeText(UpActivity.this, "轮胎识别成功", Toast.LENGTH_SHORT).show(); + + } catch (Exception e) { + e.printStackTrace(); + handleTyreError("数据解析异常"); + } + } + + @Override + public void onError(Response response) { + super.onError(response); + hideLoadingDialog(); + handleTyreError("网络请求失败: "); + // handleTyreError("网络请求失败: " + response.getMessage()); + } + }); + } + + /** + * 统一处理轮胎查询错误 + * 作用:清空无效数据,防止误操作 + */ + private void handleTyreError(String errorMsg) { + // 1. 清空轮胎相关显示 + // thText.setText("未知轮胎"); + // zbhEdit.setText(""); + epcText.setTextColor(getColor(R.color.colorAccent)); + new CommonDialog(UpActivity.this).setMessage("轮胎识别错误!").show(); + + } + /** + * 根据车辆RFID查询车辆基本信息 + * @param carRfid 扫描到的车辆EPC码 + */ + private void findCar(String carRfid) { + // 1. 构建请求 + OkGo.post(MyUrl.url + "/tyre/car/queryCarByRfid") + .tag(this) + .params("rfid", carRfid) // 发送RFID查询 + .execute(new StringCallback() { + @Override + public void onSuccess(Response response) { + hideLoadingDialog(); // 隐藏加载框 + String body = response.body(); + Gson gson = new Gson(); + try { + // 2. 解析响应 + // 假设后端返回的是标准的 AjaxResult 包装类,或者直接是 BaseCar JSON + // 这里为了健壮性,先尝试解析 BaseCar + BaseCar baseCar = gson.fromJson(body, BaseCar.class); + if (baseCar != null && baseCar.getCarNo() != null) { + // 3. UI 更新 - 数据回填 + // 填充车牌号 + carEdit.setText(safeGetString(baseCar.getCarNo())); + // 如果有其他字段,继续填充 + // start.setText(safeGetString(baseCar.getDefaultMileage())); // 默认里程 + + // 视觉反馈:高亮车牌号,提示用户车辆已识别 + carEdit.setTextColor(getColor(R.color.green500)); // 假设 colors.xml 中有定义 + Toast.makeText(UpActivity.this, "车辆识别成功: " + baseCar.getCarNo(), Toast.LENGTH_SHORT).show(); + + // 清空轮胎显示区,准备扫描轮胎 +// epcText.setText("车辆已识别,请扫描轮胎"); +// thText.setText(""); +// zbhEdit.setText(""); + + } else { + // 4. 数据不存在处理 + handleCarQueryError("系统无此车辆绑定信息,请检查芯片是否损坏或未绑定!"); + } + } catch (JsonSyntaxException e) { + e.printStackTrace(); + handleCarQueryError("数据解析异常,请重试"); + } + } + + @Override + public void onError(Response response) { + super.onError(response); + hideLoadingDialog(); + // handleCarQueryError("网络请求失败" + response.getMessage()); + handleCarQueryError("请求失败"); + } + }); + } + + /** + * 统一处理车辆查询错误 + * 作用:锁定流程,必须正确识别车辆才能继续 + */ + + private String safeGetString(String value) { + return value == null || "null".equals(value) ? "" : value; + } + + private void handleResponse(AjaxResult result) { + runOnUiThread(() -> { + CommonDialog dialog = new CommonDialog(this); + if ("200".equals(result.getCode()) || "0".equals(result.getCode())) { + dialog.setMessage(result.getMsg()).show(); + } else { + dialog.setMessage(result.getMsg()).show(); } - return true; + }); + } + + // 重置表单 + private void resetForm() { + epcText.setText(""); + thText.setText("请扫描或输入EPC"); + zbhEdit.setText(""); + startEdit.setText(""); + // 车牌号不清空,方便连续装车 + // carEdit.setText(""); + } + + // ---------------- Spinner 数据加载 ---------------- + /** + * 加载轮位下拉框数据 + * 对应接口:/system/dict/data/wheelPositionList + * 对应实体:InStoreSpinnerVo (根据你上传的代码推断) + */ + private void check_spinner() { + // 1. 显示加载状态(如果需要,可选) + showLoadingDialog(); + OkGo.post(MyUrl.url + "/system/dict/data/wheelPositionList") + .tag(this) + .execute(new StringCallback() { + @Override + public void onSuccess(Response response) { + hideLoadingDialog(); + String body = response.body(); + Log.d("WheelPosition", "Raw Response: " + body); + + Gson gson = new Gson(); + try { + // 2. 解析数据 + // 根据你上传的代码,使用了 InStoreSpinnerVo + // 假设接口返回的是 List 或者 包含 data 字段的 AjaxResult + // 这里提供两种常见场景的解析逻辑: + + // --- 场景 A:接口直接返回 List 或 List --- + // 如果是直接列表,使用 TypeToken 解析 +// List tempList = gson.fromJson(body, +// new TypeToken>(){}.getType()); +// + List wheelList = gson.fromJson(body, + new TypeToken>(){}.getType()); +// if (tempList != null && !tempList.isEmpty()) { +// for (InStoreSpinnerVo vo : tempList) { +// // 假设 InStoreSpinnerVo 有 getDictLabel() 或类似方法 +// // 如果是直接 String 列表,直接 add vo 即可 +// wheelList.add(vo.getDictLabel()); +// } +// } + + // --- 场景 B:接口返回 AjaxResult 包装类 (如果场景 A 报错,请尝试此逻辑) --- +// AjaxResult result = gson.fromJson(body, AjaxResult.class); +// if (result.getCode().equals("200")) { +// tempList = gson.fromJson(gson.toJson(result.getData()), +// new TypeToken>(){}.getType()); +// // ... 后续填充逻辑同上 +// } + + // 3. 绑定适配器 + if (wheelList.isEmpty()) { + wheelList.add("未获取到轮位数据"); + } + + // 创建适配器 (Simple Spinner Item 样式) + ArrayAdapter adapter = new ArrayAdapter<>(UpActivity.this, + android.R.layout.simple_spinner_item, wheelList); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + + // 绑定到 Spinner + conditionSpinner.setAdapter(adapter); + + } catch (JsonSyntaxException e) { + e.printStackTrace(); + showErrorDialog("轮位数据解析失败"); + } + } + + @Override + public void onError(Response response) { + super.onError(response); + hideLoadingDialog(); + showErrorDialog("轮位数据加载失败"); + //showErrorDialog("轮位数据加载失败: " + response.getMessage()); + } + }); + } + + // 通用错误处理 + private void showErrorDialog(String msg) { + new CommonDialog(UpActivity.this).setMessage(msg).show(); + } + + // ---------------- 生命周期与广播 ---------------- + @Override + protected void onResume() { + super.onResume(); + registerReceiver(); + startFlag = false; // 开启扫描 + } + + @Override + protected void onPause() { + super.onPause(); + startFlag = false; // 关闭扫描 + unregisterReceiver(); + } + + @Override + protected void onDestroy() { + runFlag = false; + super.onDestroy(); + } + + private void registerReceiver() { + IntentFilter filter = new IntentFilter(); + filter.addAction("android.rfid.FUN_KEY"); + filter.addAction("android.intent.action.FUN_KEY"); + registerReceiver(keyReceiver, filter); + } + + private void unregisterReceiver() { + try { + unregisterReceiver(keyReceiver); + } catch (Exception e) { + e.printStackTrace(); } - }); - private void clearData() { - listEPC.removeAll(listEPC); - listepc.removeAll(listepc); } + + private BroadcastReceiver keyReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if ("android.rfid.FUN_KEY".equals(intent.getAction()) || "android.intent.action.FUN_KEY".equals(intent.getAction())) { + int keyCode = intent.getIntExtra("keyCode", 0); + boolean keyDown = intent.getBooleanExtra("keydown", false); + Log.d("keyCode", "Response: " + keyCode); + if (keyDown) { + switch (keyCode) { + case KeyEvent.KEYCODE_F5: + startFlag = true; + break; + } + } + } + } + }; + + + private void showLoadingDialog() { - progressDialog = new ProgressDialog(this); - progressDialog.setMessage("数据加载中..."); - progressDialog.setCancelable(false); - progressDialog.show(); + if (progressDialog == null) { + progressDialog = new ProgressDialog(this); + progressDialog.setMessage("数据加载中..."); + progressDialog.setCancelable(false); + } + if (!progressDialog.isShowing()) { + progressDialog.show(); + } } + private void hideLoadingDialog() { if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); } } + // Spinner 选中事件 (用于显示选中的轮位) @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { - switch (parent.getId()){ - case R.id.condition: - azlw.setText(parent.getItemAtPosition(position).toString()); - break; + if (parent.getId() == R.id.condition) { + // 在实际应用中,这里可能需要更新一个隐藏的变量存储轮位ID + // ((TextView) findViewById(R.id.azlw)).setText(parent.getItemAtPosition(position).toString()); } - } - // 添加缺失的方法 + @Override public void onNothingSelected(AdapterView parent) { - // 当没有选项被选中时的处理逻辑 - // 可以留空,但必须实现这个方法 + // Do nothing } - @OnClick({R.id.ok, R.id.back,R.id.searchButton}) - public void onViewClicked(View view) { - - String rfid=EPC.getText().toString(); - String carNo = car.getText().toString(); - String millage = start.getText().toString(); - String wheel = azlw.getText().toString(); - String selfNo = zbh.getText().toString(); - switch (view.getId()) { - case R.id.ok: - -// String azlw = - if (rfid == null || rfid.isEmpty()) - { - new CommonDialog(UpActivity.this).setMessage("请扫描轮胎!").show(); - return; - } - if (carNo == null || carNo.isEmpty()) - { - new CommonDialog(UpActivity.this).setMessage("请选择安装车辆!").show(); - return; - } - if (millage == null || millage.isEmpty()) - { - new CommonDialog(UpActivity.this).setMessage("请输入起始里程!").show(); - return; - } - if (wheel == null || wheel.isEmpty()) - { - new CommonDialog(UpActivity.this).setMessage("请选择安装轮位!").show(); - return; - } - if (selfNo == null || selfNo.isEmpty()) - { - new CommonDialog(UpActivity.this).setMessage("请输入自编号!").show(); - return; - } - up_insert(rfid,carNo,millage,wheel,selfNo); - showLoadingDialog(); - break; - case R.id.back: - Intent intent = new Intent(this, HomePageActivity.class); - startActivity(intent); - break; - case R.id.searchButton: - if (carNo == null || carNo.isEmpty()) - { - new CommonDialog(UpActivity.this).setMessage("请输入车牌号!").show(); - return; - } - showLoadingDialog(); - car_spinner(carNo); - break; + /** + * 判断 EPC 是否在指定的车辆范围内 (十六进制字符串比较) + * 注意:此方法针对的是完整的 EPC 码字符串比较,而非简单的前缀匹配 + * + * @param epc 扫描到的 EPC 码 + * @param min 车辆范围最小值 (包含) + * @param max 车辆范围最大值 (包含) + * @return true: 是车辆, false: 是轮胎 + */ + private boolean isInRange(String epc, String min, String max) { + if (epc == null || min == null || max == null) { + return false; } - } - // 安装请求后台 - private void up_insert(String rfid,String carNo,String millage,String wheel,String selfNo) { - OkGo.post(MyUrl.url + "/tyre/install/PdaInstallTyre").tag(this) - .params("tyreRfid", rfid) - .params("mileage", millage) - .params("carNo", carNo) - .params("wheelPostion", wheel) - .params("selfNo", selfNo) - .params("CreateBy", SharedPreferencesUtils.getstring("user","admin")) - .execute(new StringCallback() { - @Override - public void onSuccess(Response response) { - hideLoadingDialog(); - String body = response.body(); - Gson gson = new Gson(); - AjaxResult ajaxResult = gson.fromJson(body, AjaxResult.class); - handleResponse(ajaxResult); -// try { -// Gson gson = new Gson(); -// BaseTyre baseTyre = gson.fromJson(body, BaseTyre.class); -// if (baseTyre != null) { -// // 空值处理:若字段为 null 则显示空字符串 -// String TyreNo = safeGetString(baseTyre.getTyreNo()); -// th.setText(TyreNo); -// } -// } catch (JsonSyntaxException e) { -// return; -// } - } - }); - } - private void handleResponse(AjaxResult result) { - switch (result.getCode()) { - case "500": - new CommonDialog(this).setMessage(result.getMsg()).show(); - break; - case "0": - new CommonDialog(this).setMessage(result.getMsg()).show(); - break; - } - } - // 基本信息查询 - private void findCar(String carNumber) { - OkGo.post(MyUrl.url + "/tyre/car/queryCarByRfid").tag(this).params("rfid", carNumber).execute(new StringCallback() { - @Override - public void onSuccess(Response response) { - String body = response.body(); - hideLoadingDialog(); - try { - Gson gson = new Gson(); - BaseCar baseCar = gson.fromJson(body, BaseCar.class); - if (baseCar != null) { - // 空值处理:若字段为 null 则显示空字符串 - String carNo = safeGetString(baseCar.getCarNo()); - car.setText(carNo); - }else { - new CommonDialog(UpActivity.this).setMessage("请检查车辆芯片绑定数据!").show(); - } - } catch (JsonSyntaxException e) { - return; - } - } - }); - } - // 基本信息查询 - private void find(String epc) { - OkGo.post(MyUrl.url + "/tyre/tyre/pdaQueryTyreInfo").tag(this).params("tyreEpc", epc).execute(new StringCallback() { - @Override - public void onSuccess(Response response) { - String body = response.body(); - hideLoadingDialog(); - try { - Gson gson = new Gson(); - BaseTyre baseTyre = gson.fromJson(body, BaseTyre.class); - if (baseTyre != null) { - // 空值处理:若字段为 null 则显示空字符串 - String TyreNo = safeGetString(baseTyre.getTyreNo()); - th.setText(TyreNo); - zbh.setText(baseTyre.getSelfNo()); - }else { - new CommonDialog(UpActivity.this).setMessage("系统无此轮胎!").show(); - th.setText(""); - zbh.setText(""); - } - } catch (JsonSyntaxException e) { - return; - } - } - }); - } - private String safeGetString(String value) { - return value == null || "null".equals(value) ? "" : value; - } - private class KeyReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - int keyCode = intent.getIntExtra("keyCode", 0); - if (keyCode == 0) { - keyCode = intent.getIntExtra("keycode", 0); - } - boolean keyDown = intent.getBooleanExtra("keydown", false); - if (keyDown) { - if (toast == null) { - // toast = Toast.makeText(OutStoreHouseActivity.this, "KeyReceiver:keyCode = down" + keyCode, Toast.LENGTH_SHORT); - } else { - // toast.setText("KeyReceiver:keyCode = down" + keyCode); - } - // toast.show(); - switch (keyCode) { - case KeyEvent.KEYCODE_F1: - case KeyEvent.KEYCODE_F2: - case KeyEvent.KEYCODE_F3: - case KeyEvent.KEYCODE_F4: - case KeyEvent.KEYCODE_F5: - //扫描 - startFlag = true; - break; - } - } - } - } - private void registerReceiver() { - keyReceiver = new KeyReceiver(); - IntentFilter filter = new IntentFilter(); - filter.addAction("android.rfid.FUN_KEY"); - filter.addAction("android.intent.action.FUN_KEY"); - registerReceiver(keyReceiver, filter); - } - private void unregisterReceiver() { - unregisterReceiver(keyReceiver); - } - private void check_spinner() { - Gson gson = new Gson(); - OkGo.post(MyUrl.url + "/system/dict/data//wheelPositionList").execute(new StringCallback() { - @Override - public void onSuccess(Response response) { - hideLoadingDialog(); - String body = response.body(); - List stringList =new ArrayList<>(); - stringList = gson.fromJson(body, new TypeToken>() { - }.getType()); - ArrayAdapter arrayAdapter = new ArrayAdapter<>(UpActivity.this, android.R.layout.simple_list_item_1, stringList); - condition.setAdapter(arrayAdapter); - } - }); + // 去除可能的空格并转大写,保证比较一致性 + epc = epc.trim().toUpperCase(); + min = min.trim().toUpperCase(); + max = max.trim().toUpperCase(); - condition.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - azlw.setText(parent.getItemAtPosition(position).toString()); - } - - @Override - public void onNothingSelected(AdapterView parent) { - } - }); + // 逻辑:如果 epc 字符串在 min 和 max 之间(包含),则认为是车辆 + // compareTo 返回值:0相等,1大于,-1小于 + boolean isGreaterOrEqual = epc.compareTo(min) >= 0; + boolean isLessOrEqual = epc.compareTo(max) <= 0; + return isGreaterOrEqual && isLessOrEqual; } - private void car_spinner(String carNo) { - OkGo.post(MyUrl.url + "/tyre/car/PdaQueryCarList") - .tag(this).params("carNo", carNo) - .execute(new StringCallback() { - @Override - public void onSuccess(Response response) { - hideLoadingDialog(); - String body = response.body(); - Gson gson=new Gson(); - List baseCarList = gson.fromJson(body, new TypeToken>(){}.getType()); - Log.e("EPC", "listepc:+ " + baseCarList.size()); - if (baseCarList!=null && baseCarList.size()>0){ - List carNoList = new ArrayList<>(); - for (BaseCar car : baseCarList) { - carNoList.add(car.getCarNo()); - } - // 显示自定义弹窗 - showCarSelectionDialog(carNoList); - } - } - }); - } - - private void showCarSelectionDialog(List carNoList) { - CarSelectionDialog dialog = new CarSelectionDialog(this, carNoList); - dialog.setOnCarSelectedListener(new CarSelectionDialog.OnCarSelectedListener() { - @Override - public void onCarSelected(String carNo) { - car.setText(carNo); - // 处理选中的车辆 - // 例如设置到EditText或其他控件 - // editTextCarNo.setText(carNo); - } - }); - dialog.show(); - } -// carAdapter.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { -// @Override -// public void onItemSelected(AdapterView parent, View view, int position, long id) { -// car.setText(parent.getItemAtPosition(position).toString()); -// } -// -// @Override -// public void onNothingSelected(AdapterView parent) { -// } -// }); - - -} +} \ No newline at end of file diff --git a/app/src/main/java/com/example/tyre/entity/InStoreSpinnerVo.java b/app/src/main/java/com/example/tyre/entity/InStoreSpinnerVo.java index 675c91c..9e28bea 100644 --- a/app/src/main/java/com/example/tyre/entity/InStoreSpinnerVo.java +++ b/app/src/main/java/com/example/tyre/entity/InStoreSpinnerVo.java @@ -4,7 +4,7 @@ import java.util.List; public class InStoreSpinnerVo { private List tyreBrandList; - private List tyreSizeList; + private List tyreSizeList; private List levelList; private List patternList; private List kindList; @@ -26,11 +26,11 @@ public class InStoreSpinnerVo { this.tyreBrandList = tyreBrandList; } - public List getTyreSizeList() { + public List getTyreSizeList() { return tyreSizeList; } - public void setTyreSizeList(List tyreSizeList) { + public void setTyreSizeList(List tyreSizeList) { this.tyreSizeList = tyreSizeList; } diff --git a/app/src/main/java/com/example/tyre/entity/TyreSizeVo.java b/app/src/main/java/com/example/tyre/entity/TyreSizeVo.java new file mode 100644 index 0000000..099818c --- /dev/null +++ b/app/src/main/java/com/example/tyre/entity/TyreSizeVo.java @@ -0,0 +1,22 @@ +package com.example.tyre.entity; + +public class TyreSizeVo { + private String label; + private String value; + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/app/src/main/java/com/example/tyre/util/MyUrl.java b/app/src/main/java/com/example/tyre/util/MyUrl.java index 23cea64..8d348c4 100644 --- a/app/src/main/java/com/example/tyre/util/MyUrl.java +++ b/app/src/main/java/com/example/tyre/util/MyUrl.java @@ -7,6 +7,6 @@ package com.example.tyre.util; */ public class MyUrl { // public static String url="http://192.168.31.26:8020"; - public static String url="http://www.qdhys.xyz:8020"; -// public static String url="http://10.11.187.77:8020"; +// public static String url="http://www.qdhys.xyz:8020"; + public static String url="http://10.11.187.77:8020"; } diff --git a/app/src/main/res/drawable/rounded_border_input.xml b/app/src/main/res/drawable/rounded_border_input.xml new file mode 100644 index 0000000..ec0567f --- /dev/null +++ b/app/src/main/res/drawable/rounded_border_input.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_button_primary.xml b/app/src/main/res/drawable/rounded_button_primary.xml new file mode 100644 index 0000000..cfe9ae9 --- /dev/null +++ b/app/src/main/res/drawable/rounded_button_primary.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/rounded_input_bg.xml b/app/src/main/res/drawable/rounded_input_bg.xml new file mode 100644 index 0000000..0711d78 --- /dev/null +++ b/app/src/main/res/drawable/rounded_input_bg.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_instorehouse.xml b/app/src/main/res/layout/activity_instorehouse.xml index 79d7b0e..79e5e3b 100644 --- a/app/src/main/res/layout/activity_instorehouse.xml +++ b/app/src/main/res/layout/activity_instorehouse.xml @@ -1,313 +1,323 @@ - + - - - + android:background="#F5F7FA" + android:padding="8dp"> + + + - - - + android:layout_height="56dp" + android:background="#FFFFFF" + android:gravity="center" + android:elevation="4dp" + android:text="轮胎入库管理" + android:textColor="#333333" + android:textSize="20sp" + android:textStyle="bold" + android:layout_marginBottom="16dp" + android:padding="8dp"/> - + - + android:layout_height="wrap_content" + app:cardCornerRadius="12dp" + app:cardElevation="8dp" + android:layout_marginBottom="16dp"> - - + - - - + + + + + + + - - + - - - - - + + + + + + - - + + - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - + + - -