Pārlūkot izejas kodu

Merge branch 'master' of lhm/ich-android into master

李慧明 3 gadi atpakaļ
vecāks
revīzija
4cc8f6bb6f
57 mainītis faili ar 947 papildinājumiem un 457 dzēšanām
  1. 4 2
      app/build.gradle
  2. 12 0
      app/src/main/assets/update_test.json
  3. 63 99
      app/src/main/java/com/emato/ich/MainActivity.java
  4. 7 0
      app/src/main/java/com/emato/ich/api/ICSPClient.java
  5. 3 1
      app/src/main/java/com/emato/ich/api/ICSPResponseCodeEnum.java
  6. 19 0
      app/src/main/java/com/emato/ich/contant/ScanGunConstant.java
  7. 26 14
      app/src/main/java/com/emato/ich/crash/CrashApplication.java
  8. 6 13
      app/src/main/java/com/emato/ich/crash/UncaughtExceptionHandlerImpl.java
  9. 2 0
      app/src/main/java/com/emato/ich/device/DeviceControl.java
  10. 15 2
      app/src/main/java/com/emato/ich/fragment/ChooseCabinetFragment.java
  11. 127 103
      app/src/main/java/com/emato/ich/fragment/ExceptionFragment.java
  12. 56 18
      app/src/main/java/com/emato/ich/fragment/InputInfoFragment.java
  13. 3 0
      app/src/main/java/com/emato/ich/fragment/MainFragment.java
  14. 8 0
      app/src/main/java/com/emato/ich/fragment/SendFragment.java
  15. 79 16
      app/src/main/java/com/emato/ich/fragment/SendInfoConfirmFragment.java
  16. 3 0
      app/src/main/java/com/emato/ich/fragment/SendMainFragment.java
  17. 2 0
      app/src/main/java/com/emato/ich/fragment/SendSuccessFragment.java
  18. 9 1
      app/src/main/java/com/emato/ich/fragment/TakeCodeFragment.java
  19. 4 0
      app/src/main/java/com/emato/ich/fragment/TakeFragment.java
  20. 10 2
      app/src/main/java/com/emato/ich/fragment/TakeSuccessFragment.java
  21. 7 13
      app/src/main/java/com/emato/ich/message/ICHPublishClient.java
  22. 9 3
      app/src/main/java/com/emato/ich/message/ICHSubscribeClient.java
  23. 1 1
      app/src/main/java/com/emato/ich/message/ICHTopic.java
  24. 35 0
      app/src/main/java/com/emato/ich/update/CustomUpdateConfigProvider.java
  25. 19 3
      app/src/main/java/com/emato/ich/update/InstallResultReceiver.java
  26. 4 1
      app/src/main/java/com/emato/ich/update/PackageManagerCompat.java
  27. 2 0
      app/src/main/java/com/emato/ich/utils/BaseUtils.java
  28. 4 0
      app/src/main/java/com/emato/ich/utils/FileUtils.java
  29. 28 0
      app/src/main/java/com/emato/ich/utils/LoggingUtils.java
  30. 57 0
      app/src/main/java/com/emato/ich/utils/ResourceUtils.java
  31. 32 0
      app/src/main/java/com/emato/ich/utils/WaitingDialogUtils.java
  32. BIN
      app/src/main/res/drawable/exception.png
  33. 12 0
      app/src/main/res/drawable/exception_button.xml
  34. BIN
      app/src/main/res/drawable/fast_send.png
  35. BIN
      app/src/main/res/drawable/large.png
  36. BIN
      app/src/main/res/drawable/medium.png
  37. BIN
      app/src/main/res/drawable/mini.png
  38. BIN
      app/src/main/res/drawable/return1.png
  39. BIN
      app/src/main/res/drawable/return_main.png
  40. BIN
      app/src/main/res/drawable/send.png
  41. BIN
      app/src/main/res/drawable/small.png
  42. BIN
      app/src/main/res/drawable/take.png
  43. 17 20
      app/src/main/res/layout/fragment_choose_cabinet.xml
  44. 84 21
      app/src/main/res/layout/fragment_exception.xml
  45. 7 9
      app/src/main/res/layout/fragment_input_info.xml
  46. 51 31
      app/src/main/res/layout/fragment_main.xml
  47. 7 9
      app/src/main/res/layout/fragment_send.xml
  48. 6 9
      app/src/main/res/layout/fragment_send_info_confirm.xml
  49. 13 20
      app/src/main/res/layout/fragment_send_main.xml
  50. 6 9
      app/src/main/res/layout/fragment_send_success.xml
  51. 5 8
      app/src/main/res/layout/fragment_take.xml
  52. 7 9
      app/src/main/res/layout/fragment_take_code.xml
  53. 6 9
      app/src/main/res/layout/fragment_take_success.xml
  54. 43 3
      app/src/main/res/values-night/themes.xml
  55. 16 5
      app/src/main/res/values/colors.xml
  56. 3 2
      app/src/main/res/values/strings.xml
  57. 8 1
      app/src/main/res/values/themes.xml

+ 4 - 2
app/build.gradle

