diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser index 46b8cd5..ddb1594 100644 Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 70bcdef..215c958 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,6 +5,9 @@ + + + + + + + + + + + - - - - + + + + + + - - - + - - + + + + - + + + - - - - + + - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/tyre/CheckActivity.java b/app/src/main/java/com/example/tyre/CheckActivity.java index b5a4d8e..355b76e 100644 --- a/app/src/main/java/com/example/tyre/CheckActivity.java +++ b/app/src/main/java/com/example/tyre/CheckActivity.java @@ -25,13 +25,17 @@ import com.android.hdhe.uhf.readerInterface.TagModel; import com.example.tyre.entity.AjaxResult; import com.example.tyre.entity.BaseTyre; import com.example.tyre.entity.Check; +import com.example.tyre.entity.CheckInfoSpinnerVo; import com.example.tyre.entity.EPC; +import com.example.tyre.entity.InStoreSpinnerVo; 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.SharedPreferencesUtils; import com.example.tyre.util.Util; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import com.google.gson.reflect.TypeToken; @@ -51,22 +55,23 @@ import butterknife.OnClick; import cn.pda.serialport.Tools; public class CheckActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener { - @BindView(R.id.epc) - TextView Epc; - @BindView(R.id.checkresult) - TextView checkresult; - @BindView(R.id.tyrecon) - TextView tyrecon; - @BindView(R.id.th) - TextView th; - @BindView(R.id.zbh) - TextView zbh; - @BindView(R.id.result) - Spinner result; - @BindView(R.id.wc) - Button wc; - @BindView(R.id.fh) - Button fh; + @BindView(R.id.epc_display) TextInputEditText epcInput; + @BindView(R.id.th) TextInputEditText tyreNoInput; + @BindView(R.id.zbh) TextInputEditText selfNoInput; + @BindView(R.id.tyrecon) TextInputEditText remarkInput; + @BindView(R.id.patternDepth) TextInputEditText patternDepthInput; + @BindView(R.id.mileage) TextInputEditText mileageInput; + + @BindView(R.id.epc_layout) TextInputLayout epcLayout; + @BindView(R.id.th_layout) TextInputLayout tyreNoLayout; + @BindView(R.id.zbh_layout) TextInputLayout selfNoLayout; + @BindView(R.id.mileage_layout) TextInputLayout mileageNoLayout; + @BindView(R.id.patternDepth_layout) TextInputLayout patternDepthNoLayout; + + @BindView(R.id.result) Spinner resultSpinner; + @BindView(R.id.CheckTypeSpinner) Spinner checkTypeSpinner; + + private boolean isStart = true; private ProgressDialog progressDialog; private boolean runFlag = true; @@ -90,7 +95,8 @@ public class CheckActivity extends AppCompatActivity implements AdapterView.OnIt Thread thread = new InventoryThread(); thread.start(); Util.initSoundPool(this); - result.setOnItemSelectedListener(this); + resultSpinner.setOnItemSelectedListener(this); + checkTypeSpinner.setOnItemSelectedListener(this); check_spinner(); showLoadingDialog(); } @@ -198,16 +204,21 @@ public class CheckActivity extends AppCompatActivity implements AdapterView.OnIt nextTime = lastTime; Log.e("TAG", "run: " + time); } + if (listepc != null && !listepc.isEmpty()){ + startFlag = false; + String currentEpc = listepc.get(0); + epcInput.setText(currentEpc); + //请求后台 + debounceHandler.removeMessages(1); + lastScannedEpc = currentEpc; + debounceHandler.sendEmptyMessageDelayed(1, DEBOUNCE_DELAY); +// showLoadingDialog(); +// find(listepc.get(0).toString()); + } + clearData(); } }); Log.e("EPC", "listepc:+ " + listepc); - if (listepc != null && !listepc.isEmpty()){ - startFlag = false; - Epc.setText(listepc.get(0).toString()); - //请求后台 - find(listepc.get(0).toString()); - } - clearData(); } private void clearData() { listEPC.removeAll(listEPC); @@ -267,7 +278,10 @@ public class CheckActivity extends AppCompatActivity implements AdapterView.OnIt public void onItemSelected(AdapterView parent, View view, int position, long id) { switch (parent.getId()) { case R.id.result: - checkresult.setText(parent.getItemAtPosition(position).toString()); + // checkresult.setText(parent.getItemAtPosition(position).toString()); + break; + case R.id.CheckTypeSpinner: + // checktype.setText(parent.getItemAtPosition(position).toString()); break; } @@ -282,16 +296,31 @@ public class CheckActivity extends AppCompatActivity implements AdapterView.OnIt public void onViewClicked(View view) { switch (view.getId()) { case R.id.wc: - String rfid=Epc.getText().toString(); - String result = checkresult.getText().toString(); - String remark = tyrecon.getText().toString(); - if (rfid == null || rfid.isEmpty()) + String rfid=epcInput.getText().toString(); + String selectedResult = resultSpinner.getSelectedItem().toString(); + String checkType = checkTypeSpinner.getSelectedItem().toString(); + String remark = remarkInput.getText().toString(); + String mileage = mileageInput.getText().toString().trim(); + String patternDepth = patternDepthInput.getText().toString().trim(); + String tyreNo = tyreNoInput.getText().toString().trim(); + String selfNo = selfNoInput.getText().toString().trim(); + if (rfid == null || rfid.isEmpty() || rfid.equals("等待扫描...")) { - new CommonDialog(CheckActivity.this).setMessage("请扫描轮胎!").show(); + epcLayout.setError("请扫描芯片"); return; } - showLoadingDialog(); - insert_check_record(rfid,result,remark); + if (tyreNo == null || tyreNo.isEmpty()) + { + tyreNoLayout.setError("请检查胎号数据"); + return; + } + if (selfNo == null || selfNo.isEmpty()) + { + selfNoLayout.setError("请检查自编号数据"); + return; + } + showLoadingDialog(); + insert_check_record(rfid,selectedResult,remark,checkType,mileage,patternDepth); break; case R.id.fh: Intent intent=new Intent(this,HomePageActivity.class); @@ -300,16 +329,32 @@ public class CheckActivity extends AppCompatActivity implements AdapterView.OnIt } } + // 防抖延迟时间 (毫秒) + 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(); + performFind(lastScannedEpc); + lastScannedEpc = null; // 清空,等待下一次扫描 + } + return true; + } + }); // 基本信息查询 - private void find(String epc) { + private void performFind(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); @@ -317,12 +362,12 @@ public class CheckActivity extends AppCompatActivity implements AdapterView.OnIt // 空值处理:若字段为 null 则显示空字符串 String TyreNo = safeGetString(baseTyre.getTyreNo()); String zb = safeGetString(baseTyre.getSelfNo()); - th.setText(TyreNo); - zbh.setText(zb); + tyreNoInput.setText(TyreNo); + selfNoInput.setText(zb); }else { new CommonDialog(CheckActivity.this).setMessage("系统无此轮胎!").show(); - th.setText(""); - zbh.setText(""); + tyreNoInput.setText(""); + selfNoInput.setText(""); } } catch (JsonSyntaxException e) { return; @@ -335,37 +380,56 @@ public class CheckActivity extends AppCompatActivity implements AdapterView.OnIt return value == null || "null".equals(value) ? "" : value; } private void check_spinner() { - OkGo.post(MyUrl.url + "/system/dict/data//checkResultList").execute(new StringCallback() { + OkGo.post(MyUrl.url + "/system/dict/data/getDictDataList").execute(new StringCallback() { @Override public void onSuccess(Response response) { String body = response.body(); Gson gson = new Gson(); hideLoadingDialog(); - List stringList =new ArrayList<>(); - stringList = gson.fromJson(body, new TypeToken>() { - }.getType()); + CheckInfoSpinnerVo checkInfoSpinnerVo =new CheckInfoSpinnerVo(); + checkInfoSpinnerVo = gson.fromJson(body,CheckInfoSpinnerVo.class); + List stringList=checkInfoSpinnerVo.getCheckResultList(); + List checkTypeList=checkInfoSpinnerVo.getCheckTypeList(); +// List stringList =new ArrayList<>(); +// stringList = gson.fromJson(body, new TypeToken>() { +// }.getType()); ArrayAdapter arrayAdapter = new ArrayAdapter<>(CheckActivity.this, android.R.layout.simple_list_item_1, stringList); - result.setAdapter(arrayAdapter); - } - }); - result.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - checkresult.setText(parent.getItemAtPosition(position).toString()); - } - - @Override - public void onNothingSelected(AdapterView parent) { + resultSpinner.setAdapter(arrayAdapter); + ArrayAdapter checkTypeAdapter = new ArrayAdapter<>(CheckActivity.this, android.R.layout.simple_list_item_1, checkTypeList); + checkTypeSpinner.setAdapter(checkTypeAdapter); } }); +// result.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { +// @Override +// public void onItemSelected(AdapterView parent, View view, int position, long id) { +// //checkresult.setText(parent.getItemAtPosition(position).toString()); +// } +// +// @Override +// public void onNothingSelected(AdapterView parent) { +// } +// }); +// result.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { +// @Override +// public void onItemSelected(AdapterView parent, View view, int position, long id) { +// // checktype.setText(parent.getItemAtPosition(position).toString()); +// } +// +// @Override +// public void onNothingSelected(AdapterView parent) { +// } +// }); } //插质检记录表 - private void insert_check_record(String rfid,String result,String remark){ + private void insert_check_record(String rfid,String selectedResult,String remark,String checkType,String mileage,String patternDepth){ OkGo.post(MyUrl.url + "/tyre/check/PdaAddCheck") .params("tyreRfid",rfid) - .params("result",result) + .params("result",selectedResult) .params("remark",remark) + .params("maintenanceType",checkType) + .params("mileage",mileage) + .params("patternDepth",patternDepth) .params("CreateBy", SharedPreferencesUtils.getstring("user","admin")) .execute(new StringCallback() { @Override diff --git a/app/src/main/java/com/example/tyre/DownActivity.java b/app/src/main/java/com/example/tyre/DownActivity.java index 125d4ad..821f1ca 100644 --- a/app/src/main/java/com/example/tyre/DownActivity.java +++ b/app/src/main/java/com/example/tyre/DownActivity.java @@ -69,6 +69,8 @@ public class DownActivity extends AppCompatActivity implements AdapterView.OnIte TextView th; @BindView(R.id.zbh) TextView zbh; + @BindView(R.id.patternDepth) + EditText patternDepth; private boolean isStart = true; private ProgressDialog progressDialog; private boolean runFlag = true; @@ -270,6 +272,7 @@ public class DownActivity extends AppCompatActivity implements AdapterView.OnIte String carNo = car.getText().toString(); String millage = start.getText().toString(); String wheel = azlw.getText().toString(); + String depth = patternDepth.getText().toString(); if (rfid == null || rfid.isEmpty()) { new CommonDialog(DownActivity.this).setMessage("请扫描轮胎!").show(); @@ -291,7 +294,7 @@ public class DownActivity extends AppCompatActivity implements AdapterView.OnIte return; } showLoadingDialog(); - down_insert(rfid,carNo,millage,wheel); + down_insert(rfid,carNo,millage,wheel,depth); break; case R.id.back: Intent intent = new Intent(this, HomePageActivity.class); @@ -346,12 +349,13 @@ public class DownActivity extends AppCompatActivity implements AdapterView.OnIte return value == null || "null".equals(value) ? "" : value; } // 删除实时表、卸车记录表 - private void down_insert(String rfid,String carNo,String millage,String wheel) { + private void down_insert(String rfid,String carNo,String millage,String wheel,String patternDepth) { OkGo.post(MyUrl.url + "/tyre/install/PdaUnInstallTyre").tag(this) .params("tyreRfid", rfid) .params("mileage", millage) .params("carNo", carNo) .params("wheelPostion", wheel) + .params("patternDepth", patternDepth) .params("CreateBy", SharedPreferencesUtils.getstring("user","admin")) .execute(new StringCallback() { @Override diff --git a/app/src/main/java/com/example/tyre/HomePageActivity.java b/app/src/main/java/com/example/tyre/HomePageActivity.java index 22a88c1..32132b1 100644 --- a/app/src/main/java/com/example/tyre/HomePageActivity.java +++ b/app/src/main/java/com/example/tyre/HomePageActivity.java @@ -33,66 +33,94 @@ public class HomePageActivity extends AppCompatActivity { RadioButton zhijian; @BindView(R.id.logout) Button logout; - private long exitTime=0; - @Override + private long exitTime = 0; + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_homepage); ButterKnife.bind(this); } - @OnClick({R.id.chaxun, R.id.ruku, R.id.chuku, R.id.zhuangxie, R.id.huanwei,R.id.zhijian,R.id.xxbd}) + /** + * 修改点 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}) public void onViewClicked(View view) { - Intent intent = new Intent(this,MainActivity.class); + Intent intent; // 建议在这里声明,而不是方法最开始 + switch (view.getId()) { case R.id.chaxun: - intent=new Intent(this,TyreSearchActivity.class); + intent = new Intent(this, TyreSearchActivity.class); break; case R.id.ruku: - intent=new Intent(this,InStoreHouseActivity.class); + intent = new Intent(this, InStoreHouseActivity.class); break; case R.id.chuku: - intent=new Intent(this,OutStoreHouseActivity.class); + intent = new Intent(this, OutStoreHouseActivity.class); break; case R.id.zhuangxie: - intent=new Intent(this,UpActivity.class); + intent = new Intent(this, UpActivity.class); break; case R.id.huanwei: - intent=new Intent(this,DownActivity.class); + intent = new Intent(this, DownActivity.class); break; case R.id.zhijian: - intent=new Intent(this,CheckActivity.class); - break; - case R.id.logout: - finish(); + intent = new Intent(this, CheckActivity.class); break; case R.id.xxbd: - intent=new Intent(this,TestActivity.class); + intent = new Intent(this, TestActivity.class); break; - + case R.id.test1: + intent = new Intent(this, TyreLayoutActivity.class); + break; + case R.id.logout: + // 修改点 2:处理退出逻辑 + handleLogout(); + return; // 退出后直接返回,不需要执行下面的 startActivity + default: + return; } + + // 只有非退出按钮才执行跳转 startActivity(intent); } + /** + * 新增:处理退出登录的逻辑 + */ + private void handleLogout() { + // 1. 清除登录状态(可选:清除 SharedPreferences 中的用户信息) + // 例如:SharedPreferencesUtils.clear(); + + // 2. 提示用户 + Toast.makeText(this, "已退出登录", Toast.LENGTH_SHORT).show(); + + // 3. 跳转回登录页 (MainActivity) + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + + // 4. 关闭当前主页,防止按返回键回到主页 + finish(); + } + private void exit() { if ((System.currentTimeMillis() - exitTime) > 2000) { Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show(); exitTime = System.currentTimeMillis(); + } else { + finish(); + // System.exit(0); // 通常不需要手动调用 System.exit,finish() 即可 } - else{ - finish(); - System.exit(0); - } - - } + } @Override - public boolean onKeyDown(int keyCode,KeyEvent event){ - if(keyCode== KeyEvent.KEYCODE_BACK){ + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK) { exit(); return false; } - return super.onKeyDown(keyCode,event); + return super.onKeyDown(keyCode, event); } - } \ No newline at end of file +} \ No newline at end of file diff --git a/app/src/main/java/com/example/tyre/InStoreHouseActivity.java b/app/src/main/java/com/example/tyre/InStoreHouseActivity.java index d680a98..9627903 100644 --- a/app/src/main/java/com/example/tyre/InStoreHouseActivity.java +++ b/app/src/main/java/com/example/tyre/InStoreHouseActivity.java @@ -69,6 +69,8 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi TextView cengji; @BindView(R.id.huawen) TextView huawen; + @BindView(R.id.gcts) + TextView gcts; @BindView(R.id.back) Button back; @BindView(R.id.wtbm) @@ -97,6 +99,9 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi @BindView(R.id.spinnerBrand) Spinner spinnerBrand; + + @BindView(R.id.spinnergcts) + Spinner spinnergcts; // private UHFService mDevice; // private MyHandler handler; private boolean isStart = true; @@ -119,6 +124,7 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi spinnerlevel.setOnItemSelectedListener(this); spinnerSize.setOnItemSelectedListener(this); spinnerBrand.setOnItemSelectedListener(this); + spinnergcts.setOnItemSelectedListener(this); initView(); Thread thread = new InventoryThread(); thread.start(); @@ -249,17 +255,24 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi 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(); +// 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); @@ -279,6 +292,8 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi 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()); @@ -300,7 +315,7 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi return value == null || "null".equals(value) ? "" : value; } //添加到库存表 - private void insert_inventory(String epc,String wtbm,String pinpai,String xinghao,String cengji,String huawen,String tyrekind) { + 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) @@ -309,6 +324,7 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi .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 @@ -319,6 +335,11 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi 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) { @@ -348,12 +369,13 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi 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,t); + insert_inventory(epc,w,p,x,c,h,g,t); // } break; case R.id.back: @@ -385,6 +407,9 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi case R.id.spinnerBrand: pinpai.setText(parent.getItemAtPosition(position).toString()); break; + case R.id.spinnergcts: + gcts.setText(parent.getItemAtPosition(position).toString()); + break; } } private Toast mToast; @@ -438,17 +463,19 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi 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() { @@ -501,7 +528,16 @@ public class InStoreHouseActivity extends AppCompatActivity implements AdapterVi 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() { diff --git a/app/src/main/java/com/example/tyre/MainActivity.java b/app/src/main/java/com/example/tyre/MainActivity.java index a843fb2..f059324 100644 --- a/app/src/main/java/com/example/tyre/MainActivity.java +++ b/app/src/main/java/com/example/tyre/MainActivity.java @@ -1,29 +1,55 @@ package com.example.tyre; +import android.Manifest; +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.DownloadManager; import android.app.ProgressDialog; +import android.content.ActivityNotFoundException; +import android.content.BroadcastReceiver; +import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; import android.os.Bundle; +import android.os.Environment; +import android.os.Process; +import android.util.Log; import android.widget.Button; +import android.widget.CheckBox; import android.widget.EditText; -import android.widget.ListPopupWindow; +import android.widget.TextView; import android.widget.Toast; import com.example.tyre.entity.AjaxResult; -import com.example.tyre.entity.Tyre; import com.example.tyre.util.CommonDialog; import com.example.tyre.util.MyUrl; import com.example.tyre.util.SharedPreferencesUtils; import com.google.gson.Gson; import com.lzy.okgo.OkGo; +import com.lzy.okgo.callback.FileCallback; import com.lzy.okgo.callback.StringCallback; +import com.lzy.okgo.model.Progress; import com.lzy.okgo.model.Response; import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; + +import org.json.JSONObject; + +import java.io.File; + import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; -//implements OnTouchListener,OnItemClickListener public class MainActivity extends AppCompatActivity { @BindView(R.id.login_name) EditText loginName; @@ -31,54 +57,190 @@ public class MainActivity extends AppCompatActivity { EditText loginPass; @BindView(R.id.login_log) Button loginLog; - private EditText etTest; - private ListPopupWindow lpw; - private String[] list; + @BindView(R.id.checkbox_remember) + CheckBox cbRemember; + @BindView(R.id.version) + TextView version; + // 声明进度条变量 private ProgressDialog progressDialog; + private static final int PERMISSION_REQUEST_CODE = 1001; + private BroadcastReceiver downloadReceiver; + + private static final int REQUEST_PERMISSIONS = 100; + private long downloadId; + private DownloadManager downloadManager; + private String newVersionName; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ButterKnife.bind(this); - loginName.setText("admin"); - loginPass.setText("haiwei@123"); -// etTest = (EditText) findViewById(R.id.login_name); -// etTest.setOnTouchListener(this); -// list = new String[] { "item1", "item2", "item3", "item4" }; -// lpw = new ListPopupWindow(this); -// lpw.setAdapter(new ArrayAdapter(this,android.R.layout.simple_list_item_1, list)); -// lpw.setAnchorView(etTest); -// lpw.setModal(true); -// lpw.setOnItemClickListener(this); + // --- 新增:页面加载时读取保存的账号密码 --- + initRememberInfo(); + // 2. 检查权限并开始检查更新 + //showLoadingDialog(); + //checkPermissionsAndUpdate(); + // 注册下载完成广播接收器 + //registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); + } + /** + * 检查权限并开始版本更新检查 + */ + private void checkPermissionsAndUpdate() { + // Android 6.0+ 动态申请存储权限(用于下载APK) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_CODE); + } else { + // 权限已获取,开始检查更新 + checkAppUpdate(); + } + } else { + // 版本低于 6.0,直接检查更新 + checkAppUpdate(); + } + } + /** + * 初始化“记住密码”的数据回显 + */ + private void initRememberInfo() { + // 假设你在 SharedPreferencesUtils 中保存的 key 是 "user" 和 "password" + String savedUser = SharedPreferencesUtils.getstring("user", ""); + String savedPass = SharedPreferencesUtils.getstring("password", ""); + + // 如果用户名不为空,说明之前勾选过,则填充数据并勾选CheckBox + if (savedUser != null && !savedUser.isEmpty()) { + loginName.setText(savedUser); + loginPass.setText(savedPass); + cbRemember.setChecked(true); + } else { + cbRemember.setChecked(false); + } } @OnClick(R.id.login_log) public void onViewClicked() { - showLoadingDialog(); - login(loginName.getText().toString(),loginPass.getText().toString()); - } -// @Override -// public void onItemClick(AdapterView parent, View view, int position,long id) {String item = list[position];etTest.setText(item);lpw.dismiss(); -// } -// @Override -// public boolean onTouch(View v, MotionEvent event) {final int DRAWABLE_RIGHT = 2; -// if (event.getAction() == MotionEvent.ACTION_UP) {if (event.getX() >= (v.getWidth() - ((EditText) v) .getCompoundDrawables()[DRAWABLE_RIGHT].getBounds().width())) {lpw.show();return true; -// } -// } -// return false; -// } - private void showLoadingDialog() { - progressDialog = new ProgressDialog(this); - progressDialog.setMessage("数据加载中..."); - progressDialog.setCancelable(false); - progressDialog.show(); - } - private void hideLoadingDialog() { - if (progressDialog != null && progressDialog.isShowing()) { - progressDialog.dismiss(); + // 获取输入内容 + String name = loginName.getText().toString().trim(); + String pass = loginPass.getText().toString().trim(); + + // --- 修改:在点击登录时立即获取CheckBox状态 --- + // 注意:这里直接用 cbRemember.isChecked(),不要等到网络请求回来再判断 + boolean isRemember = cbRemember.isChecked(); + + // 简单的非空校验 + if (name.isEmpty() || pass.isEmpty()) { + Toast.makeText(this, "用户名或密码不能为空", Toast.LENGTH_SHORT).show(); + return; } + + showLoadingDialog(); + login(name, pass, isRemember); // 将状态传递给 login 方法 } - private void login(String name, String pass) { + + /** + * 核心逻辑:检查更新 + */ + private void checkAppUpdate() { + // 1. 获取本地版本号 (从 AndroidManifest.xml 读取) + String localVersionName = getVersionName(); + Log.d("Version", "本地版本: " + localVersionName); + // 2. 请求服务器接口获取最新版本 + // 假设接口返回格式: { "code": "0", "data": { "versionCode": 2, "apkUrl": "..." } } + OkGo.post(MyUrl.url + "/system/package/checkUpdate") // 替换为你实际的检查更新接口地址 + .tag(this) + .execute(new StringCallback() { + @Override + public void onSuccess(Response response) { + hideLoadingDialog(); + try { + JSONObject jsonObject = new JSONObject(response.body()); + String code = jsonObject.getString("code"); + if ("0".equals(code)) { + JSONObject data = jsonObject.getJSONObject("data"); +// // 获取服务器版本号 (String) + String serverVersionName = data.getString("version"); + String apkUrl = data.getString("fileName"); + int compareResult = compareVersion(serverVersionName, localVersionName); + runOnUiThread(() -> { + version.setText("当前版本: " + localVersionName + " | 最新版本: " + serverVersionName); + }); +// // 3. 对比版本号 +// // 如果服务器版本 > 本地版本 + if (compareResult > 0) { + showUpdateDialog(apkUrl, serverVersionName); + } +// if (compareVersion(serverVersionName, localVersionName) > 0) { +// showUpdateDialog(apkUrl); +// } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + /** + * 显示更新对话框 + */ + private void showUpdateDialog(String downloadUrl, String serverVersion) { + this.newVersionName = serverVersion; + new AlertDialog.Builder(this) + .setTitle("发现新版本 " + serverVersion) + .setMessage("检测到最新版本,是否立即下载并安装?") + .setPositiveButton("立即下载", (dialog, which) -> startDownload(downloadUrl)) + .setNegativeButton("取消", null) + .show(); + } + + private String getVersionName() { + // 1. 先尝试从 SP 读取(这个值是上次下载更新时存进去的最新版本) + + // 3. 如果 SP 里没有(说明是第一次安装或没更新过),读取 build.gradle 里的 versionName + try { + PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); + return packageInfo.versionName; + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } + return "1.0"; + } + private int compareVersion(String v1, String v2) { + // 如果两个版本号完全相同,直接返回0 + if (v1.equals(v2)) { + return 0; + } + + // 将版本号按 "." 分割成数组 + String[] v1Array = v1.split("\\."); + String[] v2Array = v2.split("\\."); + + // 获取最大长度,确保能遍历完所有部分 + int maxLength = Math.max(v1Array.length, v2Array.length); + + for (int i = 0; i < maxLength; i++) { + // 获取当前位的数值,如果该位置不存在(比如 1.0 对比 1.0.1),则默认为 0 + int v1Part = i < v1Array.length ? Integer.parseInt(v1Array[i]) : 0; + int v2Part = i < v2Array.length ? Integer.parseInt(v2Array[i]) : 0; + + // 逐位比较 + if (v1Part > v2Part) { + return 1; // v1 大 + } else if (v1Part < v2Part) { + return -1; // v2 大 + } + } + return 0; // 相等 + } + /** + * 登录请求 + * @param isRemember 是否勾选了记住密码 + */ + private void login(String name, String pass, boolean isRemember) { OkGo.post(MyUrl.url + "/PdaLogin") .tag(this) .params("username", name) @@ -90,9 +252,23 @@ public class MainActivity extends AppCompatActivity { String body = response.body(); Gson gson = new Gson(); AjaxResult ajaxResult = gson.fromJson(body, AjaxResult.class); + + // 处理登录结果 handleLoginResponse(ajaxResult); - SharedPreferencesUtils.putstring("user",name); - SharedPreferencesUtils.putstring("password",pass); + + // --- 修改:在这里处理保存逻辑 --- + // 如果登录成功(假设 code 为 "0" 代表成功),且用户勾选了记住密码,则保存 + // 如果用户没勾选,则清空保存的数据 + if ("0".equals(ajaxResult.getCode())) { + if (isRemember) { + SharedPreferencesUtils.putstring("user", name); + SharedPreferencesUtils.putstring("password", pass); + } else { + // 如果没勾选,清除本地存储的密码(可选) + SharedPreferencesUtils.putstring("user", ""); + SharedPreferencesUtils.putstring("password", ""); + } + } } @Override @@ -103,11 +279,28 @@ public class MainActivity extends AppCompatActivity { }); } + 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(); + } + } + private void handleLoginResponse(AjaxResult result) { switch (result.getCode()) { case "0": + // 登录成功 Toast.makeText(this, result.getMsg(), Toast.LENGTH_SHORT).show(); - //SharedPreferencesUtils.putString("UserID", name); Intent intent = new Intent(this, HomePageActivity.class); startActivity(intent); finish(); @@ -120,4 +313,103 @@ public class MainActivity extends AppCompatActivity { break; } } -} + /** + * 开始下载 APK + * @param fileName 服务器上的文件名 (例如: "app-release.apk" 或若依数据库里的 "resourceName") + */ + private void startDownload(String fileName) { + // 1. 构建完整的下载 URL + String downloadUrl = MyUrl.url + "/common/downloadApk?fileName=tyre_update.apk"; + + downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadUrl)); + request.setTitle("APK下载"); + request.setDescription("正在下载更新..."); + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + request.setRequiresDeviceIdle(false); + request.setAllowedOverMetered(true); + request.setAllowedOverRoaming(true); + } + + downloadId = downloadManager.enqueue(request); + Toast.makeText(this, "开始下载...", Toast.LENGTH_SHORT).show(); + } + + + + + private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); + + if (downloadId == id) { + SharedPreferencesUtils.putstring("local_app_version", newVersionName); + runOnUiThread(() -> { + // 这里更新界面上的 TextView + version.setText("当前版本: " + newVersionName); // ⭐ 修改:直接显示新版本 + }); + DownloadManager.Query query = new DownloadManager.Query(); + query.setFilterById(id); + + Cursor cursor = downloadManager.query(query); + if (cursor.moveToFirst()) { + int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); + + if (status == DownloadManager.STATUS_SUCCESSFUL) { + String localUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); + installApk(Uri.parse(localUri).getPath()); + } else { + int reason = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_REASON)); + Toast.makeText(context, "下载失败,错误码: " + reason, Toast.LENGTH_SHORT).show(); + } + } + cursor.close(); + } + } + }; + private void installApk(String apkPath) { + File file = new File(apkPath); + if (!file.exists()) { + Toast.makeText(this, "APK文件不存在", Toast.LENGTH_SHORT).show(); + return; + } + + Intent intent = new Intent(Intent.ACTION_VIEW); + Uri uri; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + uri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", file); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + uri = Uri.fromFile(file); + } + + intent.setDataAndType(uri, "application/vnd.android.package-archive"); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + try { + startActivity(intent); + } catch (Exception e) { + Toast.makeText(this, "无法安装应用: " + e.getMessage(), Toast.LENGTH_LONG).show(); + } + } + @Override + protected void onDestroy() { + super.onDestroy(); + // unregisterReceiver(onDownloadComplete); + } + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 1001) { + if (resultCode == RESULT_OK) { + Toast.makeText(this, "已获得安装未知应用权限", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(this, "未获得安装未知应用权限,无法自动安装", Toast.LENGTH_LONG).show(); + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/tyre/MainActivity2.java b/app/src/main/java/com/example/tyre/MainActivity2.java new file mode 100644 index 0000000..11b15bc --- /dev/null +++ b/app/src/main/java/com/example/tyre/MainActivity2.java @@ -0,0 +1,189 @@ +package com.example.tyre; + + +import android.Manifest; +import android.app.DownloadManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.provider.Settings; +import android.view.View; +import android.widget.Button; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; + +import com.example.tyre.util.MyUrl; + +import java.io.File; + +public class MainActivity2 extends AppCompatActivity { + + private static final int REQUEST_PERMISSIONS = 100; + private long downloadId; + private DownloadManager downloadManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main2); + + Button downloadButton = findViewById(R.id.download_button); + + // 注册下载完成广播接收器 + registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); + + downloadButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (checkPermissions()) { + startDownload("app-release.apk"); + } else { + requestPermissions(); + } + } + }); + downloadButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (checkPermissions()) { + startDownload("app-release.apk"); + } else { + requestPermissions(); + } + } + }); + } + + private boolean checkPermissions() { + boolean storagePermissionGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; + boolean installPermissionGranted = true; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + installPermissionGranted = getPackageManager().canRequestPackageInstalls(); + } + + return storagePermissionGranted && installPermissionGranted; + } + + private void requestPermissions() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + REQUEST_PERMISSIONS); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (!getPackageManager().canRequestPackageInstalls()) { + startActivityForResult(new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES) + .setData(Uri.parse(String.format("package:%s", getPackageName()))), 1001); + } + } + } + + /** + * 开始下载 APK + * @param fileName 服务器上的文件名 (例如: "app-release.apk" 或若依数据库里的 "resourceName") + */ + private void startDownload(String fileName) { + // 1. 构建完整的下载 URL + String downloadUrl = MyUrl.url + "/common/downloadApk?fileName=tyre_update.apk"; + + downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); + DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadUrl)); + request.setTitle("APK下载"); + request.setDescription("正在下载更新..."); + request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); + request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + request.setRequiresDeviceIdle(false); + request.setAllowedOverMetered(true); + request.setAllowedOverRoaming(true); + } + + downloadId = downloadManager.enqueue(request); + Toast.makeText(this, "开始下载...", Toast.LENGTH_SHORT).show(); + } + + private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1); + + if (downloadId == id) { + DownloadManager.Query query = new DownloadManager.Query(); + query.setFilterById(id); + + Cursor cursor = downloadManager.query(query); + if (cursor.moveToFirst()) { + int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)); + + if (status == DownloadManager.STATUS_SUCCESSFUL) { + String localUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)); + installApk(Uri.parse(localUri).getPath()); + } else { + int reason = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_REASON)); + Toast.makeText(context, "下载失败,错误码: " + reason, Toast.LENGTH_SHORT).show(); + } + } + cursor.close(); + } + } + }; + + private void installApk(String apkPath) { + File file = new File(apkPath); + if (!file.exists()) { + Toast.makeText(this, "APK文件不存在", Toast.LENGTH_SHORT).show(); + return; + } + + Intent intent = new Intent(Intent.ACTION_VIEW); + Uri uri; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + uri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", file); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + } else { + uri = Uri.fromFile(file); + } + + intent.setDataAndType(uri, "application/vnd.android.package-archive"); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + try { + startActivity(intent); + } catch (Exception e) { + Toast.makeText(this, "无法安装应用: " + e.getMessage(), Toast.LENGTH_LONG).show(); + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + unregisterReceiver(onDownloadComplete); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 1001) { + if (resultCode == RESULT_OK) { + Toast.makeText(this, "已获得安装未知应用权限", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(this, "未获得安装未知应用权限,无法自动安装", Toast.LENGTH_LONG).show(); + } + } + } +} diff --git a/app/src/main/java/com/example/tyre/TestActivity.java b/app/src/main/java/com/example/tyre/TestActivity.java index 5778ee5..8fd09a2 100644 --- a/app/src/main/java/com/example/tyre/TestActivity.java +++ b/app/src/main/java/com/example/tyre/TestActivity.java @@ -85,7 +85,7 @@ public class TestActivity extends AppCompatActivity { private KeyReceiver keyReceiver; private String deptId; String min = "EC0001012026010100000001"; // 左边界(包含) - String max = "EC00010120260101001000000"; // 右边界(包含) + String max = "EC0001012026010100100000"; // 右边界(包含) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); diff --git a/app/src/main/java/com/example/tyre/TyreLayoutActivity.java b/app/src/main/java/com/example/tyre/TyreLayoutActivity.java new file mode 100644 index 0000000..6c1877a --- /dev/null +++ b/app/src/main/java/com/example/tyre/TyreLayoutActivity.java @@ -0,0 +1,507 @@ +package com.example.tyre; + +import androidx.appcompat.app.AppCompatActivity; + +import android.app.ProgressDialog; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.os.SystemClock; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.view.KeyEvent; +import android.view.View; +import android.widget.Button; +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.BaseCar; +import com.example.tyre.entity.BaseTyre; +import com.example.tyre.entity.EPC; +import com.example.tyre.util.CarSelectionDialog; +import com.example.tyre.util.CommonDialog; +import com.example.tyre.util.MyUrl; +import com.example.tyre.util.SharedPreferencesUtils; +import com.example.tyre.util.Util; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; +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.util.ArrayList; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnClick; +import cn.pda.serialport.Tools; + +public class TyreLayoutActivity extends AppCompatActivity { + + // 1. 使用 @BindView 绑定控件 + // 注意:变量名可以自定义,但 ID 必须对应 XML 中的 id + @BindView(R.id.et_plate_number) + TextInputEditText etPlateNumber; + + @BindView(R.id.btn_retrieve) + Button btnRetrieve; // 因为使用的是 MaterialButton,这里类型要对应 + + @BindView(R.id.til_plate_number) + TextInputLayout tilPlateNumber; + + private ProgressDialog progressDialog; + + private boolean isStart = true; + private boolean runFlag = true; + private boolean startFlag = false; + private UhfReader manager; // UHF manager,UHF Operating handle + private ArrayList listEPC; + private ArrayList listepc = new ArrayList(); + long lastTime; + long nextTime; + private Toast mToast; + private Toast toast; + private KeyReceiver keyReceiver; + String min = "EC0001012026010100000001"; // 左边界(包含) + String max = "EC0001012026010100100000"; // 右边界(包含) + // 1. 定义数据模型类 (对应后台返回的字段) + public static class TireData { + public String position; // 轮位名称 + public String brand; // 品牌 + public String spec; // 规格 + public String installDate; // 安装日期 + + public TireData(String position, String brand, String spec, String installDate) { + this.position = position; + this.brand = brand; + this.spec = spec; + this.installDate = installDate; + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_tyre_layout); + ButterKnife.bind(this); + manager = MyApplication.getManager(); + listEPC = new ArrayList(); + Thread thread = new InventoryThread(); + thread.start(); + Util.initSoundPool(this); + tilPlateNumber = findViewById(R.id.til_plate_number); + etPlateNumber.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) {} + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + // 核心代码:只要用户输入了内容,就清除错误提示 + tilPlateNumber.setError(null); + + // 可选:如果你使用了 errorEnabled="true",可能还需要调用下面这行来彻底清除空间占用 + // tilPlateNumber.setErrorEnabled(false); + } + }); + tilPlateNumber.setEndIconOnClickListener(v -> { + // 在这里处理搜索逻辑 + String plateNumber = etPlateNumber.getText().toString().trim(); + if (!plateNumber.isEmpty()) { + // 执行搜索 + showLoadingDialog(); + performSearch(plateNumber); + } else { + tilPlateNumber.setError("车牌号不能为空"); + } + }); + } + @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(); + } + private void performSearch(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) { + // 处理选中的车辆 + etPlateNumber.setText(carNo); + } + }); + dialog.show(); + } + @OnClick({R.id.btn_retrieve}) + public void onViewClicked(View view) { + String PlateNumber = etPlateNumber.getText().toString(); + switch (view.getId()) { + case R.id.btn_retrieve: + if (PlateNumber == null || PlateNumber.isEmpty()) + { + new CommonDialog(TyreLayoutActivity.this).setMessage("请输入车牌号!").show(); + return; + } + carBangding(PlateNumber); + break; + } + } + //绑定车牌与RFID信息 + private void carBangding(String PlateNumber) { + OkGo.post(MyUrl.url + "/tyre/tyre/getCarBingTire") + .tag(this).params("carNo", PlateNumber) + .execute(new StringCallback() { + @Override + public void onSuccess(Response response) { + //hideLoadingDialog(); + String body = response.body(); + Gson gson=new Gson(); +// List baseTyreList = gson.fromJson(body, BaseTyre.class); + List baseTyreList = gson.fromJson(body, new com.google.gson.reflect.TypeToken>(){}.getType()); + bindDataToViews(baseTyreList); + } + }); + } + 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()); + etPlateNumber.setText(carNo); + }else { + new CommonDialog(TyreLayoutActivity.this).setMessage("请检查车辆芯片绑定数据!").show(); + } + } catch (JsonSyntaxException e) { + return; + } + } + }); + } + private String safeGetString(String value) { + return value == null || "null".equals(value) ? "" : value; + } + /** + * 核心方法:将数据绑定到具体的 Include 视图上 + */ + private void bindDataToViews(List dataList) { + if (dataList == null) return; + + // 遍历列表,根据具体位置找到对应的 View + for (BaseTyre tyre : dataList) { + View targetView = null; + + // 根据后端返回的位置字段判断要更新哪个布局 + // 假设 tyre.getPosition() 返回 "LF" (左前), "RF" (右前) 等 + String pos = tyre.getWheelPostion(); + + if ("左前轮".equals(pos) || "1".equals(pos)) { + targetView = findViewById(R.id.tire_left_front); + } else if ("右前轮".equals(pos) || "2".equals(pos)) { + targetView = findViewById(R.id.tire_right_front); + } else if ("左内轮".equals(pos)) { + targetView = findViewById(R.id.tire_middle_left); + }else if ("右内轮".equals(pos)) { + targetView = findViewById(R.id.tire_middle_right); + }else if ("左外轮".equals(pos)) { + targetView = findViewById(R.id.tire_bottom_left); + }else if ("右外轮".equals(pos)) { + targetView = findViewById(R.id.tire_bottom_right); + } + // ... 其他位置 + + if (targetView != null) { + updateTireView(targetView, tyre); + } + } + } +// private void bindDataToViews(List dataList) { +// // 假设 dataList.get(0) 是左前轮,dataList.get(1) 是右前轮... +// // 请根据你实际的列表顺序调整索引 +// +// if (dataList.size() >= 2) { +// // 绑定左前轮 +// updateTireView(findViewById(R.id.tire_left_front), dataList.get(0)); +// +// // 绑定右前轮 +// updateTireView(findViewById(R.id.tire_right_front), dataList.get(1)); +// +// // 绑定其他轮胎... +// // updateTireView(findViewById(R.id.tire_left_mid), dataList.get(2)); +// } +// } + + /** + * 通用方法:更新单个轮胎卡片的 UI + * @param container include 标签对应的根布局 View + * @param data 该轮胎的数据对象 + */ + private void updateTireView(View container, BaseTyre data) { + if (container == null) return; + + // 【关键点】:必须在 container 内部查找控件,而不是在 Activity 中直接查找 + TextView tvBrand = container.findViewById(R.id.tv_brand); + TextView tvSpec = container.findViewById(R.id.tv_spec); + TextView tvSelfNo = container.findViewById(R.id.tv_self_no); // 或者是 tv_install_date + TextView tvDate = container.findViewById(R.id.tv_install_date); // 或者是 tv_install_date + // 设置数据 + if (tvBrand != null) tvBrand.setText("品牌: " + data.getTyreBrand()); + if (tvSpec != null) tvSpec.setText("规格: " + data.getTyreModel()); + if (tvSelfNo != null) tvSelfNo.setText("自编号: " + data.getSelfNo()); + if (tvDate != null) tvDate.setText("日期: " + data.getCreateTime()); + } + + 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); + + }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); + } + } + } + + // 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); + //请求后台 + debounceHandler.removeMessages(1); + lastScannedEpc = currentEpc; + debounceHandler.sendEmptyMessageDelayed(1, DEBOUNCE_DELAY); + } + + } + clearData(); + } + }); + Log.e("EPC", "listepc:+ " + listepc); + } + /** + * 判断字符串是否在指定的区间内(包含边界) + * @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 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(); + + //查询车辆数据方法 + findCar(lastScannedEpc); + lastScannedEpc = null; // 清空,等待下一次扫描 + } + return true; + } + }); + private void clearData() { + listEPC.removeAll(listEPC); + listepc.removeAll(listepc); + } + + 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); + } + + 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 = ""; +// 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); + } + + } + } + tagList = null; + try { + Thread.sleep(20); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + } + } + + private void showLoadingDialog() { + progressDialog = new ProgressDialog(this); + progressDialog.setMessage("数据加载中..."); + progressDialog.setCancelable(false); + 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/UpActivity.java b/app/src/main/java/com/example/tyre/UpActivity.java index 483e640..8007222 100644 --- a/app/src/main/java/com/example/tyre/UpActivity.java +++ b/app/src/main/java/com/example/tyre/UpActivity.java @@ -90,7 +90,8 @@ public class UpActivity extends AppCompatActivity implements AdapterView.OnItemS private Toast mToast; private Toast toast; private KeyReceiver keyReceiver; - + String min = "EC0001012026010100000001"; // 左边界(包含) + String max = "EC0001012026010100100000"; // 右边界(包含) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -217,17 +218,70 @@ public class UpActivity extends AppCompatActivity implements AdapterView.OnItemS 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); + } + debounceHandler.removeMessages(1); + lastScannedEpc = currentEpc; + debounceHandler.sendEmptyMessageDelayed(1, DEBOUNCE_DELAY); + } + + clearData(); } }); Log.e("EPC", "listepc:+ " + listepc); - if (listepc != null && !listepc.isEmpty()){ - startFlag = false; - EPC.setText(listepc.get(0).toString()); - //请求后台 - find(listepc.get(0).toString()); - } - clearData(); } + /** + * 判断字符串是否在指定的区间内(包含边界) + * @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 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; // 清空,等待下一次扫描 + } + return true; + } + }); private void clearData() { listEPC.removeAll(listEPC); listepc.removeAll(listepc); @@ -356,11 +410,35 @@ public class UpActivity extends AppCompatActivity implements AdapterView.OnItemS } } // 基本信息查询 + 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); diff --git a/app/src/main/java/com/example/tyre/entity/BaseTyre.java b/app/src/main/java/com/example/tyre/entity/BaseTyre.java index 7bf2582..fa00b22 100644 --- a/app/src/main/java/com/example/tyre/entity/BaseTyre.java +++ b/app/src/main/java/com/example/tyre/entity/BaseTyre.java @@ -1,6 +1,7 @@ package com.example.tyre.entity; +import java.util.Date; /** * 轮胎基础信息对象 base_tyre @@ -47,6 +48,16 @@ public class BaseTyre private String wheelPostion; + private String createTime; + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + public String getSelfNo() { return selfNo; } diff --git a/app/src/main/java/com/example/tyre/entity/CheckInfoSpinnerVo.java b/app/src/main/java/com/example/tyre/entity/CheckInfoSpinnerVo.java new file mode 100644 index 0000000..e088b1a --- /dev/null +++ b/app/src/main/java/com/example/tyre/entity/CheckInfoSpinnerVo.java @@ -0,0 +1,24 @@ +package com.example.tyre.entity; + +import java.util.List; + +public class CheckInfoSpinnerVo { + private List checkResultList; + private List checkTypeList; + + public List getCheckResultList() { + return checkResultList; + } + + public void setCheckResultList(List checkResultList) { + this.checkResultList = checkResultList; + } + + public List getCheckTypeList() { + return checkTypeList; + } + + public void setCheckTypeList(List checkTypeList) { + this.checkTypeList = checkTypeList; + } +} 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 50c9ec9..675c91c 100644 --- a/app/src/main/java/com/example/tyre/entity/InStoreSpinnerVo.java +++ b/app/src/main/java/com/example/tyre/entity/InStoreSpinnerVo.java @@ -8,6 +8,15 @@ public class InStoreSpinnerVo { private List levelList; private List patternList; private List kindList; + private List gctsList; + + public List getGctsList() { + return gctsList; + } + + public void setGctsList(List gctsList) { + this.gctsList = gctsList; + } public List getTyreBrandList() { return tyreBrandList; 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 b668167..23cea64 100644 --- a/app/src/main/java/com/example/tyre/util/MyUrl.java +++ b/app/src/main/java/com/example/tyre/util/MyUrl.java @@ -6,7 +6,7 @@ package com.example.tyre.util; * @date: 2019-10-24 13:59 */ public class MyUrl { - public static String url="http://10.11.187.77:8020"; -// public static String url="http://www.qdhys.xyz:8020"; -// public static String url="http://192.168.0.102:8020"; +// 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"; } diff --git a/app/src/main/res/drawable/bg_tire_circl.xml b/app/src/main/res/drawable/bg_tire_circl.xml new file mode 100644 index 0000000..4390073 --- /dev/null +++ b/app/src/main/res/drawable/bg_tire_circl.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tire_background.xml b/app/src/main/res/drawable/tire_background.xml new file mode 100644 index 0000000..a6b40fb --- /dev/null +++ b/app/src/main/res/drawable/tire_background.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/tire_image.png b/app/src/main/res/drawable/tire_image.png new file mode 100644 index 0000000..31dcf15 Binary files /dev/null and b/app/src/main/res/drawable/tire_image.png differ diff --git a/app/src/main/res/drawable/tire_side_view.png b/app/src/main/res/drawable/tire_side_view.png new file mode 100644 index 0000000..e0f23a4 Binary files /dev/null and b/app/src/main/res/drawable/tire_side_view.png differ diff --git a/app/src/main/res/layout/activity_check.xml b/app/src/main/res/layout/activity_check.xml index e4e7a10..4e3e3e5 100644 --- a/app/src/main/res/layout/activity_check.xml +++ b/app/src/main/res/layout/activity_check.xml @@ -1,234 +1,284 @@ - - + android:layout_height="match_parent" + android:background="#F5F5F5"> + - + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="16dp"> - + - - - - - - - - - - - - - - - - - - - - - - android:textColor="@color/black" - android:textSize="22sp" - android:inputType="textMultiLine" - android:minLines="3" - android:lines="5" - android:gravity="top|start" - android:padding="8dp" - android:scrollbars="vertical" - android:hint="请输入内容" - /> + + + + + + + + + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +