package com.example.tyre; import android.app.ProgressDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.graphics.Color; import android.media.AudioManager; import android.media.SoundPool; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.os.SystemClock; import android.text.Html; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.android.hdhe.uhf.reader.UhfReader; import com.android.hdhe.uhf.readerInterface.TagModel; import com.example.tyre.entity.AjaxResult; import com.example.tyre.entity.BaseTyre; import com.example.tyre.entity.EPC; import com.example.tyre.entity.Tyre; import com.example.tyre.util.CommonDialog; import com.example.tyre.util.MyUrl; import com.example.tyre.util.PlayMusic; import com.example.tyre.util.Util; import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; 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 cn.pda.serialport.Tools; import com.example.tyre.databinding.ActivityTyresearchBinding; import org.json.JSONObject; public class TyreSearchActivity extends AppCompatActivity { private ActivityTyresearchBinding binding; EditText inSantext; Button basemessage; Button button; TextView pinpai; TextView xinghao; TextView cengji; TextView huawen; private int power = 0; private int area = 0; private SharedPreferences shared; private EditText textVersion; private boolean runFlag = true; private boolean startFlag = false; private UhfReader manager; private ArrayList listEPC; private ArrayList listepc = new ArrayList(); private ProgressDialog progressDialog; private LinearLayout llTimelineContainer; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityTyresearchBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); bindViews(); // setupClickListeners(); manager = MyApplication.getManager(); initView(); Thread thread = new InventoryThread(); thread.start(); com.example.tyre.util.Util.initSoundPool(this); Log.e("onCreate", "onCreate:+ " ); llTimelineContainer = findViewById(R.id.ll_timeline_container); } private void renderTimeline(List data) { LayoutInflater inflater = LayoutInflater.from(this); llTimelineContainer.removeAllViews(); for (int i = 0; i < data.size(); i++) { // 加载单项布局 View itemView = inflater.inflate(R.layout.item_timeline, llTimelineContainer, false); TimelineItem item = data.get(i); // 绑定数据 TextView tvTime = itemView.findViewById(R.id.tv_time); TextView tvTitle = itemView.findViewById(R.id.tv_title); TextView tvContent = itemView.findViewById(R.id.tv_content); View viewLine = itemView.findViewById(R.id.view_line); // 竖线 tvTime.setText(item.time); tvTitle.setText(item.title); tvContent.setText(item.content); // 逻辑控制:如果是最后一条数据,隐藏竖线 if (i == data.size() - 1) { viewLine.setVisibility(View.GONE); } // 添加到容器 llTimelineContainer.addView(itemView); } } private void bindViews() { inSantext = binding.inSantext; // basemessage = binding.basemessage; button = binding.button; pinpai = binding.pinpai; xinghao = binding.xinghao; cengji = binding.cengji; huawen = binding.huawen; } // private void setupClickListeners() { // binding.scanButton.setOnClickListener(v -> { // if (!startFlag) { // startFlag = true; // binding.scanButton.setText("停 止"); // } else { // startFlag = false; // binding.scanButton.setText("扫 描"); // } // }); // binding.button.setOnClickListener(v -> { // // Intent intent = new Intent(this, HomePageActivity.class); // // startActivity(intent); // finish(); // }); // } @Override public void onResume() { super.onResume(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } registerReceiver(); } // TyreSearchActivity.java (内部类或单独文件) public class TimelineItem { public String time; public String title; public CharSequence content; public TimelineItem(String time, String title, CharSequence content) { this.time = time; this.title = title; this.content = content; } } @Override public void onPause() { startFlag = false; binding.scanButton.setText("搜索"); // manager.close(); unregisterReceiver(); Log.e("onPause", "onPause:+ " ); super.onPause(); } @Override protected void onDestroy() { startFlag = false; runFlag = false; Log.e("onDestroy", "onDestroy:+ " ); super.onDestroy(); } private void initView() { textVersion = binding.inSantext; pinpai = binding.pinpai; xinghao = binding.xinghao; cengji = binding.cengji; huawen = binding.huawen; listEPC = new ArrayList(); } private long exitTime = 0; private Toast mToast; private Toast toast; 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(); if (tagList != null && !tagList.isEmpty()) { Util.play(1, 0); for (TagModel tag : tagList) { if (tag == null) { String epcStr = ""; addToList(listEPC, epcStr, (byte) -1); } else { String epcStr = Tools.Bytes2HexString(tag.getmEpcBytes(), tag.getmEpcBytes().length); byte rssi = tag.getmRssi(); addToList(listEPC, epcStr, rssi); } } } tagList = null; try { Thread.sleep(20); } catch (InterruptedException e) { e.printStackTrace(); } } } } } private void addToList(final List list, final String epc, final byte rssi) { runOnUiThread(new Runnable() { @Override public void run() { if (list.isEmpty()) { EPC epcTag = new EPC(); epcTag.setEpc(epc); epcTag.setCount(1); epcTag.setRssi(rssi); list.add(epcTag); listepc.add(epc); }else { for (int i = 0; i < list.size(); i++) { EPC mEPC = list.get(i); if (epc.equals(mEPC.getEpc())) { mEPC.setCount(mEPC.getCount() + 1); mEPC.setRssi(rssi); list.set(i, mEPC); break; } else if (i == (list.size() - 1)) { EPC newEPC = new EPC(); newEPC.setEpc(epc); newEPC.setCount(1); newEPC.setRssi(rssi); list.add(newEPC); listepc.add(epc); } } } lastTime = SystemClock.elapsedRealtime(); long time = lastTime - nextTime; if (time >= 60) { Util.play(1, 0); nextTime = lastTime; Log.e("TAG", "run: " + time); } } }); Log.e("EPC", "listepc:+ " + listepc); if (listepc != null && !listepc.isEmpty()){ startFlag = false; //binding.scanButton.setText("扫 描"); textVersion.setText(listepc.get(0).toString()); find(listepc.get(0).toString()); } clearData(); } long lastTime; long nextTime; private void setButtonClickable(Button button, boolean flag) { button.setClickable(flag); if (flag) { button.setTextColor(Color.BLACK); } else { button.setTextColor(Color.GRAY); } } private void showToast(String message) { if (mToast == null) { mToast = Toast.makeText(TyreSearchActivity.this, message, Toast.LENGTH_SHORT); mToast.show(); } else { mToast.setText(message); mToast.show(); } } private void clearData() { listEPC.removeAll(listEPC); listepc.removeAll(listepc); } private KeyReceiver keyReceiver; 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 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) { } else { } switch (keyCode) { case KeyEvent.KEYCODE_F1: case KeyEvent.KEYCODE_F2: case KeyEvent.KEYCODE_F3: case KeyEvent.KEYCODE_F4: case KeyEvent.KEYCODE_F5: case 136: startFlag = true; //binding.scanButton.callOnClick(); break; } } } } private void find(String epc) { OkGo.post(MyUrl.url + "/tyre/tyre/pdaQueryTyreTimeLine").tag(this) .params("keyParam", epc) .execute(new StringCallback() { @Override public void onSuccess(Response response) { hideLoadingDialog(); String body = response.body(); try { Gson gson = new Gson(); JsonElement rootElement = JsonParser.parseString(body); JsonObject rootObject = rootElement.getAsJsonObject(); BaseTyre baseTyre =new BaseTyre(); // 3. 获取 "data" 节点 (注意判空,防止空指针异常) if (rootObject.has("data") && !rootObject.get("data").isJsonNull()) { JsonObject dataObject = rootObject.getAsJsonObject("data"); // 4. 获取 "resultBase" 节点 String team = ""; String TYREPYTE = ""; String patternDepth = ""; if (dataObject.has("resultBase") && !dataObject.get("resultBase").isJsonNull()) { JsonElement resultBaseElement = dataObject.get("resultBase"); // 5. 【关键步骤】将 resultBase 节点直接转换为 BaseTyre 对象 baseTyre = gson.fromJson(resultBaseElement, BaseTyre.class); if (baseTyre != null) { String brand = safeGetString(baseTyre.getTyreBrand()); String model = safeGetString(baseTyre.getTyreModel()); String level = safeGetString(baseTyre.getTyreLevel()); String pattern = safeGetString(baseTyre.getTyrePattern()); team = safeGetString(baseTyre.getTeam()); TYREPYTE = "new".equals(TYREPYTE) ? "全新胎" : TYREPYTE; patternDepth = safeGetString(baseTyre.getPatternDepth()); pinpai.setText(brand); xinghao.setText(model); cengji.setText(level); huawen.setText(pattern); }else { pinpai.setText(""); xinghao.setText(""); cengji.setText(""); huawen.setText(""); } } //出入库数据 List data = new ArrayList<>(); if(dataObject.has("recordWarehousingList") && !dataObject.get("recordWarehousingList").isJsonNull()){ JsonElement resultBaseElement = dataObject.get("recordWarehousingList"); JsonArray jsonArray = resultBaseElement.getAsJsonArray(); // 2. 遍历数组中的每一个元素 for (JsonElement element : jsonArray) { // 3. 将每个元素转为 JsonObject,方便通过键名取值 JsonObject itemObject = element.getAsJsonObject(); // 4. 提取你需要的字段(假设里面有 "warehouseId" 和 "status" 字段) String tyreNo = itemObject.has("tyreNo") ? itemObject.get("tyreNo").getAsString() : ""; String type = itemObject.has("type") ? itemObject.get("type").getAsString() : ""; String time = itemObject.has("createTime") ? itemObject.get("createTime").getAsString() : ""; String user = itemObject.has("createBy") ? itemObject.get("createBy").getAsString() : ""; // 打印或处理你的数据 if (type.equals("0")){ data.add(new TimelineItem(time, "轮胎入库", Html.fromHtml("操作人:"+user+"
场站: "+team+ "
轮胎类型: "+TYREPYTE+ "
剩余花纹深度: "+patternDepth+"mm"+ "
里程: "+"0"))); } } // 1. 生成模拟数据 (按时间倒序) // // data.add(new TimelineItem("2026-04-20 12:23:28", "轮胎安装: 赵宁波", "车辆: 粤B08499D | 轮位: 右外轮")); // data.add(new TimelineItem("2026-04-20 12:17:46", "轮胎出库: 赵宁波", "仓库: 轮胎仓库")); // data.add(new TimelineItem("2026-04-20 12:15:37", "轮胎入库: 赵宁波", "仓库: 轮胎仓库")); // data.add(new TimelineItem("2026-04-19 09:00:00", "轮胎采购", "供应商: 某某橡胶厂")); // // 2. 动态添加视图 renderTimeline(data); data.clear(); } } } catch (JsonSyntaxException e) { pinpai.setText(""); xinghao.setText(""); cengji.setText(""); huawen.setText(""); return; } } @Override public void onError(Response response) { super.onError(response); // ✅ 修改点 3:网络请求失败也要关闭弹窗 Toast.makeText(TyreSearchActivity.this, "网络请求失败", Toast.LENGTH_SHORT).show(); } }); } private String safeGetString(String value) { return value == null || "null".equals(value) ? "" : value; } 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(); } } }