@@ -48,13 +48,15 @@ dependencies {
     implementation 'com.fasterxml.jackson.core:jackson-annotations:2.10.5'
     implementation 'com.fasterxml.jackson.core:jackson-core:2.10.5'
     implementation 'com.fasterxml.jackson.core:jackson-databind:2.10.5'
-    implementation 'com.squareup.okhttp3:okhttp:4.0.1'
+    implementation 'com.squareup.okhttp3:okhttp:4.4.0'
     implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
     implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
     implementation "org.permissionsdispatcher:permissionsdispatcher:4.3.1"//权限
     annotationProcessor "org.permissionsdispatcher:permissionsdispatcher-processor:4.3.1"//权限
     implementation 'com.github.xuexiangjys:XUpdate:2.0.7'
-    implementation 'com.google.code.gson:gson:2.8.5'
+    implementation 'com.github.xuexiangjys.XUpdateAPI:xupdate-downloader-aria:1.0.0'
+    implementation 'com.google.code.gson:gson:2.8.6'
+    implementation 'com.github.xuexiangjys.XUpdateAPI:xupdate-easy:1.0.0'
     implementation 'com.zhy:okhttputils:2.6.2'
 
     testImplementation 'junit:junit:4.12'

+ 12 - 0
app/src/main/assets/update_test.json

@@ -0,0 +1,12 @@
+{
+  "Code": 0,
+  "Msg": "",
+  "UpdateStatus": 1,
+  "VersionCode": 3,
+  "VersionName": "1.0.2",
+  "UploadTime": "2018-07-10 17:28:41",
+  "ModifyContent": "111111",
+  "DownloadUrl": "http://icsp-testend.ds-bay.com/profile/app-release.apk",
+  "ApkSize": 2048,
+  "ApkMd5": "560017dc94e8f9b65f4ca997c7feb326"
+}

+ 63 - 99
app/src/main/java/com/emato/ich/MainActivity.java

@@ -15,11 +15,14 @@ import com.emato.ich.entity.vo.ResponseData;
 import com.emato.ich.entity.vo.ShellVo;
 import com.emato.ich.local.LocalStorage;
 import com.emato.ich.message.ICHPublishClient;
+import com.emato.ich.message.ICHSubscribeClient;
 import com.emato.ich.message.ICHTopic;
 import com.emato.ich.update.APKUpdateDownload;
 import com.emato.ich.update.OnDownloadListener;
 import com.emato.ich.utils.BaseUtils;
 import com.emato.ich.utils.JacksonUtils;
+import com.emato.ich.utils.LoggingUtils;
+import com.emato.ich.utils.ResourceUtils;
 import com.emato.ich.utils.StringUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
@@ -27,6 +30,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 
 import androidx.appcompat.app.AppCompatActivity;
 
+import android.provider.SyncStateContract;
 import android.util.Log;
 import android.view.KeyEvent;
 
@@ -37,6 +41,12 @@ import androidx.navigation.ui.NavigationUI;
 
 import com.emato.ich.databinding.ActivityMainBinding;
 import com.xuexiang.xupdate.XUpdate;
+import com.xuexiang.xupdate.aria.AriaDownloadServiceProxyImpl;
+import com.xuexiang.xupdate.aria.AriaDownloader;
+import com.xuexiang.xupdate.easy.EasyUpdate;
+import com.xuexiang.xupdate.easy.config.UpdateConfig;
+import com.xuexiang.xupdate.entity.UpdateEntity;
+import com.xuexiang.xupdate.proxy.impl.DefaultUpdateParser;
 
 import android.view.Menu;
 import android.view.MenuItem;
@@ -85,20 +95,21 @@ public class MainActivity extends AppCompatActivity  {
         getSystemConfig();
 
         ICHPublishClient ichPublishClient = ICHPublishClient.getInstance();
+        ICHSubscribeClient ichSubscribeClient = ICHSubscribeClient.getInstance();
 
         ICHTopic.CLIENT_ID = BaseUtils.getClientId();
         // 订阅主题
 //        ICHSubscribeClient ichSubscribeClient = ICHSubscribeClient.getInstance();
-        openLocker(ichPublishClient);
+        openLocker(ichSubscribeClient, ichPublishClient);
 
         // 注册柜子信息
         cabinetInfoReport(ichPublishClient);
 
         // TODO 更新版本监听
-        autoUpdateVersion(ichPublishClient);
+        autoUpdateVersion(ichSubscribeClient);
 
         // TODO 监听shell命令脚本
-        executeShell(ichPublishClient);
+        executeShell(ichSubscribeClient, ichPublishClient);
     }
 
     private void getSystemConfig(){
@@ -106,6 +117,7 @@ public class MainActivity extends AppCompatActivity  {
             @Override
             public void onFailure(@NotNull Call call, @NotNull IOException e) {
                 Log.e(TAG, "onFailure: 获取系统配置错误! 网络错误! ", e);
+                LoggingUtils.sendErrorLog("业务异常: 获取系统配置错误! 网络错误!  ", e);
             }
 
             @Override
@@ -113,23 +125,6 @@ public class MainActivity extends AppCompatActivity  {
                     (@NotNull Call call, @NotNull Response response) throws IOException {
 
                 try {
-                    OnDownloadListener listener = new OnDownloadListener() {
-
-                        @Override
-                        public void onDownloadSuccess(File file) {
-
-                        }
-
-                        @Override
-                        public void onDownloading(int progress) {
-
-                        }
-
-                        @Override
-                        public void onDownloadFailed(Exception e) {
-
-                        }
-                    };
                     String parseResponse = ICSPClient.isSuccessfulAndParseResponse(response);
                     ObjectMapper objectMapper = JacksonUtils.objectmapper;
                     ResponseData<Map<String, String>> readValue = objectMapper.readValue(parseResponse, new TypeReference<ResponseData<Map<String, String>>>() {
@@ -141,68 +136,8 @@ public class MainActivity extends AppCompatActivity  {
                         if (!StringUtils.isNullOrEmpty(time)) {
                             LocalStorage.getInstance().getSession().setTime(Long.parseLong(time));
                         }
-                        String qrcode_url = configMap.get(SystemConfigConstant.cabinet_take_object_qrcode_url);
-
-                        try {
-                            ICSPClient.download(qrcode_url, new Callback() {
-                                @Override
-                                public void onFailure(@NotNull Call call, @NotNull IOException e) {
-
-                                }
-
-                                @Override
-                                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
-                                    InputStream is = null;
-                                    byte[] buf = new byte[2048];
-                                    int len = 0;
-                                    FileOutputStream fos = null;
-                                    final String destFileDir = "res/drawable/";
-                                    String destFileName = "e_mp_qrcode_8x8.jpg";
-                                    //储存下载文件的目录
-                                    File dir = new File(getApplication().getFilesDir().getAbsolutePath() + "/" +destFileDir);
-                                    if (!dir.exists()) {
-                                        dir.mkdirs();
-                                    }
-//                destFileName = apk_url.substring(apk_url.lastIndexOf('/'), apk_url.length() - 1);
-                                    File file = new File(dir, destFileName);
-
-                                    try {
-
-                                        is = response.body().byteStream();
-                                        long total = response.body().contentLength();
-                                        fos = new FileOutputStream(file);
-                                        long sum = 0;
-                                        while ((len = is.read(buf)) != -1) {
-                                            fos.write(buf, 0, len);
-                                            sum += len;
-                                            int progress = (int) (sum * 1.0f / total * 100);
-                                            //下载中更新进度条
-                                            listener.onDownloading(progress);
-                                        }
-                                        fos.flush();
-                                        //下载完成
-                                        listener.onDownloadSuccess(file);
-                                    } catch (Exception e) {
-                                        listener.onDownloadFailed(e);
-                                    }finally {
-                                        try {
-                                            if (is != null) {
-                                                is.close();
-                                            }
-                                            if (fos != null) {
-                                                fos.close();
-                                            }
-                                        } catch (IOException e) {
-
-                                        }
-
-                                    }
-                                }
-                            }, listener);
-                        } catch (Exception e) {
 
-                        }
-                        Log.i(TAG, "onResponse: 获取系统配置成功! ");
+                        Log.i(TAG, "onResponse: =====================>获取系统配置成功! ");
                     } else {
                         Log.w(TAG, "onResponse: code==>" + readValue.getCode() + ", msg==>" + readValue.getMsg());
                     }
@@ -213,32 +148,51 @@ public class MainActivity extends AppCompatActivity  {
         });
     }
 
-    private void autoUpdateVersion(ICHPublishClient ichPublishClient) {
-        ichPublishClient.subscribe(String.format(ICHTopic.APK_UPDATE_PATH, BaseUtils.getClientId()), (msgId, msg) -> {
+    private void autoUpdateVersion(ICHSubscribeClient ichSubscribeClient) {
+        ichSubscribeClient.subscribe(String.format(ICHTopic.APK_UPDATE_PATH, BaseUtils.getClientId()), (msgId, msg) -> {
             try {
-                // String path = new String(msg.getPayload());
+//                 String path = new String(msg.getPayload());
                 // 发起请求下载APK
-                XUpdate.newBuild(this)
-                        .updateUrl(ICSPApi.GET_UPDATE_PATH.getUrl())
-                        .isAutoMode(true) // 如果需要完全无人干预,自动更新,需要root权限【静默安装需要】
+                Log.i(TAG, "autoUpdateVersion: =====================>接收到服务器发来更新指令! 开始更新! ");
+                UpdateConfig updateConfig = EasyUpdate.getUpdateConfig(getApplication());
+                EasyUpdate.create(getBaseContext(), ICSPApi.GET_UPDATE_PATH.getUrl())
+                        .updateHttpService(AriaDownloader.getUpdateHttpService(getApplication()))
+                        .build()
                         .update();
-                Log.i(TAG, "autoUpdateVersion: ====================================>更新完成! ");
+
+//                XUpdate.newBuild(this)
+//                        .updateUrl(ICSPApi.GET_UPDATE_PATH.getUrl())
+//                        .isAutoMode(true) // 如果需要完全无人干预,自动更新,需要root权限【静默安装需要】
+//                        .update();
+                Log.i(TAG, "autoUpdateVersion: ====================================>更新中! ");
 //                APKUpdateDownload.getInstance().downloadAPK(MainActivity.this, getApplication(), path);
             }  catch (Exception e) {
-                Log.e(TAG, "onCreate: 更新版本监听失败! ", e);
+                Log.e(TAG, "onCreate: =====================>更新版本监听失败! ", e);
+                LoggingUtils.sendErrorLog("业务异常: 更新版本监听失败! ", e);
             }
         });
     }
 
-    private void executeShell(ICHPublishClient ichPublishClient){
-        ichPublishClient.subscribe(String.format(ICHTopic.EXECUTE_SHELL_SCRIPT, BaseUtils.getClientId()), (msgId, msg) -> {
+    private UpdateEntity getUpdateEntityFromAssets() {
+//        UpdateEntity updateEntity = new UpdateEntity();
+//        updateEntity.setVersionCode(3);
+//
+//
+
+        return new DefaultUpdateParser().parseJson(ResourceUtils.readStringFromAssert("update_test.json", getAssets()));
+    }
+
+    private void executeShell(ICHSubscribeClient ichSubscribeClient, ICHPublishClient ichPublishClient){
+        ichSubscribeClient.subscribe(String.format(ICHTopic.EXECUTE_SHELL_SCRIPT, BaseUtils.getClientId()), (msgId, msg) -> {
             if (msg != null) {
                 try {
                     ShellVo shellVo = JacksonUtils.objectmapper.readValue(msg.getPayload(), ShellVo.class);
                     ShellVo result = shellVo;
-                    if (shellVo != null && shellVo.getScript() != null && "".equals(shellVo.getScript()) && shellVo.getScript().length() > 0) {
+                    if (shellVo != null && shellVo.getScript() != null && !"".equals(shellVo.getScript()) && shellVo.getScript().length() > 0) {
+                        Log.i(TAG, "executeShell: =====================>接到服务端传来命令: " + shellVo.getScript() + ", 参数: " + shellVo.getArgs());
                         BaseUtils.executeShell(shellVo);
                     } else {
+                        Log.i(TAG, "executeShell: =====================>接到服务端传来空命令, 不执行! ");
                         result = new ShellVo();
                         result.setResult("命令为空, 不可执行!");
                     }
@@ -246,19 +200,22 @@ public class MainActivity extends AppCompatActivity  {
                     mqttMessage.setQos(1);
                     mqttMessage.setPayload(JacksonUtils.objectmapper.writeValueAsString(result).getBytes());
                     ichPublishClient.publish(String.format(ICHTopic.EXECUTE_SHELL_SCRIPT_RESPONSE, BaseUtils.getClientId()), mqttMessage);
+                    Log.i(TAG, "executeShell: =====================>发送命令执行结果成功! ");
                 } catch (Exception e) {
                     Log.e(TAG, "onCreate: 发送执行脚本结果失败! ", e);
+                    LoggingUtils.sendErrorLog("业务异常: 发送执行脚本结果失败! ", e);
                 }
             }
         });
     }
 
-    private void openLocker(ICHPublishClient ichPublishClient) {
-        ichPublishClient.subscribe(ICHTopic.LOCK + BaseUtils.getClientId(), (s, msg) -> {
+    private void openLocker(ICHSubscribeClient ichSubscribeClient, ICHPublishClient ichPublishClient) {
+        ichSubscribeClient.subscribe(ICHTopic.LOCK + BaseUtils.getClientId(), (s, msg) -> {
             String payload = new String(msg.getPayload());
             ObjectMapper objectMapper = JacksonUtils.objectmapper;
             Message message = objectMapper.readValue(payload, Message.class);
             Log.i(TAG, "onCreate: message id: " + s + "--------------消息体: " + message);
+            Log.i(TAG, "openLocker: ==================>接到开锁消息: " + message);
 
             DeviceControl.unlockLocker(message.getSection(), message.getPort(), (var1, var2) -> {
                 Log.i(TAG, "onCreate: 开锁返回码: " + var1 + "--------------返回消息: " + Arrays.asList(var2));
@@ -267,14 +224,16 @@ public class MainActivity extends AppCompatActivity  {
                     try {
                         mqttMessage = wrapMessage(message, objectMapper);
                         ichPublishClient.publish(String.format(ICHTopic.CALLBACK_FAILED, BaseUtils.getClientId()), mqttMessage);
+                        Log.i(TAG, "openLocker: ==================>发送开锁失败消息成功! 锁板id: " + message.getSection() + ", 端口: " + message.getPort());
                     } catch (JsonProcessingException e) {
                         Log.e(TAG, "onCreate: ---------------------序列化开锁错误消息失败! ", e);
+                        LoggingUtils.sendErrorLog("业务异常: 序列化开锁错误消息失败! ", e);
                     } catch (Exception e) {
                         Log.e(TAG, "onCreate: ---------------------未知错误! ", e);
+                        LoggingUtils.sendErrorLog("业务异常: 序列化开锁未知错误! ", e);
                     }
                 } else {
                     // TODO 暂时不做 成功需要不断去请求查询锁是否关闭, 关闭后推送成功消息
-                    Log.i(TAG, "onCreate: -------------------------开锁成功");
 //                    AtomicBoolean atomicBoolean = new AtomicBoolean(true);
 //                    AtomicInteger atomicInteger = new AtomicInteger(5);
 //                    do {
@@ -295,6 +254,7 @@ public class MainActivity extends AppCompatActivity  {
 //                        }
 //                    } while(atomicBoolean.get());
                     try {
+                        Log.i(TAG, "onCreate: =====================>开锁成功! 锁板id: " + message.getSection() + ", 端口: " + message.getPort());
                         mqttMessage = wrapMessage(message, objectMapper);
 //                        if (atomicInteger.get() <= 0) {
 //                            message.setCause("长时间未关闭柜门!");
@@ -305,8 +265,10 @@ public class MainActivity extends AppCompatActivity  {
                         ichPublishClient.publish(String.format(ICHTopic.CALLBACK_SUCCESS, BaseUtils.getClientId()), mqttMessage);
                     } catch (JsonProcessingException e) {
                         Log.e(TAG, "onCreate: ---------------------序列化开锁成功消息失败! ", e);
+                        LoggingUtils.sendErrorLog("业务异常: 序列化开锁成功消息失败! ", e);
                     } catch (RuntimeException e) {
-                        Log.e(TAG, "onCreate: ---------------------未知错误! ", e);
+                        Log.e(TAG, "onCreate: ---------------------序列化开锁成功消息未知错误! ", e);
+                        LoggingUtils.sendErrorLog("业务异常: 开锁未知错误! ", e);
                     }
                 }
             });
@@ -332,10 +294,10 @@ public class MainActivity extends AppCompatActivity  {
         cabinet.setImei(BaseUtils.getIMEI(getApplicationContext()));
         cabinet.setMacIpv4(BaseUtils.getIp());
         cabinet.setMacIpv6("unknown");
-        cabinet.setNetType("111");
+        cabinet.setNetType("unknown");
         cabinet.setPlatType("S905");
-        cabinet.setSim("111");
-        cabinet.setWifiSSid("111");
+        cabinet.setSim("unknown");
+        cabinet.setWifiSSid("unknown");
 
         ObjectMapper objectMapper = JacksonUtils.objectmapper;
 
@@ -347,8 +309,10 @@ public class MainActivity extends AppCompatActivity  {
             message.setQos(1);
             message.setPayload(jsonData.getBytes());
             ichPublishClient.publish(String.format(ICHTopic.CABINET_INFO_REPORT, BaseUtils.getClientId()), message);
+            Log.i(TAG, "cabinetInfoReport: ===============>上报柜子信息成功! ");
         } catch (JsonProcessingException e) {
             Log.e(TAG, "onCreate: 解析成JSON失败!", e);
+            LoggingUtils.sendErrorLog("业务异常: 上报柜子信息时解析成JSON失败! ", e);
         }
     }
 

+ 7 - 0
app/src/main/java/com/emato/ich/api/ICSPClient.java

@@ -8,6 +8,7 @@ import com.emato.ich.entity.vo.TakeParcelVo;
 import com.emato.ich.update.OnDownloadListener;
 import com.emato.ich.utils.BaseUtils;
 import com.emato.ich.utils.JacksonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.StringUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -79,6 +80,7 @@ public class ICSPClient {
             requestBody = RequestBody.create(objectMapper.writeValueAsString(orderVo), mediaType);
         } catch (JsonProcessingException e) {
             Log.e(TAG, "preparedOrder: 构建预下单请求体错误!", e);
+            LoggingUtils.sendErrorLog("业务异常: 构建预下单请求体错误! ", e);
         }
 
         Request request = postRequest(ICSPApi.PREPARED_ORDER.getUrl(), requestBody, token);
@@ -101,6 +103,7 @@ public class ICSPClient {
             requestBody = RequestBody.create(objectMapper.writeValueAsString(confirmOrderVo), mediaType);
         } catch (JsonProcessingException e) {
             Log.e(TAG, "confirmOrder: 构建确认下单请求体错误!", e);
+            LoggingUtils.sendErrorLog("业务异常: 构建确认下单请求体错误! ", e);
         }
 
         Request request = postRequest(ICSPApi.DELIVERER_ORDER.getUrl(), requestBody, token);
@@ -124,6 +127,7 @@ public class ICSPClient {
             requestBody = RequestBody.create(objectMapper.writeValueAsString(takeParcelVo), mediaType);
         } catch (JsonProcessingException e) {
             Log.e(TAG, "takeParcel: 构建取件请求体错误!", e);
+            LoggingUtils.sendErrorLog("业务异常: 构建取件请求体错误! ", e);
         }
 
         Request request = postRequest(ICSPApi.TAKE_PARCEL.getUrl(), requestBody, token);
@@ -146,6 +150,7 @@ public class ICSPClient {
             requestBody = RequestBody.create("{\"clientId\": \"" + clientId + "\"}", mediaType);
         } catch (RuntimeException e) {
             Log.e(TAG, "takeParcel: 重开柜门未知错误! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 重开柜门未知错误! ", e);
         }
 
         Request request = postRequest(ICSPApi.GET_SYSTEM_CONFIG.getUrl(), requestBody, token);
@@ -197,6 +202,7 @@ public class ICSPClient {
             requestBody = RequestBody.create("{\"mailNo\": \"" + mailNo + "\"}", mediaType);
         } catch (RuntimeException e) {
             Log.e(TAG, "getUserPhoneNumber: 获取用户手机号异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 获取用户手机号异常! ", e);
         }
 
         Request request = postRequest(ICSPApi.GET_USER_PHONE_NUMBER.getUrl(), requestBody, token);
@@ -213,6 +219,7 @@ public class ICSPClient {
                 return Objects.requireNonNull(response.body()).string();
             } catch (IOException e) {
                 Log.e(TAG, "parseResponse: 解析响应信息失败!", e);
+                LoggingUtils.sendErrorLog("业务异常: 解析响应信息失败! ", e);
             }
         }
         return "";

+ 3 - 1
app/src/main/java/com/emato/ich/api/ICSPResponseCodeEnum.java

@@ -14,6 +14,7 @@ public enum ICSPResponseCodeEnum {
     OK("0", ""),
     SYSTEM_ERROR("50000", "系统异常"),
     FILED_VALID_FAILED("50001", "请输入正确的信息"),
+
     DELIVERER_AUTH("50003", "需要登录快递员操作才能操作"),
     CABINET_NOT_FOUND("50004", "机柜信息不存在"),
     DELIVERER_NOT_FOUND("50005", "投递员信息不存在"),
@@ -22,7 +23,8 @@ public enum ICSPResponseCodeEnum {
     PICK_UP_NOT_FOUND("50008", "取货码不存在"),
     MAIL_NO_NOT_FOUND("50010", "快递单号不存在"),
     MAIL_NO_QUERY_FAIL("50011", "获取快递信息失败"),
-    ORDER_CONFIRM_FAIL("50012", "已取消或关闭的订单无法确认完成")
+    ORDER_CONFIRM_FAIL("50012", "已取消或关闭的订单无法确认完成"),
+    PREPARED_ORDER_FAILED("50013", "该单号已投递,无法重复投递")
     ;
 
     public static void responseHint(Context context, ResponseData responseData){

+ 19 - 0
app/src/main/java/com/emato/ich/contant/ScanGunConstant.java

@@ -0,0 +1,19 @@
+package com.emato.ich.contant;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ScanGunConstant {
+
+    private static final List<String> patterns = new ArrayList<>();
+
+    private static final String protocol = "^[a-zA-Z0-9]+$";
+
+    static {
+        patterns.add(protocol);
+    }
+
+    public static List<String> getPatterns() {
+        return patterns;
+    }
+}

+ 26 - 14
app/src/main/java/com/emato/ich/crash/CrashApplication.java

@@ -2,6 +2,7 @@ package com.emato.ich.crash;
 
 import android.app.Activity;
 import android.app.Application;
+import android.content.Context;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -9,8 +10,12 @@ import androidx.appcompat.widget.TooltipCompat;
 
 import com.cherry.sdk.controller.BuildConfig;
 import com.emato.ich.MainActivity;
+import com.emato.ich.update.CustomUpdateConfigProvider;
 import com.emato.ich.update.UpdateService;
 import com.xuexiang.xupdate.XUpdate;
+import com.xuexiang.xupdate.aria.AriaDownloadServiceProxyImpl;
+import com.xuexiang.xupdate.easy.EasyUpdate;
+import com.xuexiang.xupdate.easy.config.UpdateConfig;
 import com.xuexiang.xupdate.entity.UpdateError;
 import com.xuexiang.xupdate.listener.OnUpdateFailureListener;
 import com.xuexiang.xupdate.proxy.IUpdateHttpService;
@@ -25,26 +30,33 @@ import java.util.Map;
 public class CrashApplication extends Application {
     private final List<Activity> mActivityList = new ArrayList<>();
     private static final String TAG = CrashApplication.class.getName();
+    CustomUpdateConfigProvider provider = new CustomUpdateConfigProvider();
+    @Override
+    protected void attachBaseContext(Context base) {
+
+        // XUpdate自定义配置
+        EasyUpdate.setUpdateConfigProvider(provider);
+        super.attachBaseContext(base);
+    }
 
     @Override
     public void onCreate() {
         super.onCreate();
         UncaughtExceptionHandlerImpl.getInstance().init(getApplicationContext(), BuildConfig.DEBUG, true, 1000, MainActivity.class);
 
-        //设置版本更新出错的监听
-        XUpdate.get()
-                .debug(true)
-                .isWifiOnly(false)                                               //默认设置只在wifi下检查版本更新
-                .isGet(false)                                                    //默认设置使用get请求检查版本
-                .isAutoMode(true)                                              //默认设置非自动模式,可根据具体使用配置
-                .param("versionCode", UpdateUtils.getVersionCode(this))         //设置默认公共请求参数
-                .param("appKey", getPackageName())
-                .setOnUpdateFailureListener(error -> {
-                    Log.i(TAG, "onCreate: 自动更新失败! " + error.getCode());
-                })
-                .supportSilentInstall(true)                                     //设置是否支持静默安装,默认是true
-                .setIUpdateHttpService(new UpdateService())                     //这个必须设置!实现网络请求功能。
-                .init(this);                                                    //这个必须初始化
+//        XUpdate.get()
+//                .debug(true)
+//                .isWifiOnly(false)                                               //默认设置只在wifi下检查版本更新
+//                .isGet(false)                                                    //默认设置使用get请求检查版本
+//                .isAutoMode(true)                                              //默认设置非自动模式,可根据具体使用配置
+//                .param("versionCode", UpdateUtils.getVersionCode(this))         //设置默认公共请求参数
+//                .param("appKey", getPackageName())
+//                .setOnUpdateFailureListener(error -> {
+//                    Log.i(TAG, "onCreate: 自动更新失败! " + error.getCode());
+//                })
+//                .supportSilentInstall(true)                                     //设置是否支持静默安装,默认是true
+//                .setIUpdateHttpService(new UpdateService())                     //这个必须设置!实现网络请求功能。
+//                .init(this);                                                    //这个必须初始化
     }
 
     /**

+ 6 - 13
app/src/main/java/com/emato/ich/crash/UncaughtExceptionHandlerImpl.java

@@ -18,6 +18,7 @@ import com.emato.ich.MainActivity;
 import com.emato.ich.message.ICHPublishClient;
 import com.emato.ich.message.ICHTopic;
 import com.emato.ich.utils.BaseUtils;
+import com.emato.ich.utils.LoggingUtils;
 
 import org.eclipse.paho.client.mqttv3.MqttMessage;
 
@@ -78,11 +79,7 @@ public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHan
 
     @SuppressLint("WrongConstant")
     public void uncaughtException(Thread thread, Throwable ex) {
-        // TODO 发送异常信息
-        MqttMessage mqttMessage = new MqttMessage();
-        mqttMessage.setQos(1);
-        mqttMessage.setPayload(getStackTrace(ex).toByteArray());
-        ICHPublishClient.getInstance().publish(String.format(ICHTopic.ERROR_LOG_REPORT, BaseUtils.getClientId()), mqttMessage);
+        LoggingUtils.sendErrorLog("系统异常: 崩溃异常! ", ex);
 
         if (!this.handleException(ex) && this.mDefaultHandler != null) {
             this.mDefaultHandler.uncaughtException(thread, ex);
@@ -91,8 +88,7 @@ public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHan
                 Thread.sleep(1000L);
             } catch (InterruptedException var6) {
                 Log.e(TAG, "error 出现未知异常: ", var6);
-                mqttMessage.setPayload(getStackTrace(var6).toByteArray());
-                ICHPublishClient.getInstance().publish(String.format(ICHTopic.ERROR_LOG_REPORT, BaseUtils.getClientId()), mqttMessage);
+                LoggingUtils.sendErrorLog("系统异常: 线程中断异常! ", var6);
             }
 
             if (this.mIsRestartApp) {
@@ -108,12 +104,6 @@ public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHan
 
     }
 
-    private static ByteArrayOutputStream getStackTrace(Throwable t) {
-        ByteArrayOutputStream buf = new java.io.ByteArrayOutputStream();
-        t.printStackTrace(new java.io.PrintWriter(buf, true));
-        return buf;
-    }
-
     private boolean handleException(final Throwable ex) {
         if (ex == null) {
             return false;
@@ -163,6 +153,7 @@ public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHan
             }
         } catch (PackageManager.NameNotFoundException var9) {
             Log.e(TAG, "an error occured when collect package info", var9);
+            LoggingUtils.sendErrorLog("业务异常: an error occured when collect package info! ", var9);
         }
 
         Field[] fields = Build.class.getDeclaredFields();
@@ -178,6 +169,7 @@ public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHan
                 Log.d(TAG, field.getName() + " : " + field.get((Object)null));
             } catch (Exception var8) {
                 Log.e(TAG, "an error occured when collect crash info", var8);
+                LoggingUtils.sendErrorLog("业务异常: an error occured when collect crash info! ", var8);
             }
         }
 
@@ -226,6 +218,7 @@ public class UncaughtExceptionHandlerImpl implements Thread.UncaughtExceptionHan
             return fileName;
         } catch (Exception var14) {
             Log.e(TAG, "an error occured while writing file...", var14);
+            LoggingUtils.sendErrorLog("业务异常: an error occured while writing file... ", var14);
             return null;
         }
     }

+ 2 - 0
app/src/main/java/com/emato/ich/device/DeviceControl.java

@@ -7,6 +7,7 @@ import com.cherry.sdk.controller.MoternDeviceController;
 import com.cherry.sdk.controller.callback.CmdCallback;
 import com.emato.ich.entity.Cabinet;
 import com.emato.ich.utils.JacksonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -238,6 +239,7 @@ public class DeviceControl {
                     lockPlateInfos.add(lockPlateInfo);
                 } catch (JsonProcessingException e) {
                     Log.e(TAG, new Date() + "queryCabinetInfo: JSON转换对象失败!", e);
+                    LoggingUtils.sendErrorLog("业务异常: 查询柜子信息时JSON转换对象失败! ", e);
                 }
 
             }

+ 15 - 2
app/src/main/java/com/emato/ich/fragment/ChooseCabinetFragment.java

@@ -31,6 +31,7 @@ import com.emato.ich.local.LocalStorage;
 import com.emato.ich.utils.BaseUtils;
 import com.emato.ich.utils.ButtonUtils;
 import com.emato.ich.utils.JacksonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.StringUtils;
 import com.emato.ich.utils.TimeOutUtils;
 import com.emato.ich.utils.ToastUtils;
@@ -59,7 +60,7 @@ public class ChooseCabinetFragment extends Fragment {
             button.setEnabled(false);
         } else {
             button.setEnabled(true);
-            textView.setBackgroundColor(android.graphics.Color.parseColor("#44CE3B"));
+//            textView.setBackgroundColor(android.graphics.Color.parseColor("#44CE3B"));
         }
     }
 
@@ -83,6 +84,7 @@ public class ChooseCabinetFragment extends Fragment {
             timer.start();
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 倒计时出现异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 选择柜子类型页面倒计时出现异常! ", e);
         }
 
         // 获取柜子信息
@@ -92,6 +94,7 @@ public class ChooseCabinetFragment extends Fragment {
                 // TODO 获取柜子信息失败处理
                 ToastUtils.make(getContext(), "获取柜子信息失败!网络异常!");
                 Log.e(TAG, "onFailure: 获取柜子信息调用失败! call: " + call.timeout().toString(), e);
+                LoggingUtils.sendErrorLog("业务异常: 获取柜子信息调用失败! ", e);
             }
 
             @Override
@@ -140,11 +143,14 @@ public class ChooseCabinetFragment extends Fragment {
 
                             } catch (IOException e) {
                                 Log.e(TAG, "onCreateView: 获取柜子剩余信息响应信息解析失败!", e);
+                                LoggingUtils.sendErrorLog("业务异常: 获取柜子剩余信息响应信息解析失败! ", e);
                             } catch (RuntimeException e) {
                                 Log.e(TAG, "onResponse: ", e);
+                                LoggingUtils.sendErrorLog("业务异常: 获取柜子剩余信息未知错误! ", e);
                             }
                         } else {
                             ToastUtils.make(getContext(), "获取柜子剩余信息出错!请重新进入此页面!");
+                            LoggingUtils.sendErrorLog("业务异常: 获取柜子剩余信息出错!请重新进入此页面! ", null);
                         }
                     });
                 }
@@ -229,6 +235,7 @@ public class ChooseCabinetFragment extends Fragment {
                                 //
                                 ToastUtils.make(getContext(), "换柜子失败!网络异常!");
                                 Log.e(TAG, "onFailure: 大小不合适, 换柜子更新预下单失败! ", e);
+                                LoggingUtils.sendErrorLog("业务异常: 大小不合适, 换柜子更新预下单失败! ", e);
                             }
 
                             @Override
@@ -260,16 +267,21 @@ public class ChooseCabinetFragment extends Fragment {
                                                             .navigate(R.id.action_chooseCabinetFragment_to_sendInfoConfirmFragment);
                                                 } catch (RuntimeException e) {
                                                     Log.e(TAG, "onResponse: InputInfoFragment页面获取SendInfoConfirmFragment传值错误! ", e);
+                                                    LoggingUtils.sendErrorLog("业务异常: InputInfoFragment页面获取SendInfoConfirmFragment传值错误! ", e);
                                                 }
                                             }
                                         } else {
                                             ICSPResponseCodeEnum.responseHint(getContext(), responseData);
-                                            Log.e(TAG, "onResponse: ICSP返回码: " + responseData.getCode() + ", 返回信息: " + responseData.getMsg(), new RuntimeException("系统异常"));
+                                            RuntimeException exception = new RuntimeException("系统异常");
+                                            Log.e(TAG, "onResponse: ICSP返回码: " + responseData.getCode() + ", 返回信息: " + responseData.getMsg(), exception);
+                                            LoggingUtils.sendErrorLog("业务异常: ICSP返回码: " + responseData.getCode() + ", 返回信息: " + responseData.getMsg(), exception);
                                         }
                                     } catch (JsonProcessingException e) {
                                         Log.e(TAG, "onResponse: 预下单转换成JSON出错! ", e);
+                                        LoggingUtils.sendErrorLog("业务异常: 预下单转换成JSON出错! ", e);
                                     } catch (RuntimeException e) {
                                         Log.e(TAG, "onResponse: 换柜子错误! ", e);
+                                        LoggingUtils.sendErrorLog("业务异常: 换柜子错误! ", e);
                                     }
                                 });
                             }
@@ -286,6 +298,7 @@ public class ChooseCabinetFragment extends Fragment {
 
         } catch (RuntimeException | JsonProcessingException e) {
             Log.e(TAG, "onViewCreated: ChooseCabinetFragment向InputInfoFragment页面传值错误! ", e);
+            LoggingUtils.sendErrorLog("业务异常: ChooseCabinetFragment向InputInfoFragment页面传值错误! ", e);
         }
 
     }

+ 127 - 103
app/src/main/java/com/emato/ich/fragment/ExceptionFragment.java

@@ -9,6 +9,7 @@ import android.view.ViewGroup;
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.Fragment;
 import androidx.navigation.fragment.NavHostFragment;
 
@@ -25,6 +26,7 @@ import com.emato.ich.local.LocalStorage;
 import com.emato.ich.utils.BaseUtils;
 import com.emato.ich.utils.ButtonUtils;
 import com.emato.ich.utils.JacksonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.TimeOutUtils;
 import com.emato.ich.utils.ToastUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -62,6 +64,7 @@ public class ExceptionFragment extends Fragment {
             timer.start();
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 倒计时出现异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 异常处理页面倒计时出现异常! ", e);
         }
 
         if (!LocalStorage.getInstance().getSession().getException()) {
@@ -79,6 +82,7 @@ public class ExceptionFragment extends Fragment {
             arguments = activity.getBundleMap().get(InputInfoFragment.class.getName());
         } catch (RuntimeException e) {
             Log.e(TAG, "onViewCreated: InputInfoFragment向ExceptionFragment页面传值错误! ", e);
+            LoggingUtils.sendErrorLog("业务异常: InputInfoFragment向ExceptionFragment页面传值错误! ", e);
         }
 
         // 异常处理, 调下单接口,
@@ -157,121 +161,141 @@ public class ExceptionFragment extends Fragment {
             return;
         }
         if (null == bundle) {
+            ToastUtils.make(getContext(), "没有待提交的投递订单! ");
             return;
         }
-        ObjectMapper objectMapper = JacksonUtils.objectmapper;
-        String response = bundle.getString("preparedOrderResponse");
-        String sectionType = bundle.getString("section_type");
-        try {
-            PreparedOrderResponseVo preparedOrderResponseVo = objectMapper.readValue(response, PreparedOrderResponseVo.class);
-            ConfirmOrderVo confirmOrderVo = new ConfirmOrderVo();
-            confirmOrderVo.setOrderSn(preparedOrderResponseVo.getOrderSn());
-            confirmOrderVo.setClientId(BaseUtils.getClientId());
-            confirmOrderVo.setLockerType(sectionType);
-            switch (decisionEnum) {
-                case CANCEL_11:
-                    // 未投递 取消
-                    confirmOrderVo.setDecision(DecisionEnum.CANCEL_11.getDecision());
-                    ToastUtils.make(getContext(), "异常处理只能处理一次! 如未处理您的问题! 请联系我们处理! ");
-                    break;
-                case CANCEL_12:
-                    // 拿出快递 取消
-                    confirmOrderVo.setDecision(DecisionEnum.CANCEL_12.getDecision());
-                    ToastUtils.make(getContext(), "异常处理只能处理一次! 如未处理您的问题! 请联系我们处理! ");
-                    NavHostFragment.findNavController(ExceptionFragment.this).navigate(R.id.action_exceptionFragment_to_sendSuccessFragment);
-                    break;
-                case REOPEN_01:
-                    // 大小不合适
-                    confirmOrderVo.setDecision(DecisionEnum.REOPEN_01.getDecision());
-                    ToastUtils.make(getContext(), "异常处理只能处理一次! 如未处理您的问题! 请联系我们处理! ");
-                    break;
-                case REOPEN_02:
-                    // 门没开换柜门
-                    confirmOrderVo.setDecision(DecisionEnum.REOPEN_02.getDecision());
-                    ToastUtils.make(getContext(), "异常处理只能处理一次! 如未处理您的问题! 请联系我们处理! ");
-                    break;
-                case REOPEN_03:
-                    // 门没开再开一次
-                    confirmOrderVo.setDecision(DecisionEnum.REOPEN_03.getDecision());
-                    ToastUtils.make(getContext(), "异常处理只能处理一次! 如未处理您的问题! 请联系我们处理! ");
-                    break;
-                default:
-                    break;
-            }
 
-            LocalStorage.getInstance().getSession().setException(false);
-            binding.issueCancel.setEnabled(false);
-            binding.issueDoorNotOpen.setEnabled(false);
-            binding.issueOpenAgain.setEnabled(false);
-            binding.issueSize.setEnabled(false);
-            binding.issueTakeCancel.setEnabled(false);
+        // 异常按钮提示
+        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+        AlertDialog alertDialog = builder.setTitle("e站通")
+                .setMessage("点击按钮会执行相应操作! 本次投递只能使用一次! ")
+                .setPositiveButton("是", (dialog, which) -> {
+                    ObjectMapper objectMapper = JacksonUtils.objectmapper;
+                    String response = bundle.getString("preparedOrderResponse");
+                    String sectionType = bundle.getString("section_type");
+                    try {
+                        PreparedOrderResponseVo preparedOrderResponseVo = objectMapper.readValue(response, PreparedOrderResponseVo.class);
+                        ConfirmOrderVo confirmOrderVo = new ConfirmOrderVo();
+                        confirmOrderVo.setOrderSn(preparedOrderResponseVo.getOrderSn());
+                        confirmOrderVo.setClientId(BaseUtils.getClientId());
+                        confirmOrderVo.setLockerType(sectionType);
+                        switch (decisionEnum) {
+                            case CANCEL_11:
+                                // 未投递 取消
+                                confirmOrderVo.setDecision(DecisionEnum.CANCEL_11.getDecision());
+//                                ToastUtils.make(getContext(), "异常处理只能处理一次! 如未处理您的问题! 请联系我们处理! ");
+                                break;
+                            case CANCEL_12:
+                                // 拿出快递 取消
+                                confirmOrderVo.setDecision(DecisionEnum.CANCEL_12.getDecision());
+                                ToastUtils.make(getContext(), "异常处理只能处理一次! 如未处理您的问题! 请联系我们处理! ");
+//                                NavHostFragment.findNavController(ExceptionFragment.this).navigate(R.id.action_exceptionFragment_to_sendSuccessFragment);
+                                break;
+                            case REOPEN_01:
+                                // 大小不合适
+                                confirmOrderVo.setDecision(DecisionEnum.REOPEN_01.getDecision());
+//                                ToastUtils.make(getContext(), "异常处理只能处理一次! 如未处理您的问题! 请联系我们处理! ");
+                                break;
+                            case REOPEN_02:
+                                // 门没开换柜门
+                                confirmOrderVo.setDecision(DecisionEnum.REOPEN_02.getDecision());
+//                                ToastUtils.make(getContext(), "异常处理只能处理一次! 如未处理您的问题! 请联系我们处理! ");
+                                break;
+                            case REOPEN_03:
+                                // 门没开再开一次
+                                confirmOrderVo.setDecision(DecisionEnum.REOPEN_03.getDecision());
+//                                ToastUtils.make(getContext(), "异常处理只能处理一次! 如未处理您的问题! 请联系我们处理! ");
+                                break;
+                            default:
+                                break;
+                        }
 
-            ICSPClient.confirmOrder(LocalStorage.getInstance().getSession().getToken(), confirmOrderVo, new Callback() {
-                @Override
-                public void onFailure(@NotNull Call call, @NotNull IOException e) {
-                    ToastUtils.make(getContext(), "发送异常处理请求失败!网络异常!");
-                    Log.e(TAG, "onFailure: 发送异常处理请求失败! ", e);
-                }
+                        LocalStorage.getInstance().getSession().setException(false);
+                        binding.issueCancel.setEnabled(false);
+                        binding.issueDoorNotOpen.setEnabled(false);
+                        binding.issueOpenAgain.setEnabled(false);
+                        binding.issueSize.setEnabled(false);
+                        binding.issueTakeCancel.setEnabled(false);
 
-                @Override
-                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
-                    // 场景不同, 处理方式不同
-                    getActivity().runOnUiThread(() -> {
-                        ResponseData responseData = null;
-                        try {
-                            String parseResponse = ICSPClient.isSuccessfulAndParseResponse(response);
-                            try {
-                                responseData = objectMapper.readValue(parseResponse, ResponseData.class);
-                                // TODO 处理异常
-                                if (responseData != null && responseData.getCode().equals(ICSPResponseCodeEnum.OK.getCode())) {
-                                    String code = responseData.getCode();
-                                    Object data = responseData.getData();
-                                    Log.i(TAG, "onResponse: 响应码: " + code + ", 响应消息: " + responseData.getMsg());
-                                    switch (decisionEnum) {
-                                        case CANCEL_11:
-                                            // 未投递 取消投递 并清空Session
-                                            LocalStorage.getInstance().cleanSession(((MainActivity) getActivity()));
-                                            timer.cancel();
-                                            NavHostFragment.findNavController(ExceptionFragment.this)
-                                                    .navigate(R.id.actionExceptionFragment_to_mainFragment);
-                                            break;
-                                        case CANCEL_12:
-                                            // 拿出快递 取消
+                        ICSPClient.confirmOrder(LocalStorage.getInstance().getSession().getToken(), confirmOrderVo, new Callback() {
+                            @Override
+                            public void onFailure(@NotNull Call call, @NotNull IOException e) {
+                                ToastUtils.make(getContext(), "发送异常处理请求失败!网络异常!");
+                                Log.e(TAG, "onFailure: 发送异常处理请求失败! ", e);
+                                LoggingUtils.sendErrorLog("业务异常: 发送异常处理请求失败! ", e);
+                            }
 
-                                            break;
-                                        case REOPEN_01:
-                                            // 大小不合适
+                            @Override
+                            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+                                // 场景不同, 处理方式不同
+                                getActivity().runOnUiThread(() -> {
+                                    ResponseData responseData = null;
+                                    try {
+                                        String parseResponse = ICSPClient.isSuccessfulAndParseResponse(response);
+                                        try {
+                                            responseData = objectMapper.readValue(parseResponse, ResponseData.class);
+                                            // TODO 处理异常
+                                            if (responseData != null && responseData.getCode().equals(ICSPResponseCodeEnum.OK.getCode())) {
+                                                String code = responseData.getCode();
+                                                Object data = responseData.getData();
+                                                Log.i(TAG, "onResponse: 响应码: " + code + ", 响应消息: " + responseData.getMsg());
+                                                switch (decisionEnum) {
+                                                    case CANCEL_11:
+                                                        // 未投递 取消
+                                                    case CANCEL_12:
+                                                        // 拿出快递 取消
+                                                        // 清空session, 跳转到主页
+                                                        LocalStorage.getInstance().cleanSession(((MainActivity) getActivity()));
+                                                        timer.cancel();
+                                                        NavHostFragment.findNavController(ExceptionFragment.this)
+                                                                .navigate(R.id.action_exceptionFragment_to_sendSuccessFragment);
+                                                        break;
+                                                    case REOPEN_01:
+                                                        // 大小不合适
 
-                                            break;
-                                        case REOPEN_02:
-                                            // 门没开换柜门
+                                                        break;
+                                                    case REOPEN_02:
+                                                        // 门没开换柜门
 
-                                            break;
-                                        case REOPEN_03:
-                                            // 门没开再开一次
+                                                        break;
+                                                    case REOPEN_03:
+                                                        // 门没开再开一次
 
-                                            break;
-                                        default:
-                                            break;
+                                                        break;
+                                                    default:
+                                                        break;
+                                                }
+                                            } else {
+                                                ICSPResponseCodeEnum.responseHint(getContext(), responseData);
+                                                Log.w(TAG, "onResponse: " + responseData.getMsg());
+                                            }
+                                        } catch (JsonProcessingException e) {
+                                            Log.e(TAG, "onResponse: 处理异常场景: " + decisionEnum.getMsg() + ", 解析响应信息时出错! ", e);
+                                            LoggingUtils.sendErrorLog("业务异常: 处理异常场景: " + decisionEnum.getMsg() + ", 解析响应信息时出错! ", e);
+                                        }
+                                    } catch (RuntimeException e) {
+                                        Log.e(TAG, "onResponse: 处理\"" + decisionEnum.getMsg() + "\"问题时出错! 返回码: " + responseData.getCode() + ", 错误消息: " + responseData.getMsg(), e);
+                                        LoggingUtils.sendErrorLog("业务异常: 处理\"" + decisionEnum.getMsg() + "\"问题时出错! 返回码: " + responseData.getCode() + ", 错误消息: " + responseData.getMsg(), e);
                                     }
-                                } else {
-                                    ICSPResponseCodeEnum.responseHint(getContext(), responseData);
-                                    Log.w(TAG, "onResponse: " + responseData.getMsg());
-                                }
-                            } catch (JsonProcessingException e) {
-                                Log.e(TAG, "onResponse: 处理异常场景: " + decisionEnum.getMsg() + ", 解析响应信息时出错! ", e);
+                                });
                             }
-                        } catch (RuntimeException e) {
-                            Log.e(TAG, "onResponse: 处理\"" + decisionEnum.getMsg() + "\"问题时出错! 返回码: " + responseData.getCode() + ", 错误消息: " + responseData.getMsg(), e);
-                        }
-                    });
-                }
-            });
-
-        } catch (JsonProcessingException e) {
-            Log.e(TAG, "handleExceptionScene: 解析订单数据失败!", e);
-        }
+                        });
 
+                    } catch (JsonProcessingException e) {
+                        Log.e(TAG, "handleExceptionScene: 解析订单数据失败!", e);
+                        LoggingUtils.sendErrorLog("业务异常: 异常页面解析订单数据失败! ", e);
+                    }
+                })
+                .setNegativeButton("否", (dialog, which) -> {
+                    LocalStorage.getInstance().getSession().setException(true);
+                    binding.issueCancel.setEnabled(true);
+                    binding.issueDoorNotOpen.setEnabled(true);
+                    binding.issueOpenAgain.setEnabled(true);
+                    binding.issueSize.setEnabled(true);
+                    binding.issueTakeCancel.setEnabled(true);
+                    dialog.dismiss();
+                }).create();
+        alertDialog.show();
 
     }
 

+ 56 - 18
app/src/main/java/com/emato/ich/fragment/InputInfoFragment.java

@@ -19,6 +19,7 @@ import com.emato.ich.MainActivity;
 import com.emato.ich.R;
 import com.emato.ich.api.ICSPClient;
 import com.emato.ich.api.ICSPResponseCodeEnum;
+import com.emato.ich.contant.ScanGunConstant;
 import com.emato.ich.databinding.FragmentInputInfoBinding;
 import com.emato.ich.entity.vo.ResponseData;
 import com.emato.ich.entity.vo.PreparedOrderResponseVo;
@@ -26,8 +27,10 @@ import com.emato.ich.entity.vo.PreparedOrderVo;
 import com.emato.ich.local.LocalStorage;
 import com.emato.ich.utils.BaseUtils;
 import com.emato.ich.utils.JacksonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.StringUtils;
 import com.emato.ich.utils.TimeOutUtils;
+import com.emato.ich.utils.ToastUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
@@ -38,6 +41,7 @@ import org.jetbrains.annotations.NotNull;
 import java.io.IOException;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import okhttp3.Call;
@@ -78,6 +82,7 @@ public class InputInfoFragment extends Fragment {
             timer.start();
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 倒计时出现异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 输入投递信息页面倒计时出现异常! ", e);
         }
 
         Bundle arguments = null;
@@ -92,6 +97,16 @@ public class InputInfoFragment extends Fragment {
                 // 扫码成功回调
                 Log.d(TAG, "onScanSuccess: " + s);
 
+                if (!StringUtils.isNullOrEmpty(s)) {
+                    for (String pattern : ScanGunConstant.getPatterns()) {
+                        Matcher matcher = Pattern.compile(pattern).matcher(s);
+                        if (!matcher.matches()) {
+                            ToastUtils.make(getContext(), "请将条形码置于扫码枪前! ");
+                            return;
+                        }
+                    }
+                }
+
                 if (mailNoLock.get() == 1) {
                     Editable text = binding.mailNo.getText();
                     text.clear();
@@ -102,7 +117,10 @@ public class InputInfoFragment extends Fragment {
                         @Override
                         public void onFailure(@NotNull Call call, @NotNull IOException e) {
                             // 请求失败
-                            Snackbar.make(view, "服务器异常! 请手动输入! ", Snackbar.LENGTH_LONG).show();
+                            Log.e(TAG, "onFailure: 请求oms获取手机号失败! 网络异常! ", e);
+                            LoggingUtils.sendErrorLog("请求oms获取手机号失败! 网络异常! ", e);
+                            ToastUtils.make(getContext(), "服务器异常! 请手动输入!");
+                            mailNoLock.set(1);
                         }
 
                         @Override
@@ -124,11 +142,14 @@ public class InputInfoFragment extends Fragment {
 
                                 } catch (JsonProcessingException e) {
                                     Log.e(TAG, "onResponse: 服务器响应错误! 自动获取用户手机号失败! ", e);
-                                    Snackbar.make(view, "网络异常! 请手动输入手机号! ", Snackbar.LENGTH_LONG).show();
+                                    ToastUtils.make(getContext(), "网络异常! 请手动输入手机号! ");
+                                    LoggingUtils.sendErrorLog("业务异常: 服务器响应错误! 自动获取用户手机号失败! ", e);
                                 } catch (RuntimeException e) {
                                     Log.e(TAG, "onResponse: 获取用户手机号未知错误! ", e);
-                                    Snackbar.make(view, "未查询到手机号! 请手动输入! ", Snackbar.LENGTH_LONG).show();
+                                    ToastUtils.make(getContext(), "未查询到手机号! 请手动输入! ");
+                                    LoggingUtils.sendErrorLog("业务异常: 获取用户手机号未知错误! ", e);
                                 }
+                                mailNoLock.set(1);
                             });
 
                         }
@@ -138,6 +159,7 @@ public class InputInfoFragment extends Fragment {
 
         } catch (RuntimeException e) {
             Log.e(TAG, "onViewCreated: InputInfoFragment页面获取ChooseCabinetFragment传值错误! ", e);
+            LoggingUtils.sendErrorLog("业务异常: InputInfoFragment页面获取ChooseCabinetFragment传值错误! ", e);
         }
 
         // TODO 离线逻辑, 暂时不做
@@ -153,9 +175,9 @@ public class InputInfoFragment extends Fragment {
 //            String phone = binding.delivererPhone.getText().toString();
                 String phoneConfirm = binding.delivererPhoneConfirm.getText().toString();
                 if (!phonePattern.matcher(phoneConfirm).matches()) {
-                    Snackbar.make(view1, "请输入正确的手机号!", Snackbar.LENGTH_LONG).show();
+                    ToastUtils.make(getContext(), "请输入正确的手机号!");
                 } else if (StringUtils.isNullOrEmpty(mailNo)) {
-                    Snackbar.make(view1, "运单号不能为空!请扫描运单号!", Snackbar.LENGTH_LONG).show();
+                    ToastUtils.make(getContext(), "运单号不能为空!请扫描运单号!");
                 } else {
                     // 验证完 预下单
                     PreparedOrderVo preparedOrderVo = new PreparedOrderVo();
@@ -170,8 +192,9 @@ public class InputInfoFragment extends Fragment {
                         @Override
                         public void onFailure(@NotNull Call call, @NotNull IOException e) {
                             // TODO 预下单调用失败
-                            Snackbar.make(view, "请求服务器失败!网络异常!", Snackbar.LENGTH_LONG).show();
+                            ToastUtils.make(getContext(), "请求服务器失败!网络异常!");
                             Log.e(TAG, "onFailure: 预下单失败! call: " + call.timeout().toString(), e);
+                            LoggingUtils.sendErrorLog("业务异常: 预下单失败! call: " + call.timeout().toString(), e);
                         }
 
                         @Override
@@ -194,17 +217,22 @@ public class InputInfoFragment extends Fragment {
                                             activity.getBundleMap().put(InputInfoFragment.class.getName(), bundle);
                                         } catch (RuntimeException e) {
                                             Log.e(TAG, "onResponse: InputInfoFragment页面获取SendInfoConfirmFragment传值错误! ", e);
+                                            LoggingUtils.sendErrorLog("业务异常: InputInfoFragment页面获取SendInfoConfirmFragment传值错误! ", e);
                                         }
                                         timer.cancel();
                                         NavHostFragment.findNavController(InputInfoFragment.this).navigate(R.id.action_inputInfoFragment_to_sendInfoConfirmFragment);
                                     } else {
-                                        ICSPResponseCodeEnum.responseHint(getContext(), responseData);
-                                        Log.e(TAG, "onResponse: ICSP返回码: " + responseData.getCode() + ", 返回信息: " + responseData.getMsg(), new RuntimeException("系统异常"));
+                                        RuntimeException exception = new RuntimeException("系统异常");
+                                        Log.e(TAG, "onResponse: ICSP返回码: " + responseData.getCode() + ", 返回信息: " + responseData.getMsg(), exception);
+                                        LoggingUtils.sendErrorLog("业务异常: ICSP返回码: " + responseData.getCode() + ", 返回信息: " + responseData.getMsg(), exception);
                                     }
+                                    ToastUtils.make(getContext(), responseData.getMsg());
                                 } catch (JsonProcessingException e) {
                                     Log.e(TAG, "onResponse: 预下单转换成JSON出错! ", e);
+                                    LoggingUtils.sendErrorLog("业务异常: 预下单转换成JSON出错! ", e);
                                 } catch (RuntimeException e) {
                                     Log.e(TAG, "onResponse: 预下单失败! ", e);
+                                    LoggingUtils.sendErrorLog("业务异常: 预下单失败! ", e);
                                 }
                             });
                         }
@@ -221,7 +249,7 @@ public class InputInfoFragment extends Fragment {
                 binding.inputButton0.setOnClickListener(v -> {
                     int length = binding.delivererPhoneConfirm.getText().length();
                     if (length >= 11) {
-                        Snackbar.make(view1, "手机号不能超过11位", Snackbar.LENGTH_LONG).show();
+                        ToastUtils.make(getContext(), "手机号不能超过11位! ");
                         return;
                     }
                     int start = binding.delivererPhoneConfirm.getSelectionStart();
@@ -230,7 +258,7 @@ public class InputInfoFragment extends Fragment {
                 binding.inputButton1.setOnClickListener(v -> {
                     int length = binding.delivererPhoneConfirm.getText().length();
                     if (length >= 11) {
-                        Snackbar.make(view1, "手机号不能超过11位", Snackbar.LENGTH_LONG).show();
+                        ToastUtils.make(getContext(), "手机号不能超过11位! ");
                         return;
                     }
                     int start = binding.delivererPhoneConfirm.getSelectionStart();
@@ -239,7 +267,7 @@ public class InputInfoFragment extends Fragment {
                 binding.inputButton2.setOnClickListener(v -> {
                     int length = binding.delivererPhoneConfirm.getText().length();
                     if (length >= 11) {
-                        Snackbar.make(view1, "手机号不能超过11位", Snackbar.LENGTH_LONG).show();
+                        ToastUtils.make(getContext(), "手机号不能超过11位! ");
                         return;
                     }
                     int start = binding.delivererPhoneConfirm.getSelectionStart();
@@ -248,7 +276,7 @@ public class InputInfoFragment extends Fragment {
                 binding.inputButton3.setOnClickListener(v -> {
                     int length = binding.delivererPhoneConfirm.getText().length();
                     if (length >= 11) {
-                        Snackbar.make(view1, "手机号不能超过11位", Snackbar.LENGTH_LONG).show();
+                        ToastUtils.make(getContext(), "手机号不能超过11位! ");
                         return;
                     }
                     int start = binding.delivererPhoneConfirm.getSelectionStart();
@@ -257,7 +285,7 @@ public class InputInfoFragment extends Fragment {
                 binding.inputButton4.setOnClickListener(v -> {
                     int length = binding.delivererPhoneConfirm.getText().length();
                     if (length >= 11) {
-                        Snackbar.make(view1, "手机号不能超过11位", Snackbar.LENGTH_LONG).show();
+                        ToastUtils.make(getContext(), "手机号不能超过11位! ");
                         return;
                     }
                     int start = binding.delivererPhoneConfirm.getSelectionStart();
@@ -266,7 +294,7 @@ public class InputInfoFragment extends Fragment {
                 binding.inputButton5.setOnClickListener(v -> {
                     int length = binding.delivererPhoneConfirm.getText().length();
                     if (length >= 11) {
-                        Snackbar.make(view1, "手机号不能超过11位", Snackbar.LENGTH_LONG).show();
+                        ToastUtils.make(getContext(), "手机号不能超过11位! ");
                         return;
                     }
                     int start = binding.delivererPhoneConfirm.getSelectionStart();
@@ -275,7 +303,7 @@ public class InputInfoFragment extends Fragment {
                 binding.inputButton6.setOnClickListener(v -> {
                     int length = binding.delivererPhoneConfirm.getText().length();
                     if (length >= 11) {
-                        Snackbar.make(view1, "手机号不能超过11位", Snackbar.LENGTH_LONG).show();
+                        ToastUtils.make(getContext(), "手机号不能超过11位! ");
                         return;
                     }
                     int start = binding.delivererPhoneConfirm.getSelectionStart();
@@ -284,7 +312,7 @@ public class InputInfoFragment extends Fragment {
                 binding.inputButton7.setOnClickListener(v -> {
                     int length = binding.delivererPhoneConfirm.getText().length();
                     if (length >= 11) {
-                        Snackbar.make(view1, "手机号不能超过11位", Snackbar.LENGTH_LONG).show();
+                        ToastUtils.make(getContext(), "手机号不能超过11位! ");
                         return;
                     }
                     int start = binding.delivererPhoneConfirm.getSelectionStart();
@@ -293,7 +321,7 @@ public class InputInfoFragment extends Fragment {
                 binding.inputButton8.setOnClickListener(v -> {
                     int length = binding.delivererPhoneConfirm.getText().length();
                     if (length >= 11) {
-                        Snackbar.make(view1, "手机号不能超过11位", Snackbar.LENGTH_LONG).show();
+                        ToastUtils.make(getContext(), "手机号不能超过11位! ");
                         return;
                     }
                     int start = binding.delivererPhoneConfirm.getSelectionStart();
@@ -302,7 +330,7 @@ public class InputInfoFragment extends Fragment {
                 binding.inputButton9.setOnClickListener(v -> {
                     int length = binding.delivererPhoneConfirm.getText().length();
                     if (length >= 11) {
-                        Snackbar.make(view1, "手机号不能超过11位", Snackbar.LENGTH_LONG).show();
+                        ToastUtils.make(getContext(), "手机号不能超过11位");
                         return;
                     }
                     int start = binding.delivererPhoneConfirm.getSelectionStart();
@@ -316,6 +344,11 @@ public class InputInfoFragment extends Fragment {
                         binding.delivererPhoneConfirm.setSelection(binding.delivererPhoneConfirm.getText().length());
                     }
                 });
+                // 长按删除
+                binding.inputButtonCancel.setOnLongClickListener(v -> {
+                    binding.delivererPhoneConfirm.getText().clear();
+                    return false;
+                });
             }
         });
 
@@ -369,6 +402,11 @@ public class InputInfoFragment extends Fragment {
                         binding.mailNo.setSelection(binding.mailNo.getText().length());
                     }
                 });
+                // 长按删除
+                binding.inputButtonCancel.setOnLongClickListener(v -> {
+                    binding.mailNo.getText().clear();
+                    return false;
+                });
             }
         });
 

+ 3 - 0
app/src/main/java/com/emato/ich/fragment/MainFragment.java

@@ -17,6 +17,7 @@ import com.emato.ich.api.ICSPClient;
 import com.emato.ich.contant.SystemConfigConstant;
 import com.emato.ich.databinding.FragmentMainBinding;
 import com.emato.ich.utils.ButtonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.StringUtils;
 
 import org.jetbrains.annotations.NotNull;
@@ -54,6 +55,7 @@ public class MainFragment extends Fragment {
                 @Override
                 public void onFailure(@NotNull Call call, @NotNull IOException e) {
                     Log.e(TAG, "onFailure: 请求微信公众号图片错误! 网络异常! ", e);
+                    LoggingUtils.sendErrorLog("业务异常: 请求微信公众号图片错误! 网络异常! ", e);
                 }
 
                 @Override
@@ -66,6 +68,7 @@ public class MainFragment extends Fragment {
                             is.close();
                         } catch (Exception e) {
                             Log.e(TAG, "onResponse: 设置图片异常! ", e);
+                            LoggingUtils.sendErrorLog("业务异常: 请求微信公众号图片异常! ", e);
                         }
                     });
                 }

+ 8 - 0
app/src/main/java/com/emato/ich/fragment/SendFragment.java

@@ -26,6 +26,7 @@ import com.emato.ich.local.LocalStorage;
 import com.emato.ich.utils.BaseUtils;
 import com.emato.ich.utils.ButtonUtils;
 import com.emato.ich.utils.JacksonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.StringUtils;
 import com.emato.ich.utils.TimeOutUtils;
 import com.emato.ich.utils.ToastUtils;
@@ -68,6 +69,7 @@ public class SendFragment extends Fragment {
             timer.start();
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 倒计时异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 投递员登录页面倒计时异常! ", e);
         }
 
         binding.inputButtonConfirm.setOnClickListener(view1 -> {
@@ -89,6 +91,7 @@ public class SendFragment extends Fragment {
                         // TODO 登录失败处理
                         ToastUtils.make(getContext(), "登录失败!网络异常!");
                         Log.e(TAG, "onFailure: 登录失败! call: " + call.timeout().toString(), e);
+                        LoggingUtils.sendErrorLog("业务异常: 登录失败!网络异常! ", e);
                     }
 
                     @Override
@@ -118,16 +121,20 @@ public class SendFragment extends Fragment {
                                 } catch (JsonProcessingException e) {
                                     Log.e(TAG, "onViewCreated: 解析登录响应信息错误! response body: " + responseStr, e);
                                     ToastUtils.make(getContext(), "登录失败!");
+                                    LoggingUtils.sendErrorLog("业务异常: 登录失败!", e);
                                 } catch (ClassCastException e) {
                                     Log.e(TAG, "onResponse: 解析登录响应信息类型转换错误! response body: " + responseStr, e);
                                     ToastUtils.make(getContext(), "登录失败!");
+                                    LoggingUtils.sendErrorLog("业务异常: 登录失败!", e);
                                 } catch (RuntimeException e) {
                                     Log.e(TAG, "onResponse: 登录失败! ", e);
                                     ToastUtils.make(getContext(), "登录失败!");
+                                    LoggingUtils.sendErrorLog("业务异常: 登录失败!未知错误! ", e);
                                 }
                             } else {
                                 // 登录失败
                                 ToastUtils.make(getContext(), "登录失败!手机号或密码错误!");
+                                LoggingUtils.sendErrorLog("业务异常: 登录失败!手机号或密码错误!", null);
                             }
                         });
                     }
@@ -147,6 +154,7 @@ public class SendFragment extends Fragment {
             loginPhone = activity.getConfigMap().get(SystemConfigConstant.cabinet_login_phone);
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 配置登录手机号出错! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 配置登录手机号出错! ", e);
         }
         if (!StringUtils.isNullOrEmpty(loginPhone)) {
             binding.editTextTextPersonName4.setText(loginPhone);

+ 79 - 16
app/src/main/java/com/emato/ich/fragment/SendInfoConfirmFragment.java

@@ -1,5 +1,6 @@
 package com.emato.ich.fragment;
 
+import android.app.AlertDialog;
 import android.os.Bundle;
 import android.os.CountDownTimer;
 import android.util.Log;
@@ -23,16 +24,17 @@ import com.emato.ich.entity.vo.ConfirmOrderVo;
 import com.emato.ich.entity.vo.PreparedOrderResponseVo;
 import com.emato.ich.local.LocalStorage;
 import com.emato.ich.utils.BaseUtils;
+import com.emato.ich.utils.ButtonUtils;
 import com.emato.ich.utils.JacksonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.TimeOutUtils;
+import com.emato.ich.utils.ToastUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.android.material.snackbar.Snackbar;
 
 import org.jetbrains.annotations.NotNull;
 
 import java.io.IOException;
-import java.util.Map;
 
 import okhttp3.Call;
 import okhttp3.Callback;
@@ -62,6 +64,7 @@ public class SendInfoConfirmFragment extends Fragment {
             timer.start();
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 倒计时出现异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 订单确认页面倒计时出现异常! ", e);
         }
 
         Bundle arguments = null;
@@ -71,15 +74,18 @@ public class SendInfoConfirmFragment extends Fragment {
             arguments = activity.getBundleMap().get(InputInfoFragment.class.getName());
         } catch (RuntimeException e) {
             Log.e(TAG, "onResponse: SendInfoConfirmFragment页面获取InputInfoFragment传值错误! ", e);
+            LoggingUtils.sendErrorLog("业务异常: SendInfoConfirmFragment页面获取InputInfoFragment传值错误! ", e);
         }
 
         String orderSn = null;
         String collectorPhone;
         PreparedOrderResponseVo orderResponseVo;
+        String sectionType = null;
         // 设置订单提示属性
         if (null != arguments) {
-            String response = arguments.getString("preparedOrderResponse");
             try {
+                String response = arguments.getString("preparedOrderResponse");
+                sectionType = arguments.getString("sectionType");
                 orderResponseVo = JacksonUtils.objectmapper.readValue(response, PreparedOrderResponseVo.class);
                 collectorPhone = orderResponseVo.getCollectorPhone();
                 orderSn = orderResponseVo.getOrderSn();
@@ -89,6 +95,7 @@ public class SendInfoConfirmFragment extends Fragment {
 
             } catch (JsonProcessingException e) {
                 Log.e(TAG, "onViewCreated: 解析预下单页面传递信息错误! ", e);
+                LoggingUtils.sendErrorLog("业务异常: 解析预下单页面传递信息错误! ", e);
             }
 
         }
@@ -96,6 +103,9 @@ public class SendInfoConfirmFragment extends Fragment {
         // 投递完成确认
         String finalOrderSn = orderSn;
         binding.alreadySend.setOnClickListener(view1 -> {
+            if (ButtonUtils.isFastClick()) {
+                return;
+            }
             // TODO 确认投递, 真正下单
             String clientId = BaseUtils.getClientId();
             // /order/deliverer/confirm
@@ -110,8 +120,9 @@ public class SendInfoConfirmFragment extends Fragment {
 //                    getActivity().runOnUiThread(() -> {
 //
 //                    });
-                    Snackbar.make(view, "投递失败!网络异常!", Snackbar.LENGTH_LONG).show();
+                    ToastUtils.make(getContext(), "投递失败!网络异常!");
                     Log.e(TAG, "onFailure: 确认投递失败! ", e);
+                    LoggingUtils.sendErrorLog("业务异常: 投递失败!网络异常! ", e);
                 }
 
                 @Override
@@ -124,19 +135,21 @@ public class SendInfoConfirmFragment extends Fragment {
                             String code = responseData.getCode();
                             if (code.equals(ICSPResponseCodeEnum.OK.getCode())) {
                                 // TODO 确认投递成功逻辑处理
-                                Snackbar.make(view, "投递成功! ", Snackbar.LENGTH_LONG).show();
+                                ToastUtils.make(getContext(), "投递成功!");
                                 timer.cancel();
                                 NavHostFragment.findNavController(SendInfoConfirmFragment.this)
                                         .navigate(R.id.action_sendInfoConfirmFragment_to_sendSuccessFragment);
                             } else {
                                 // TODO 确认投递失败逻辑处理
-                                ICSPResponseCodeEnum.responseHint(getContext(), responseData);
+                                ToastUtils.make(getContext(), responseData.getMsg());
                                 Log.w(TAG, "onResponse: " + responseData.getMsg());
                             }
                         } catch (JsonProcessingException e) {
                             Log.e(TAG, "onResponse: 确认投递解析响应信息失败!", e);
+                            LoggingUtils.sendErrorLog("业务异常: 确认投递解析响应信息失败! ", e);
                         } catch (RuntimeException e) {
                             Log.e(TAG, "onResponse: 投递失败! ", e);
+                            LoggingUtils.sendErrorLog("业务异常: 投递失败! 未知异常! ", e);
                         }
                     });
                 }
@@ -148,6 +161,9 @@ public class SendInfoConfirmFragment extends Fragment {
         // 异常页面跳转
         MainActivity finalActivity = activity;
         binding.exceptionBtn.setOnClickListener(view1 -> {
+            if (ButtonUtils.isFastClick()) {
+                return;
+            }
             Bundle bundle = new Bundle();
             timer.cancel();
             bundle.putString("exception", "exception_page");
@@ -157,20 +173,67 @@ public class SendInfoConfirmFragment extends Fragment {
         });
 
         // 未投递按钮
+        String finalSectionType = sectionType;
         binding.noneSend.setOnClickListener(view1 -> {
-            Bundle bundle = new Bundle();
-            bundle.putString("exception", "exception_page");
-            finalActivity.getBundleMap().put(SendInfoConfirmFragment.class.getName(), bundle);
-            timer.cancel();
-            NavHostFragment.findNavController(SendInfoConfirmFragment.this)
-                    .navigate(R.id.action_sendInfoConfirmFragment_to_exceptionFragment);
+            if (ButtonUtils.isFastClick()) {
+                return;
+            }
+//            Bundle bundle = new Bundle();
+//            bundle.putString("exception", "exception_page");
+//            finalActivity.getBundleMap().put(SendInfoConfirmFragment.class.getName(), bundle);
+            AlertDialog alertDialog = new AlertDialog.Builder(finalActivity)
+                    .setTitle("e站通")
+                    .setMessage("确定要取消本次投递吗?")
+                    .setPositiveButton("是", (dialog, which) -> {
+                        // 是, 取消本次投递
+                        ConfirmOrderVo confirmOrderVo = new ConfirmOrderVo();
+                        confirmOrderVo.setOrderSn(finalOrderSn);
+                        confirmOrderVo.setClientId(BaseUtils.getClientId());
+                        confirmOrderVo.setDecision(DecisionEnum.CANCEL_11.getDecision());
+                        confirmOrderVo.setLockerType(finalSectionType);
+                        ICSPClient.confirmOrder(LocalStorage.getInstance().getSession().getToken(), confirmOrderVo, new Callback() {
+                            @Override
+                            public void onFailure(@NotNull Call call, @NotNull IOException e) {
+                                Log.e(TAG, "onFailure: 取消投递错误! 网络错误! ", e);
+                                LoggingUtils.sendErrorLog("业务异常: 取消投递错误! 网络错误! ", e);
+                            }
+
+                            @Override
+                            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
+                                getActivity().runOnUiThread(() -> {
+                                    try {
+                                        timer.cancel();
+                                        NavHostFragment.findNavController(SendInfoConfirmFragment.this)
+                                                .navigate(R.id.action_sendInfoConfirmFragment_to_sendSuccessFragment);
+                                    } catch (Exception e) {
+
+                                    }
+                                });
+                            }
+                        });
+                    }).setNegativeButton("否", (dialog, which) -> {
+                        // 否
+                        dialog.dismiss();
+                    }).create();
+            alertDialog.show();
         });
 
         binding.returnMainBtn.setOnClickListener(view1 -> {
-            timer.cancel();
-            LocalStorage.getInstance().cleanSession(((MainActivity) getActivity()));
-            NavHostFragment.findNavController(SendInfoConfirmFragment.this)
-                    .navigate(R.id.action_sendInfoConfirmFragment_to_mainFragment);
+            if (ButtonUtils.isFastClick()) {
+                return;
+            }
+            AlertDialog alertDialog = new AlertDialog.Builder(finalActivity)
+                    .setTitle("e站通")
+                    .setMessage("返回主页会取消本次投递!确认取消吗?")
+                    .setPositiveButton("是", ((dialog, which) -> {
+                        timer.cancel();
+                        LocalStorage.getInstance().cleanSession(((MainActivity) getActivity()));
+                        NavHostFragment.findNavController(SendInfoConfirmFragment.this)
+                                .navigate(R.id.action_sendInfoConfirmFragment_to_mainFragment);
+                    })).setNegativeButton("否", ((dialog, which) -> {
+                        dialog.dismiss();
+                    })).create();
+            alertDialog.show();
         });
 
     }

+ 3 - 0
app/src/main/java/com/emato/ich/fragment/SendMainFragment.java

@@ -16,6 +16,7 @@ import com.emato.ich.MainActivity;
 import com.emato.ich.R;
 import com.emato.ich.databinding.FragmentSendMainBinding;
 import com.emato.ich.utils.ButtonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.TimeOutUtils;
 
 import org.jetbrains.annotations.NotNull;
@@ -45,6 +46,7 @@ public class SendMainFragment extends Fragment {
             activity.getBundleMap().remove(ExceptionFragment.class.getName());
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 去除异常页数据异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 投递员主页去除异常页数据异常! ", e);
         }
         try {
             MainActivity activity = ((MainActivity) getActivity());
@@ -52,6 +54,7 @@ public class SendMainFragment extends Fragment {
             timer.start();
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 倒计时出现异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 投递员主页倒计时出现异常! ", e);
         }
         // 输入快件信息
         binding.sendConfirmBtn.setOnClickListener(view1 -> {

+ 2 - 0
app/src/main/java/com/emato/ich/fragment/SendSuccessFragment.java

@@ -17,6 +17,7 @@ import com.emato.ich.R;
 import com.emato.ich.databinding.FragmentSendSuccessBinding;
 import com.emato.ich.local.LocalStorage;
 import com.emato.ich.utils.ButtonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.TimeOutUtils;
 
 import org.jetbrains.annotations.NotNull;
@@ -46,6 +47,7 @@ public class SendSuccessFragment extends Fragment {
             timer.start();
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 倒计时出现异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 投递成功页面倒计时出现异常! ", e);
         }
 
         // 继续投递

+ 9 - 1
app/src/main/java/com/emato/ich/fragment/TakeCodeFragment.java

@@ -28,6 +28,7 @@ import com.emato.ich.entity.vo.ResponseData;
 import com.emato.ich.entity.vo.TakeParcelVo;
 import com.emato.ich.utils.BaseUtils;
 import com.emato.ich.utils.ButtonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.StringUtils;
 import com.emato.ich.utils.JacksonUtils;
 import com.emato.ich.utils.TimeOutUtils;
@@ -75,6 +76,7 @@ public class TakeCodeFragment extends Fragment {
             timer.start();
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 倒计时出现异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 取件码输入页面倒计时出现异常! ", e);
         }
 
 //        binding.textView.setBackgroundResource(R.drawable.e_mp_qrcode_8x8_backup);
@@ -86,6 +88,7 @@ public class TakeCodeFragment extends Fragment {
                 @Override
                 public void onFailure(@NotNull Call call, @NotNull IOException e) {
                     Log.e(TAG, "onFailure: 请求微信公众号图片错误! 网络异常! ", e);
+                    LoggingUtils.sendErrorLog("业务异常: 请求微信公众号图片错误! 网络异常! ", e);
                 }
 
                 @Override
@@ -98,6 +101,7 @@ public class TakeCodeFragment extends Fragment {
                             is.close();
                         } catch (Exception e) {
                             Log.e(TAG, "onResponse: 设置图片异常! ", e);
+                            LoggingUtils.sendErrorLog("业务异常: 取件码输入页面设置图片异常! ", e);
                         }
                     });
                 }
@@ -233,6 +237,7 @@ public class TakeCodeFragment extends Fragment {
                         // TODO 取件接口请求失败逻辑处理
                         ToastUtils.make(getContext(), "取件失败!网络异常!");
                         Log.e(TAG, "onFailure: 取件请求失败!", e);
+                        LoggingUtils.sendErrorLog("业务异常: 取件请求失败! 网络异常! ", e);
                     }
 
                     @Override
@@ -246,12 +251,14 @@ public class TakeCodeFragment extends Fragment {
                                 try {
                                     responseData = objectMapper.readValue(parseResponse, new TypeReference<ResponseData<PreparedOrderResponseVo>>() {
                                     });
-                                    ICSPResponseCodeEnum.responseHint(getContext(), responseData);
+                                    ToastUtils.make(getContext(), responseData.getMsg());
                                 } catch (JsonProcessingException e) {
                                     Log.e(TAG, "onResponse: 解析取件开门响应信息失败! ", e);
+                                    LoggingUtils.sendErrorLog("业务异常: 解析取件开门响应信息失败! ", e);
                                 } catch (RuntimeException e) {
                                     Log.e(TAG, "onResponse: 未知错误! ", e);
                                     ToastUtils.make(getContext(), "未知错误!");
+                                    LoggingUtils.sendErrorLog("业务异常: 解析取件开门响应信息失败! 未知错误!  ", e);
                                 }
                                 if (null != responseData && responseData.getCode().equals(ICSPResponseCodeEnum.OK.getCode())) {
                                     // 开门
@@ -267,6 +274,7 @@ public class TakeCodeFragment extends Fragment {
                             } catch (RuntimeException e) {
                                 Log.e(TAG, "onResponse: 取件失败! ", e);
                                 ToastUtils.make(getContext(), "取件失败!");
+                                LoggingUtils.sendErrorLog("业务异常: 取件失败! ", e);
                             }
                         });
                     }

+ 4 - 0
app/src/main/java/com/emato/ich/fragment/TakeFragment.java

@@ -19,6 +19,7 @@ import com.emato.ich.api.ICSPClient;
 import com.emato.ich.contant.SystemConfigConstant;
 import com.emato.ich.databinding.FragmentTakeBinding;
 import com.emato.ich.utils.ButtonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.StringUtils;
 import com.emato.ich.utils.TimeOutUtils;
 
@@ -59,6 +60,7 @@ public class TakeFragment extends Fragment {
             timer.start();
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 倒计时出现异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 取件页面倒计时出现异常! ", e);
         }
 
         MainActivity activity = (MainActivity) getActivity();
@@ -69,6 +71,7 @@ public class TakeFragment extends Fragment {
                 @Override
                 public void onFailure(@NotNull Call call, @NotNull IOException e) {
                     Log.e(TAG, "onFailure: 请求微信公众号图片错误! 网络异常! ", e);
+                    LoggingUtils.sendErrorLog("业务异常: 请求微信公众号图片错误! 网络异常!", e);
                 }
 
                 @Override
@@ -81,6 +84,7 @@ public class TakeFragment extends Fragment {
                             is.close();
                         } catch (Exception e) {
                             Log.e(TAG, "onResponse: 设置图片异常! ", e);
+                            LoggingUtils.sendErrorLog("业务异常: 设置图片异常! ", e);
                         }
                     });
                 }

+ 10 - 2
app/src/main/java/com/emato/ich/fragment/TakeSuccessFragment.java

@@ -25,6 +25,7 @@ import com.emato.ich.local.LocalStorage;
 import com.emato.ich.utils.BaseUtils;
 import com.emato.ich.utils.ButtonUtils;
 import com.emato.ich.utils.JacksonUtils;
+import com.emato.ich.utils.LoggingUtils;
 import com.emato.ich.utils.TimeOutUtils;
 import com.emato.ich.utils.ToastUtils;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -66,6 +67,7 @@ public class TakeSuccessFragment extends Fragment {
             timer.start();
         } catch (Exception e) {
             Log.e(TAG, "onViewCreated: 倒计时出现异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 取件成功页面倒计时出现异常! ", e);
         }
 
         binding.continueTakeBtn.setOnClickListener(view1 -> {
@@ -112,6 +114,7 @@ public class TakeSuccessFragment extends Fragment {
             timer2.start();
         } catch (RuntimeException e) {
             Log.e(TAG, "onViewCreated: 倒计时未知异常! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 取件成功再开一次按钮倒计时出现异常! ", e);
         }
 
         binding.reOpenCabinetBtn.setOnClickListener(view1 -> {
@@ -130,6 +133,7 @@ public class TakeSuccessFragment extends Fragment {
                 takeParcelCode = bundle.getString("takeParcelCode");
             } catch (RuntimeException e) {
                 Log.e(TAG, "onViewCreated: 获取TakeCodeFragment传值TakeSuccessFragment失败! ", e);
+                LoggingUtils.sendErrorLog("业务异常: 获取TakeCodeFragment传值TakeSuccessFragment失败! ", e);
             }
             TakeParcelVo takeParcelVo = new TakeParcelVo();
             takeParcelVo.setClientId(BaseUtils.getClientId());
@@ -142,6 +146,7 @@ public class TakeSuccessFragment extends Fragment {
                     // TODO 取件接口请求失败逻辑处理
                     ToastUtils.make(getContext(), "取件失败!网络异常!");
                     Log.e(TAG, "onFailure: 取件请求失败!", e);
+                    LoggingUtils.sendErrorLog("业务异常: 取件失败!网络异常! ", e);
                 }
 
                 @Override
@@ -155,12 +160,14 @@ public class TakeSuccessFragment extends Fragment {
                             try {
                                 responseData = objectMapper.readValue(parseResponse, new TypeReference<ResponseData<PreparedOrderResponseVo>>() {
                                 });
-                                ICSPResponseCodeEnum.responseHint(getContext(), responseData);
+                                ToastUtils.make(getContext(), responseData.getMsg());
                             } catch (JsonProcessingException e) {
                                 Log.e(TAG, "onResponse: 解析取件开门响应信息失败! ", e);
+                                LoggingUtils.sendErrorLog("业务异常: 解析取件开门响应信息失败! ", e);
                             } catch (RuntimeException e) {
                                 Log.e(TAG, "onResponse: 未知错误! ", e);
                                 ToastUtils.make(getContext(), "未知错误!");
+                                LoggingUtils.sendErrorLog("业务异常: 解析取件开门响应信息失败! 未知错误! ", e);
                             }
                             if (null != responseData && responseData.getCode().equals(ICSPResponseCodeEnum.OK.getCode())) {
                                 // 开门
@@ -170,11 +177,12 @@ public class TakeSuccessFragment extends Fragment {
                                 binding.openCabinetHintNo.setText(data.getLockerName());
                                 finalActivity.getBundleMap().remove(TakeCodeFragment.class.getName());
                             } else {
-                                ICSPResponseCodeEnum.responseHint(getContext(), responseData);
+                                ToastUtils.make(getContext(), responseData.getMsg());
                             }
                         } catch (RuntimeException e) {
                             Log.e(TAG, "onResponse: 取件失败! ", e);
                             ToastUtils.make(getContext(), "取件失败!");
+                            LoggingUtils.sendErrorLog("业务异常: 取件失败! 未知错误! ", e);
                         }
                     });
                 }

+ 7 - 13
app/src/main/java/com/emato/ich/message/ICHPublishClient.java

@@ -4,6 +4,7 @@ import android.util.Log;
 
 import com.emato.ich.contant.ICSPConstant;
 import com.emato.ich.utils.BaseUtils;
+import com.emato.ich.utils.LoggingUtils;
 
 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
 import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
@@ -39,14 +40,15 @@ public class ICHPublishClient {
 
     // 初始化客户端实例
     private ICHPublishClient() {
-//        String clientId = BaseUtils.getClientId() + "publish";
-        String clientId = BaseUtils.getClientId();
+        String clientId = BaseUtils.getClientId() + "_publish";
+//        String clientId = BaseUtils.getClientId();
         try {
             Log.i(TAG, "ICHPublishClient: 创建客户端实例开始!");
             client = new MqttClient(ICSPConstant.MQTT_SERVER_ADDRESS, clientId, new MemoryPersistence());
             Log.i(TAG, "ICHPublishClient: 创建客户端实例完成!");
         } catch (MqttException e) {
             Log.e(TAG, "ICHPublishClient: 创建客户端实例失败!", e);
+            LoggingUtils.sendErrorLog("业务异常: 创建客户端实例失败! ", e);
         }
         connect();
     }
@@ -60,7 +62,7 @@ public class ICHPublishClient {
         options.setUserName(userName);
         options.setPassword(password.toCharArray());
         // 连接超时时间
-        options.setConnectionTimeout(10);
+        options.setConnectionTimeout(30);
         // 设置心跳间隔时间
         options.setKeepAliveInterval(30);
         // TODO 设置发布回调
@@ -85,6 +87,7 @@ public class ICHPublishClient {
             Log.i(TAG, "connect: 连接消息服务器成功!");
         } catch (MqttException e) {
             Log.e(TAG, "connect: 连接消息服务器失败!", e);
+            LoggingUtils.sendErrorLog("业务异常: 连接消息服务器失败! ", e);
         }
     }
 
@@ -99,16 +102,7 @@ public class ICHPublishClient {
             Log.i(TAG, "publish: 消息发送成功 " + token.isComplete());
         } catch (MqttException e) {
             Log.e(TAG, "publish: 消息推送失败!", e);
-        }
-    }
-
-    public void subscribe(String topicName, IMqttMessageListener iMqttMessageListener) {
-        try {
-            topic = client.getTopic(topicName);
-            Log.i(TAG, "subscribe: 开始消息监听! topicName: " + topicName);
-            client.subscribe(topicName, iMqttMessageListener);
-        } catch (MqttException e) {
-            Log.e(TAG, "subscribe: 消息监听失败! topicName: " + topicName, e);
+            LoggingUtils.sendErrorLog("业务异常: 消息推送失败! ", e);
         }
     }
 }

+ 9 - 3
app/src/main/java/com/emato/ich/message/ICHSubscribeClient.java

@@ -4,6 +4,7 @@ import android.util.Log;
 
 import com.emato.ich.contant.ICSPConstant;
 import com.emato.ich.utils.BaseUtils;
+import com.emato.ich.utils.LoggingUtils;
 
 import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
 import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
@@ -18,7 +19,6 @@ import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
 /**
  * 订阅客户端
  */
-@Deprecated
 public class ICHSubscribeClient {
 
     public static final String TAG = "ICHSubscribeClient";
@@ -40,13 +40,14 @@ public class ICHSubscribeClient {
 
 
     private ICHSubscribeClient() {
-        String clientId = BaseUtils.getClientId() + "subscribe";
+        String clientId = BaseUtils.getClientId() + "_subscribe";
         try {
             Log.i(TAG, "ICHSubscribeClient: 开始创建消息服务器订阅客户端实例!");
             client = new MqttClient(ICSPConstant.MQTT_SERVER_ADDRESS, clientId, new MemoryPersistence());
             Log.i(TAG, "ICHSubscribeClient: 创建消息服务器订阅客户端实例成功!");
         } catch (MqttException e) {
             Log.e(TAG, "ICHSubscribeClient: 创建消息服务器客户端失败!", e);
+            LoggingUtils.sendErrorLog("业务异常: 创建消息服务器客户端失败! ", e);
         }
         connect();
     }
@@ -58,7 +59,7 @@ public class ICHSubscribeClient {
         options.setUserName(userName);
         options.setPassword(password.toCharArray());
         // 连接超时时间
-        options.setConnectionTimeout(10);
+        options.setConnectionTimeout(30);
         // 设置心跳间隔时间
         options.setKeepAliveInterval(30);
         // TODO 设置连接回调
@@ -66,16 +67,19 @@ public class ICHSubscribeClient {
             @Override
             public void connectionLost(Throwable cause) {
                 // TODO 重连
+                Log.e(TAG, "connectionLost: cause: ", cause);
             }
 
             @Override
             public void messageArrived(String topic, MqttMessage message) throws Exception {
                 // TODO MQTT服务器成功接收消息后,返回消息并调用此方法
+                Log.i(TAG, "messageArrived: topic: " + topic + ", msg: " + message.getId() + "--" + new String(message.getPayload()));
             }
 
             @Override
             public void deliveryComplete(IMqttDeliveryToken token) {
                 // TODO 接收到已经发布的 QoS 1 或 QoS 2 消息的传递令牌时调用
+                Log.i(TAG, "deliveryComplete: token---" + token.toString() + "---" + topic.getName());
             }
         });
         try {
@@ -83,6 +87,7 @@ public class ICHSubscribeClient {
             Log.i(TAG, "connect: 连接消息服务器成功!");
         } catch (MqttException e) {
             Log.e(TAG, "connect: 连接消息服务器失败!", e);
+            LoggingUtils.sendErrorLog("业务异常: 连接消息服务器失败! ", e);
         }
     }
 
@@ -93,6 +98,7 @@ public class ICHSubscribeClient {
             client.subscribe(topicName, iMqttMessageListener);
         } catch (MqttException e) {
             Log.e(TAG, "subscribe: 消息监听失败! topicName: " + topicName, e);
+            LoggingUtils.sendErrorLog("业务异常: 消息监听失败! topicName: " + topicName, e);
         }
     }
 }

+ 1 - 1
app/src/main/java/com/emato/ich/message/ICHTopic.java

@@ -17,7 +17,7 @@ public class ICHTopic {
 
     public static final String APK_UPDATE_PATH = "/icsp-server/apk/upgrade/%s";
 
-    public static final String EXECUTE_SHELL_SCRIPT = "/iscp-server/execute/shell/%s";
+    public static final String EXECUTE_SHELL_SCRIPT = "/icsp-server/execute/shell/%s";
 
     public static final String EXECUTE_SHELL_SCRIPT_RESPONSE = "/icsp-client/execute/shell/response/%s";
 

+ 35 - 0
app/src/main/java/com/emato/ich/update/CustomUpdateConfigProvider.java

@@ -0,0 +1,35 @@
+package com.emato.ich.update;
+
+import android.content.Context;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import com.xuexiang.xupdate.aria.AriaDownloadServiceProxyImpl;
+import com.xuexiang.xupdate.easy.config.IUpdateConfigProvider;
+import com.xuexiang.xupdate.easy.config.UpdateConfig;
+import com.xuexiang.xupdate.utils.UpdateUtils;
+
+import org.jetbrains.annotations.NotNull;
+
+public class CustomUpdateConfigProvider implements IUpdateConfigProvider {
+
+    private static final String TAG = CustomUpdateConfigProvider.class.getName();
+
+    @NonNull
+    @NotNull
+    @Override
+    public UpdateConfig getUpdateConfig(@NonNull @NotNull Context context) {
+        return UpdateConfig.create()
+                .setIsDebug(true)                                                     // 开启debug日志
+                .setIsWifiOnly(false)                                                 // 设置非wifi更新
+                .setIsGet(false)                                                      // 设置post方式获取下载参数
+                .setIsAutoMode(true)                                                  // 设置自动更新
+                .setParam("versionCode", UpdateUtils.getVersionCode(context))         // 设置默认公共请求参数
+                .setParam("appKey", context.getPackageName())
+                .setOnUpdateFailureListener(error -> {
+                    Log.i(TAG, "onCreate: =====================>自动更新失败! " + error.getCode() + ", " + error.getDetailMsg());
+                })
+                .setIsSupportSilentInstall(true);                                     // 设置是否支持静默安装,默认是true
+    }
+}

+ 19 - 3
app/src/main/java/com/emato/ich/update/InstallResultReceiver.java

@@ -1,9 +1,12 @@
 package com.emato.ich.update;
 
+import android.app.AlarmManager;
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInstaller;
+import android.os.Build;
 import android.util.Log;
 
 public class InstallResultReceiver extends BroadcastReceiver {
@@ -12,16 +15,29 @@ public class InstallResultReceiver extends BroadcastReceiver {
     @Override
     public void onReceive(Context context, Intent intent) {
         Log.d(TAG, "onReceive: "+intent.getIntExtra(PackageInstaller.EXTRA_STATUS,PackageInstaller.STATUS_FAILURE));
-        if (intent != null) {
+
+        Intent intent1 = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
+        PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent1, PendingIntent.FLAG_ONE_SHOT);
+        AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// 6.0及以上
+            mgr.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, restartIntent);
+
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {// 4.4及以上
+            mgr.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10000, restartIntent);
+        }
+        /*if (intent != null) {
             final int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS,PackageInstaller.STATUS_FAILURE);
             if (status == PackageInstaller.STATUS_SUCCESS) {
                 // TODO 安装成功 启动应用
                 PackageManagerCompat.restartApp(context);
             } else {
                 // 失败
-                Log.e(TAG, "onReceive: 自动安装失败! ");
+                Log.e(TAG, "onReceive: =================================================>自动安装失败! ");
             }
-        }
+        } else {
+            Log.i(TAG, "onReceive: ===================================================>启动失败! ");
+        }*/
     }
 
 }

+ 4 - 1
app/src/main/java/com/emato/ich/update/PackageManagerCompat.java

@@ -14,6 +14,7 @@ import android.util.Log;
 import androidx.annotation.RequiresApi;
 
 import com.emato.ich.MainActivity;
+import com.emato.ich.utils.LoggingUtils;
 
 import java.io.BufferedReader;
 import java.io.Closeable;
@@ -158,9 +159,11 @@ public class PackageManagerCompat {
                 Intent intent1 = new Intent(context, MainActivity.class);
                 intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                 context.startActivity(intent1);
+                Log.i(TAG, "restartApp: ======================================>重启成功");
             }
         } catch (Exception e) {
-            Log.e(TAG, "restartApp: 重启失败! ", e);
+            Log.e(TAG, "restartApp: ======================================>重启失败! ", e);
+            LoggingUtils.sendErrorLog("业务异常: ======================================>重启失败! ", e);
         }
 //        PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_ONE_SHOT);
 //        AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

+ 2 - 0
app/src/main/java/com/emato/ich/utils/BaseUtils.java

@@ -101,6 +101,7 @@ public class BaseUtils {
             while ((line = bufferedreader.readLine()) != null) {
                 //System.out.println(line);
                 sb.append(line);
+                sb.append("\n");
             }
             shellVo.setResult(sb.toString());
             return shellVo;
@@ -153,6 +154,7 @@ public class BaseUtils {
             return packageInfo.versionName;
         } catch (Exception e) {
             Log.e(TAG, "getAppVersion: 获取APP版本失败!", e);
+            LoggingUtils.sendErrorLog("业务异常: 获取APP版本失败! ", e);
         }
         return "";
     }

+ 4 - 0
app/src/main/java/com/emato/ich/utils/FileUtils.java

@@ -28,8 +28,10 @@ public class FileUtils {
             outputStream.write(content.getBytes());
         } catch (FileNotFoundException e) {
             Log.e(TAG, "write: 该路径下没有这个文件!", e);
+            LoggingUtils.sendErrorLog("业务异常: 该路径下没有这个文件! ", e);
         } catch (IOException e) {
             Log.e(TAG, "write: 写入文件失败!", e);
+            LoggingUtils.sendErrorLog("业务异常: 写入文件失败! ", e);
         }
     }
 
@@ -45,8 +47,10 @@ public class FileUtils {
             return builder.toString();
         } catch (FileNotFoundException e) {
             Log.e(TAG, "read: 读取的文件未找到! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 读取的文件未找到! ", e);
         } catch (IOException e) {
             Log.e(TAG, "read: 读取文件出现异常!", e);
+            LoggingUtils.sendErrorLog("业务异常: 读取文件出现异常! ", e);
         }
         return "";
     }

+ 28 - 0
app/src/main/java/com/emato/ich/utils/LoggingUtils.java

@@ -0,0 +1,28 @@
+package com.emato.ich.utils;
+
+import com.emato.ich.message.ICHPublishClient;
+import com.emato.ich.message.ICHTopic;
+
+import org.eclipse.paho.client.mqttv3.MqttMessage;
+
+import java.io.ByteArrayOutputStream;
+
+public class LoggingUtils {
+
+
+    public static void sendErrorLog(String cause, Throwable throwable){
+
+        // TODO 发送异常信息
+        MqttMessage mqttMessage = new MqttMessage();
+        mqttMessage.setQos(1);
+        mqttMessage.setPayload((cause + ": " + (getStackTrace(throwable).toString())).getBytes());
+        ICHPublishClient.getInstance().publish(String.format(ICHTopic.ERROR_LOG_REPORT, BaseUtils.getClientId()), mqttMessage);
+    }
+
+    private static ByteArrayOutputStream getStackTrace(Throwable t) {
+        ByteArrayOutputStream buf = new java.io.ByteArrayOutputStream();
+        t.printStackTrace(new java.io.PrintWriter(buf, true));
+        return buf;
+    }
+
+}

+ 57 - 0
app/src/main/java/com/emato/ich/utils/ResourceUtils.java

@@ -0,0 +1,57 @@
+package com.emato.ich.utils;
+
+import android.content.res.AssetManager;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.nio.charset.StandardCharsets;
+
+public class ResourceUtils {
+
+    private static final String TAG = ResourceUtils.class.getName();
+
+    public static String readStringFromAssert(String s, AssetManager am) {
+
+//        s = "file://android_assets/" + s;
+//
+//        File file = new File(s);
+
+        int len = 0;
+        StringBuilder stringBuffer = new StringBuilder();
+        InputStream is = null;
+        try {
+            is = am.open(s);
+            byte[] bytes = new byte[1024];
+            while ((len = (is.read(bytes))) != -1) {
+                stringBuffer.append(new String(bytes, 0, len));
+            }
+            return stringBuffer.toString();
+        } catch (IOException e) {
+            Log.e(TAG, "readStringFromAssert: 读取json文件失败! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 读取json文件失败! ", e);
+        } catch (Exception e) {
+            Log.e(TAG, "readStringFromAssert: 读取json文件未知错误! ", e);
+            LoggingUtils.sendErrorLog("业务异常: 读取json文件未知错误! ", e);
+        } finally {
+            if (is != null) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    Log.e(TAG, "readStringFromAssert: 关闭流错误! ", e);
+                    LoggingUtils.sendErrorLog("业务异常: 关闭流错误! ", e);
+                }
+            }
+        }
+
+
+        return null;
+    }
+}

+ 32 - 0
app/src/main/java/com/emato/ich/utils/WaitingDialogUtils.java

@@ -0,0 +1,32 @@
+package com.emato.ich.utils;
+
+import android.app.ProgressDialog;
+import android.content.Context;
+
+/**
+ * 加载框
+ */
+public class WaitingDialogUtils {
+
+    private static ProgressDialog progressDialog;
+
+
+    public static void showWaitingDialog(Context context){
+        if (progressDialog == null) {
+            progressDialog = new ProgressDialog(context);
+            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
+        }
+        progressDialog.setMessage("加载中...");
+        progressDialog.setCancelable(true);
+        progressDialog.show();
+    }
+
+    public static void cancelProgressDialog(){
+        if (progressDialog != null) {
+            if (progressDialog.isShowing()) {
+                progressDialog.dismiss();
+            }
+        }
+    }
+
+}

BIN
app/src/main/res/drawable/exception.png


+ 12 - 0
app/src/main/res/drawable/exception_button.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <!-- 设置按钮的四个角为弧形 -->
+    <!-- android:radius 弧形的半径 -->
+    <stroke android:color="@color/black" android:width="2dp"/>
+
+    <corners android:radius="20dip" />
+<!--    <stroke android:color="@color/exception_solid_color" android:width="0.5dp"/>-->
+
+</shape>

BIN
app/src/main/res/drawable/fast_send.png


BIN
app/src/main/res/drawable/large.png


BIN
app/src/main/res/drawable/medium.png


BIN
app/src/main/res/drawable/mini.png


BIN
app/src/main/res/drawable/return1.png


BIN
app/src/main/res/drawable/return_main.png


BIN
app/src/main/res/drawable/send.png


BIN
app/src/main/res/drawable/small.png


BIN
app/src/main/res/drawable/take.png


+ 17 - 20
app/src/main/res/layout/fragment_choose_cabinet.xml

@@ -19,10 +19,10 @@
         android:layout_height="60dp"
         android:layout_x="30dp"
         android:layout_y="363dp"
-        android:background="@color/choose_cabinet_view"
+        android:background="@drawable/mini"
         android:gravity="center"
         android:text="@string/tiny_cabinet"
-        android:textColor="@color/white"
+        android:textColor="@color/black"
         android:textSize="10dp" />
 
     <TextView
@@ -31,10 +31,10 @@
         android:layout_height="65dp"
         android:layout_x="98dp"
         android:layout_y="358dp"
-        android:background="@color/choose_cabinet_view"
+        android:background="@drawable/small"
         android:gravity="center"
         android:text="@string/small_cabinet"
-        android:textColor="@color/white"
+        android:textColor="@color/black"
         android:textSize="15dp" />
 
     <Button
@@ -56,7 +56,7 @@
         android:layout_x="98dp"
         android:layout_y="403dp"
         android:gravity="center"
-        android:textColor="@color/white"
+        android:textColor="@color/black"
         android:textSize="8dp" />
 
     <TextView
@@ -66,7 +66,7 @@
         android:layout_x="30dp"
         android:layout_y="403dp"
         android:gravity="center"
-        android:textColor="@color/white"
+        android:textColor="@color/black"
         android:textSize="8dp" />
 
     <Button
@@ -87,10 +87,10 @@
         android:layout_height="75dp"
         android:layout_x="252dp"
         android:layout_y="348dp"
-        android:background="@color/choose_cabinet_view"
+        android:background="@drawable/large"
         android:gravity="center"
         android:text="@string/big_cabinet"
-        android:textColor="@color/white"
+        android:textColor="@color/black"
         android:textSize="20dp" />
 
     <TextView
@@ -100,7 +100,7 @@
         android:layout_x="252dp"
         android:layout_y="403dp"
         android:gravity="center"
-        android:textColor="@color/white"
+        android:textColor="@color/black"
         android:textSize="8dp" />
 
     <Button
@@ -121,10 +121,10 @@
         android:layout_height="70dp"
         android:layout_x="172dp"
         android:layout_y="353dp"
-        android:background="@color/choose_cabinet_view"
+        android:background="@drawable/medium"
         android:gravity="center"
         android:text="@string/medium_cabinet"
-        android:textColor="@color/white"
+        android:textColor="@color/black"
         android:textSize="18dp" />
 
     <TextView
@@ -134,7 +134,7 @@
         android:layout_x="172dp"
         android:layout_y="403dp"
         android:gravity="center"
-        android:textColor="@color/white"
+        android:textColor="@color/black"
         android:textSize="8dp" />
 
     <Button
@@ -149,15 +149,12 @@
         android:text="@string/choose_btn"
         android:textSize="8dp" />
 
-    <Button
+    <ImageButton
         android:id="@+id/return_btn"
-        android:layout_width="60dp"
+        android:layout_width="80dp"
         android:layout_height="30dp"
-        android:layout_x="31dp"
-        android:layout_y="528dp"
-        android:background="@drawable/button_radius"
-        android:text="@string/return_btn"
-        android:textSize="8dp"
-        android:theme="@style/Theme.ButtonStyle" />
+        android:layout_x="30dp"
+        android:layout_y="560dp"
+        android:background="@drawable/return1" />
 
 </AbsoluteLayout>

+ 84 - 21
app/src/main/res/layout/fragment_exception.xml

@@ -19,20 +19,19 @@
         android:layout_height="50dp"
         android:layout_x="69dp"
         android:layout_y="456dp"
-        android:background="@drawable/button_radius"
         android:text="@string/issue_cancel"
-        android:textSize="10dp" />
+        android:background="@drawable/exception_button"
+        android:theme="@style/Theme.ButtonStyle.WHITE"
+        android:textSize="10dp"
+        android:textColor="@color/black" />
 
-    <Button
+    <ImageButton
         android:id="@+id/return_btn"
-        android:layout_width="60dp"
+        android:layout_width="80dp"
         android:layout_height="30dp"
-        android:layout_x="25dp"
-        android:layout_y="532dp"
-        android:background="@drawable/button_radius"
-        android:text="@string/return_btn"
-        android:textSize="8dp"
-        android:theme="@style/Theme.ButtonStyle" />
+        android:layout_x="30dp"
+        android:layout_y="560dp"
+        android:background="@drawable/return1" />
 
     <Button
         android:id="@+id/issue_open_again"
@@ -40,19 +39,23 @@
         android:layout_height="50dp"
         android:layout_x="204dp"
         android:layout_y="336dp"
-        android:background="@drawable/button_radius"
         android:text="@string/issue_open_again"
-        android:textSize="10dp" />
+        android:background="@drawable/exception_button"
+        android:theme="@style/Theme.ButtonStyle.WHITE"
+        android:textSize="10dp"
+        android:textColor="@color/black" />
 
     <Button
         android:id="@+id/issue_size"
         android:layout_width="90dp"
         android:layout_height="50dp"
-        android:layout_x="69dp"
+        android:layout_x="71dp"
         android:layout_y="336dp"
-        android:background="@drawable/button_radius"
         android:text="@string/issue_size"
-        android:textSize="10dp" />
+        android:background="@drawable/exception_button"
+        android:theme="@style/Theme.ButtonStyle.WHITE"
+        android:textSize="10dp"
+        android:textColor="@color/black"/>
 
     <Button
         android:id="@+id/issue_take_cancel"
@@ -60,9 +63,11 @@
         android:layout_height="50dp"
         android:layout_x="69dp"
         android:layout_y="396dp"
-        android:background="@drawable/button_radius"
         android:text="@string/issue_take_cancel"
-        android:textSize="10dp" />
+        android:background="@drawable/exception_button"
+        android:theme="@style/Theme.ButtonStyle.WHITE"
+        android:textSize="10dp"
+        android:textColor="@color/black" />
 
     <Button
         android:id="@+id/issue_other"
@@ -70,9 +75,11 @@
         android:layout_height="50dp"
         android:layout_x="204dp"
         android:layout_y="456dp"
-        android:background="@drawable/button_radius"
         android:text="@string/issue_other"
-        android:textSize="10dp" />
+        android:background="@drawable/exception_button"
+        android:theme="@style/Theme.ButtonStyle.WHITE"
+        android:textSize="10sp"
+        android:textColor="@color/black" />
 
     <Button
         android:id="@+id/issue_door_not_open"
@@ -80,8 +87,64 @@
         android:layout_height="50dp"
         android:layout_x="204dp"
         android:layout_y="396dp"
-        android:background="@drawable/button_radius"
         android:text="@string/issue_door_not_open"
-        android:textSize="10dp" />
+        android:background="@drawable/exception_button"
+        android:theme="@style/Theme.ButtonStyle.WHITE"
+        android:textSize="10dp"
+        android:textColor="@color/black" />
+
+    <TextView
+        android:id="@+id/textView5"
+        android:layout_width="92dp"
+        android:layout_height="52dp"
+        android:layout_x="203dp"
+        android:layout_y="395dp"
+        android:background="@drawable/exception_button"
+        android:text="" />
+
+    <TextView
+        android:id="@+id/textView4"
+        android:layout_width="92dp"
+        android:layout_height="52dp"
+        android:layout_x="70dp"
+        android:layout_y="335dp"
+        android:background="@drawable/exception_button"
+        android:text="" />
+
+    <TextView
+        android:id="@+id/textView3"
+        android:layout_width="92dp"
+        android:layout_height="52dp"
+        android:layout_x="68dp"
+        android:layout_y="395dp"
+        android:background="@drawable/exception_button"
+        android:text="" />
+
+    <TextView
+        android:id="@+id/textView2"
+        android:layout_width="92dp"
+        android:layout_height="52dp"
+        android:layout_x="68dp"
+        android:layout_y="455dp"
+        android:background="@drawable/exception_button"
+        android:text="" />
+
+    <TextView
+        android:id="@+id/textView1"
+        android:layout_width="92dp"
+        android:layout_height="52dp"
+        android:layout_x="203dp"
+        android:layout_y="335dp"
+        android:background="@drawable/exception_button"
+        android:text="" />
+
+    <TextView
+        android:id="@+id/textView6"
+        android:layout_width="92dp"
+        android:layout_height="52dp"
+        android:layout_x="203dp"
+        android:layout_y="455dp"
+        android:background="@drawable/exception_button"
+        android:text="" />
 
 </AbsoluteLayout>

+ 7 - 9
app/src/main/res/layout/fragment_input_info.xml

@@ -5,16 +5,13 @@
     android:focusable="true"
     android:focusableInTouchMode="true">
 
-    <Button
+    <ImageButton
         android:id="@+id/return_btn"
-        android:layout_width="60dp"
+        android:layout_width="80dp"
         android:layout_height="30dp"
-        android:layout_x="25dp"
-        android:layout_y="494dp"
-        android:background="@drawable/button_radius"
-        android:theme="@style/Theme.ButtonStyle"
-        android:text="@string/return_btn"
-        android:textSize="8dp" />
+        android:layout_x="30dp"
+        android:layout_y="560dp"
+        android:background="@drawable/return1" />
 
     <EditText
         android:id="@+id/mail_no"
@@ -89,7 +86,8 @@
         android:layout_x="228dp"
         android:layout_y="429dp"
         android:text="@string/cancel_btn"
-        android:textSize="10dp" />
+        android:textSize="12sp"
+        android:textStyle="bold" />
 
     <Button
         android:id="@+id/input_button0"

+ 51 - 31
app/src/main/res/layout/fragment_main.xml

@@ -1,51 +1,71 @@
 <?xml version="1.0" encoding="utf-8"?>
 <AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
+    <!--    <Button-->
+<!--        android:id="@+id/send_btn"-->
+<!--        android:layout_width="120dp"-->
+<!--        android:layout_height="70dp"-->
+<!--        android:layout_x="32dp"-->
+<!--        android:layout_y="377dp"-->
+<!--        android:background="@drawable/send1"-->
+<!--        android:text="@string/send_btn"-->
+<!--        android:textSize="20sp"-->
+<!--        android:textStyle="bold" />-->
+
+<!--    <Button-->
+<!--        android:id="@+id/take_btn"-->
+<!--        android:layout_width="120dp"-->
+<!--        android:layout_height="70dp"-->
+<!--        android:layout_x="32dp"-->
+<!--        android:layout_y="477dp"-->
+<!--        android:background="@drawable/take"-->
+<!--        android:text="@string/take_btn"-->
+<!--        android:textSize="20sp"-->
+<!--        android:textStyle="bold" />-->
+
     <TextView
         android:id="@+id/fast_take_send_bg"
-        android:layout_width="160dp"
-        android:layout_height="250dp"
-        android:layout_x="165dp"
-        android:layout_y="328dp"
+        android:layout_width="120dp"
+        android:layout_height="185dp"
+        android:layout_x="205dp"
+        android:layout_y="376dp"
         android:background="@drawable/textview_border"
         android:gravity="center_horizontal"
         android:paddingTop="15dp"
         android:text="@string/fast_take_or_send"
-        android:textSize="20sp" />
-
-    <TextView
-        android:id="@+id/fast_take_send"
-        android:layout_width="134dp"
-        android:layout_height="135dp"
-        android:layout_x="177dp"
-        android:layout_y="385dp"
-        android:background="@drawable/e_mp_qrcode_8x8_backup" />
+        android:textSize="13sp" />
 
-    <Button
+    <ImageButton
         android:id="@+id/send_btn"
-        android:layout_width="120dp"
-        android:layout_height="70dp"
-        android:layout_x="32dp"
-        android:layout_y="377dp"
-        android:background="@drawable/button_radius"
-        android:text="@string/send_btn"
+        android:layout_width="150dp"
+        android:layout_height="78dp"
+        android:layout_x="38dp"
+        android:layout_y="376dp"
+        android:background="@drawable/send"
         android:textSize="20sp"
-        android:textStyle="bold"
-        android:theme="@style/Theme.ButtonStyle.GREEN" />
+        android:textStyle="bold" />
 
-    <Button
+    <ImageButton
         android:id="@+id/take_btn"
-        android:layout_width="120dp"
-        android:layout_height="70dp"
-        android:layout_x="32dp"
-        android:layout_y="477dp"
-        android:background="@drawable/button_radius"
-        android:text="@string/take_btn"
+        android:layout_width="150dp"
+        android:layout_height="87dp"
+        android:layout_x="38dp"
+        android:layout_y="476dp"
+        android:background="@drawable/take"
         android:textSize="20sp"
-        android:textStyle="bold"
-        android:theme="@style/Theme.ButtonStyle.GREEN" />
+        android:textStyle="" />
+
+    <TextView
+        android:id="@+id/fast_take_send"
+        android:layout_width="90dp"
+        android:layout_height="90dp"
+        android:layout_x="221dp"
+        android:layout_y="442dp"
+        android:background="@drawable/e_mp_qrcode_8x8_backup" />
 
+    <!--    android:theme="@style/Theme.ButtonStyle.GREEN"-->
 
 </AbsoluteLayout>

+ 7 - 9
app/src/main/res/layout/fragment_send.xml

@@ -10,16 +10,13 @@
     <!--  投递员手机号  -->
 
 
-    <Button
+    <ImageButton
         android:id="@+id/return_btn"
-        android:layout_width="60dp"
+        android:layout_width="80dp"
         android:layout_height="30dp"
-        android:layout_x="28dp"
-        android:layout_y="556dp"
-        android:background="@drawable/button_radius"
-        android:text="@string/return_btn"
-        android:textSize="8dp"
-        android:theme="@style/Theme.ButtonStyle" />
+        android:layout_x="30dp"
+        android:layout_y="560dp"
+        android:background="@drawable/return1" />
 
     <EditText
         android:id="@+id/editTextTextPersonName4"
@@ -94,7 +91,8 @@
         android:layout_x="226dp"
         android:layout_y="441dp"
         android:text="@string/cancel_btn"
-        android:textSize="10dp" />
+        android:textSize="12sp"
+        android:textStyle="bold" />
 
     <Button
         android:id="@+id/input_button0"

+ 6 - 9
app/src/main/res/layout/fragment_send_info_confirm.xml

@@ -3,16 +3,13 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <Button
+    <ImageButton
         android:id="@+id/return_main_btn"
-        android:layout_width="70dp"
-        android:layout_height="30dp"
-        android:layout_x="16dp"
-        android:layout_y="560dp"
-        android:background="@drawable/button_radius"
-        android:theme="@style/Theme.ButtonStyle"
-        android:text="@string/return_main_btn"
-        android:textSize="8dp" />
+        android:layout_width="90dp"
+        android:layout_height="35dp"
+        android:layout_x="14dp"
+        android:layout_y="562dp"
+        android:background="@drawable/return_main" />
 
     <TextView
         android:id="@+id/timeout"

+ 13 - 20
app/src/main/res/layout/fragment_send_main.xml

@@ -12,34 +12,27 @@
         android:gravity="center"
         android:textSize="15dp" />
 
-    <Button
+    <ImageButton
         android:id="@+id/return_btn"
-        android:layout_width="60dp"
+        android:layout_width="80dp"
         android:layout_height="30dp"
-        android:layout_x="25dp"
-        android:layout_y="494dp"
-        android:background="@drawable/button_radius"
-        android:theme="@style/Theme.ButtonStyle"
-        android:text="@string/return_btn"
-        android:textSize="8dp" />
+        android:layout_x="30dp"
+        android:layout_y="560dp"
+        android:background="@drawable/return1" />
 
-    <Button
-        android:id="@+id/send_confirm_btn"
+    <ImageButton
+        android:id="@+id/exception_handle_btn"
         android:layout_width="60dp"
         android:layout_height="60dp"
-        android:layout_x="30dp"
+        android:layout_x="114dp"
         android:layout_y="360dp"
-        android:background="@drawable/button_radius"
-        android:text="@string/send_confirm"
-        android:textSize="10dp" />
+        android:background="@drawable/exception" />
 
-    <Button
-        android:id="@+id/exception_handle_btn"
+    <ImageButton
+        android:id="@+id/send_confirm_btn"
         android:layout_width="60dp"
         android:layout_height="60dp"
-        android:layout_x="100dp"
+        android:layout_x="34dp"
         android:layout_y="360dp"
-        android:background="@drawable/button_radius"
-        android:text="@string/exception_handle"
-        android:textSize="10dp" />
+        android:background="@drawable/fast_send" />
 </AbsoluteLayout>

+ 6 - 9
app/src/main/res/layout/fragment_send_success.xml

@@ -12,16 +12,13 @@
         android:gravity="center"
         android:textSize="15dp" />
 
-    <Button
+    <ImageButton
         android:id="@+id/return_main_btn"
-        android:layout_width="70dp"
-        android:layout_height="30dp"
-        android:layout_x="25dp"
-        android:layout_y="494dp"
-        android:background="@drawable/button_radius"
-        android:theme="@style/Theme.ButtonStyle"
-        android:text="@string/return_main_btn"
-        android:textSize="8dp" />
+        android:layout_width="90dp"
+        android:layout_height="35dp"
+        android:layout_x="14dp"
+        android:layout_y="562dp"
+        android:background="@drawable/return_main" />
 
     <TextView
         android:id="@+id/textView4"

+ 5 - 8
app/src/main/res/layout/fragment_take.xml

@@ -64,15 +64,12 @@
         android:textSize="15dp"
         android:theme="@style/Theme.ButtonStyle.GREEN" />
 
-    <Button
+    <ImageButton
         android:id="@+id/return_btn"
-        android:layout_width="60dp"
+        android:layout_width="80dp"
         android:layout_height="30dp"
-        android:layout_x="42dp"
-        android:layout_y="561dp"
-        android:background="@drawable/button_radius"
-        android:text="@string/return_btn"
-        android:textSize="8dp"
-        android:theme="@style/Theme.ButtonStyle" />
+        android:layout_x="30dp"
+        android:layout_y="560dp"
+        android:background="@drawable/return1" />
 
 </AbsoluteLayout>

+ 7 - 9
app/src/main/res/layout/fragment_take_code.xml

@@ -41,7 +41,8 @@
         android:layout_x="232dp"
         android:layout_y="467dp"
         android:text="@string/cancel_btn"
-        android:textSize="10dp" />
+        android:textSize="12sp"
+        android:textStyle="bold" />
 
     <Button
         android:id="@+id/take_input_button4"
@@ -127,16 +128,13 @@
         android:text="@string/number_5"
         android:textSize="10dp" />
 
-    <Button
+    <ImageButton
         android:id="@+id/return_btn"
-        android:layout_width="60dp"
+        android:layout_width="80dp"
         android:layout_height="30dp"
-        android:layout_x="41dp"
-        android:layout_y="571dp"
-        android:background="@drawable/button_radius"
-        android:text="@string/return_btn"
-        android:textSize="8dp"
-        android:theme="@style/Theme.ButtonStyle" />
+        android:layout_x="32dp"
+        android:layout_y="574dp"
+        android:background="@drawable/return1" />
 
     <Button
         android:id="@+id/take_input_button0"

+ 6 - 9
app/src/main/res/layout/fragment_take_success.xml

@@ -24,16 +24,13 @@
         android:text="@string/open_cabinet_hint_ok"
         android:textSize="30dp" />
 
-    <Button
+    <ImageButton
         android:id="@+id/return_main_btn"
-        android:layout_width="60dp"
-        android:layout_height="30dp"
-        android:layout_x="52dp"
-        android:layout_y="540dp"
-        android:background="@drawable/button_radius"
-        android:text="@string/return_main_btn"
-        android:textSize="6dp"
-        android:theme="@style/Theme.ButtonStyle" />
+        android:layout_width="90dp"
+        android:layout_height="35dp"
+        android:layout_x="14dp"
+        android:layout_y="562dp"
+        android:background="@drawable/return_main" />
 
     <Button
         android:id="@+id/re_open_cabinet_btn"

+ 43 - 3
app/src/main/res/values-night/themes.xml

@@ -2,15 +2,55 @@
     <!-- Base application theme. -->
     <style name="Theme.Ichandroid" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
         <!-- Primary brand color. -->
-        <item name="colorPrimary">@color/purple_200</item>
+        <item name="colorPrimary">@color/send_btn</item>
+        <!-- 状态栏颜色 -->
+        <item name="colorPrimaryVariant">@color/status_bar_color</item>
+        <item name="colorOnPrimary">@color/white</item>
+        <!-- Secondary brand color. -->
+        <item name="colorSecondary">@color/teal_200</item>
+        <item name="colorSecondaryVariant">@color/teal_700</item>
+        <item name="colorOnSecondary">@color/black</item>
+        <!-- Status bar color. -->
+        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
+        <!-- Customize your theme here. -->
+    </style>
+    <style name="Theme.aaa" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
+        <!-- Primary brand color. -->
+        <item name="colorPrimary">@color/take_btn</item>
         <item name="colorPrimaryVariant">@color/purple_700</item>
-        <item name="colorOnPrimary">@color/black</item>
+        <item name="colorOnPrimary">@color/white</item>
         <!-- Secondary brand color. -->
         <item name="colorSecondary">@color/teal_200</item>
-        <item name="colorSecondaryVariant">@color/teal_200</item>
+        <item name="colorSecondaryVariant">@color/teal_700</item>
         <item name="colorOnSecondary">@color/black</item>
         <!-- Status bar color. -->
         <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
         <!-- Customize your theme here. -->
     </style>
+    <style name="Theme.Ichandroid.NoActionBar">
+        <item name="windowActionBar">false</item>
+        <item name="windowNoTitle">true</item>
+    </style>
+    <!-- 返回键 -->
+    <style name="Theme.ButtonStyle" parent="Theme.MaterialComponents.Light.NoActionBar">
+        <item name="colorPrimary">@color/return_color</item>
+        <item name="colorPrimaryVariant">@color/main_label_bg</item>
+        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
+    </style>
+    <!-- 部分按钮 -->
+    <style name="Theme.ButtonStyle.GREEN" parent="Theme.MaterialComponents.Light.NoActionBar">
+        <item name="colorPrimary">@color/confirm_btn</item>
+    </style>
+    <!-- 确认按钮 -->
+    <style name="Theme.ButtonStyle.CONFIRM" parent="Theme.MaterialComponents.Light.NoActionBar">
+        <item name="colorPrimary">@color/input_confirm</item>
+    </style>
+    <style name="Theme.Ichandroid.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
+
+    <style name="Theme.Ichandroid.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
+
+    <!--  异常按钮  -->
+    <style name="Theme.ButtonStyle.WHITE"  parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge">
+        <item name="colorPrimary">@color/white</item>
+    </style>
 </resources>

+ 16 - 5
app/src/main/res/values/colors.xml

@@ -6,14 +6,25 @@
     <color name="purple_700">#c9dd22</color>
     <color name="teal_200">#FF03DAC5</color>
     <color name="teal_700">#FF018786</color>
-    <color name="black">#FF000000</color>
+    <color name="black">#000000</color>
     <color name="white">#FFFFFFFF</color>
-    <color name="send_btn">#75FF90</color>
+    <!--  键盘按钮  -->
+    <!--    <color name="send_btn">#75FF90</color>-->
+    <color name="send_btn">#9bdf46</color>
     <color name="take_btn">#EBBA3A</color>
     <color name="main_label_bg">#4E4C4D</color>
+    <!--  选择柜子类型背景颜色  -->
     <color name="choose_cabinet_view">#9DDA99</color>
-    <color name="input_confirm">#20E45E</color>
-    <color name="confirm_btn">#0eb83a</color>
-    <color name="return_color">#c9dd22</color>
+    <!--  确认键  -->
+<!--    <color name="input_confirm">#20E45E</color>-->
+    <color name="input_confirm">#e9f679</color>
+    <!--  主页按钮以及大按钮  -->
+    <color name="confirm_btn">#25a55f</color>
+    <!--  返回按钮  -->
+<!--    <color name="return_color">#c9dd22</color>-->
+    <color name="return_color">#346473</color>
+    <!--  状态栏  -->
     <color name="status_bar_color">#798E91</color>
+    <!--  异常页面边框颜色  -->
+    <color name="exception_solid_color">#cccccc</color>
 </resources>

+ 3 - 2
app/src/main/res/values/strings.xml

@@ -6,7 +6,8 @@
     <string name="take_fragment_label">快速取件</string>
     <string name="take_btn">我要取件</string>
     <string name="send_btn">我要投递</string>
-    <string name="fast_take_or_send">快速投递/取件</string>
+<!--    <string name="fast_take_or_send">快速投递/取件</string>-->
+    <string name="fast_take_or_send">微信扫码快速取件</string>
     <string name="next">Next</string>
     <string name="previous">Previous</string>
     <string name="number_1">1</string>
@@ -19,7 +20,7 @@
     <string name="number_8">8</string>
     <string name="number_9">9</string>
     <string name="number_0">0</string>
-    <string name="cancel_btn">X</string>
+    <string name="cancel_btn"></string>
     <string name="confirm_btn">确 认</string>
     <string name="input_recipients_phone_confirm">请再次输入取件人手机号</string>
     <string name="input_send_password">请输入投递人密码</string>

+ 8 - 1
app/src/main/res/values/themes.xml

@@ -3,7 +3,8 @@
     <style name="Theme.Ichandroid" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
         <!-- Primary brand color. -->
         <item name="colorPrimary">@color/send_btn</item>
-        <item name="colorPrimaryVariant">@color/purple_700</item>
+        <!-- 状态栏颜色 -->
+        <item name="colorPrimaryVariant">@color/status_bar_color</item>
         <item name="colorOnPrimary">@color/white</item>
         <!-- Secondary brand color. -->
         <item name="colorSecondary">@color/teal_200</item>
@@ -47,4 +48,10 @@
     <style name="Theme.Ichandroid.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
 
     <style name="Theme.Ichandroid.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
+
+    <!--  异常按钮  -->
+    <style name="Theme.ButtonStyle.WHITE"  parent="Theme.MaterialComponents.DayNight.NoActionBar.Bridge">
+        <item name="colorPrimary">@color/white</item>
+    </style>
+
 </resources>