diff --git a/.qoder/rules/rules_ox_android.md b/.qoder/rules/rules_ox_android.md new file mode 100644 index 0000000..02048d3 --- /dev/null +++ b/.qoder/rules/rules_ox_android.md @@ -0,0 +1,4 @@ +--- +trigger: always_on +alwaysApply: true +--- diff --git a/app/src/main/java/com/ouxuan/oxface/MainActivity.java b/app/src/main/java/com/ouxuan/oxface/MainActivity.java index fc237f7..696b5a6 100644 --- a/app/src/main/java/com/ouxuan/oxface/MainActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/MainActivity.java @@ -650,7 +650,7 @@ public class MainActivity extends AppCompatActivity { // 获取进入按钮并设置为加载状态 View buttonEnter = dialog.findViewById(R.id.buttonEnter); if (buttonEnter != null) { - buttonEnter.setEnabled(false); + // buttonEnter.setEnabled(false); TextView buttonText = (TextView) buttonEnter; buttonText.setText("正在进入..."); } @@ -694,6 +694,11 @@ public class MainActivity extends AppCompatActivity { * @param selectedPad 选中的Pad信息 */ private void selectPadAndEnter(Dialog dialog, View buttonEnter, PadApiService.PadInfo selectedPad) { + System.out.println("MainActivity: selectPadAndEnter called"); + System.out.println("MainActivity: selectPadAndEnter thread: " + Thread.currentThread().getName()); + android.util.Log.d("MainActivity", "selectPadAndEnter called"); + android.util.Log.d("MainActivity", "selectPadAndEnter thread: " + Thread.currentThread().getName()); + // 禁用按钮防止重复点击 buttonEnter.setEnabled(false); @@ -702,7 +707,7 @@ public class MainActivity extends AppCompatActivity { String originalText = buttonText.getText().toString(); // 显示loading文字 - buttonText.setText("正在进入..."); + buttonText.setText("已自动选择设备..."); // 获取所需参数 int hardwareId = selectedPad.getHardwareId(); @@ -713,10 +718,18 @@ public class MainActivity extends AppCompatActivity { android.util.Log.d("MainActivity", "=== 设备选择参数 ==="); android.util.Log.d("MainActivity", "Hardware ID: " + hardwareId); android.util.Log.d("MainActivity", "Device ID: " + deviceId); + android.util.Log.d("MainActivity", "token: " + token); android.util.Log.d("MainActivity", "Token: " + (token != null && !token.isEmpty() ? "present" : "null")); android.util.Log.d("MainActivity", "Selected Pad Name: " + selectedPad.getHardwareName()); android.util.Log.d("MainActivity", "=========================="); + // 添加更多调试信息 + System.out.println("MainActivity: About to call selectPadWithFullResponse"); + System.out.println("MainActivity: hardwareId: " + hardwareId); + System.out.println("MainActivity: deviceId: " + deviceId); + System.out.println("MainActivity: token: " + (token != null ? "present" : "null")); + System.out.println("MainActivity: selectedPad: " + (selectedPad != null ? selectedPad.getHardwareName() : "null")); + // 调用Pad选择API(使用新的API格式,支持完整API响应) NetworkUtils.selectPadWithFullResponse(hardwareId, deviceId, token, new CompleteApiResponseCallback() { @@ -724,7 +737,7 @@ public class MainActivity extends AppCompatActivity { public void onSuccessWithFullResponse(ApiResponse apiResponse) { // 选择成功,保存完整的API响应数据(code和data) showToast("进入 " + selectedPad.getHardwareName() + " 成功!"); - + android.util.Log.d("MainActivity", "=== onSuccessWithFullResponse ==="); // 保存完整的API响应数据到本地进行持久化保存 deviceSelectDataManager.saveCompleteApiResponse(apiResponse, selectedPad); @@ -741,11 +754,38 @@ public class MainActivity extends AppCompatActivity { android.util.Log.d("MainActivity", "API Message: " + deviceSelectDataManager.getApiResponseMessage()); android.util.Log.d("MainActivity", "==============================="); - // 新增:调用获取小程序码接口 - fetchAndSaveMiniQrcode(token, hardwareId, dialog, buttonEnter, buttonText, originalText); + // 添加成功信息输出到日志 + LogManager.logInfo("MainActivity", "设备选择成功: " + selectedPad.getHardwareName() + + ", Hardware ID: " + hardwareId + + ", API Code: " + apiResponse.getCode()); + + // 新增:调用获取小程序码接口和上传人脸小程序码接口 + // 使用计数器确保两个请求都完成后再进入人脸识别界面 + final int[] completedRequests = {0}; + final Object lock = new Object(); + + // 完成一个请求的回调 + Runnable onOneRequestComplete = new Runnable() { + @Override + public void run() { + synchronized (lock) { + completedRequests[0]++; + android.util.Log.d("MainActivity", "请求完成计数: " + completedRequests[0] + "/2"); + + // 当两个请求都完成时,进入人脸识别界面 + if (completedRequests[0] >= 2) { + android.util.Log.d("MainActivity", "所有请求完成,准备进入人脸识别界面"); + initializeFaceSDKIfNeeded(dialog, buttonEnter, buttonText, originalText); + } + } + } + }; + + // 调用获取小程序码接口 + fetchAndSaveMiniQrcode(token, hardwareId, dialog, buttonEnter, buttonText, originalText, onOneRequestComplete); - // 新增:调用获取上传人脸小程序码接口 - fetchAndSaveUploadFaceMiniQrcode(token, hardwareId, dialog, buttonEnter, buttonText, originalText); + // 调用获取上传人脸小程序码接口 + fetchAndSaveUploadFaceMiniQrcode(token, hardwareId, dialog, buttonEnter, buttonText, originalText, onOneRequestComplete); } @Override @@ -768,10 +808,24 @@ public class MainActivity extends AppCompatActivity { } @Override + public void onException(Throwable throwable) { + // 异常处理 + showToast("选择设备时发生异常: " + throwable.getMessage()); + + // 恢复按钮状态 + buttonEnter.setEnabled(true); + buttonText.setText(originalText); + } + + @Override public void onComplete() { // 请求完成 + android.util.Log.d("MainActivity", "设备选择请求完成"); } }); + + System.out.println("MainActivity: selectPadWithFullResponse method called"); + System.out.println("MainActivity: After calling selectPadWithFullResponse, thread: " + Thread.currentThread().getName()); } /** @@ -812,8 +866,11 @@ public class MainActivity extends AppCompatActivity { android.util.Log.e("MainActivity", logMessage, e); LogManager.logError("FaceSDK", logMessage, e); - // 发生异常时,直接进入人脸识别界面 - enterFaceRecognitionActivity(dialog); + // 即使发生异常,也要确保弹框被关闭 + if (dialog != null && dialog.isShowing()) { + dialog.dismiss(); + } + currentDialog = null; // 清除引用 } } @@ -1199,8 +1256,9 @@ public class MainActivity extends AppCompatActivity { * @param buttonEnter 进入按钮 * @param buttonText 按钮文字视图 * @param originalText 原始按钮文字 + * @param onComplete 请求完成回调 */ - private void fetchAndSaveMiniQrcode(String token, int hardwareId, Dialog dialog, View buttonEnter, TextView buttonText, String originalText) { + private void fetchAndSaveMiniQrcode(String token, int hardwareId, Dialog dialog, View buttonEnter, TextView buttonText, String originalText, Runnable onComplete) { // 调用获取小程序码接口 NetworkUtils.miniQrcode(token, hardwareId, new NetworkCallback() { @Override @@ -1228,8 +1286,10 @@ public class MainActivity extends AppCompatActivity { LogManager.logWarning("MainActivity", "获取到的小程序码数据为空或URL为空"); } - // 继续执行后续流程 - initializeFaceSDKIfNeeded(dialog, buttonEnter, buttonText, originalText); + // 执行完成回调 + if (onComplete != null) { + onComplete.run(); + } } @Override @@ -1238,8 +1298,10 @@ public class MainActivity extends AppCompatActivity { android.util.Log.e("MainActivity", "获取小程序码失败 - 错误码: " + errorCode + ", 错误信息: " + errorMessage); LogManager.logError("MainActivity", "获取小程序码失败 - 错误码: " + errorCode + ", 错误信息: " + errorMessage); - // 即使获取小程序码失败,也继续执行后续流程 - initializeFaceSDKIfNeeded(dialog, buttonEnter, buttonText, originalText); + // 即使获取小程序码失败,也执行完成回调 + if (onComplete != null) { + onComplete.run(); + } } @Override @@ -1257,8 +1319,9 @@ public class MainActivity extends AppCompatActivity { * @param buttonEnter 进入按钮 * @param buttonText 按钮文字视图 * @param originalText 原始按钮文字 + * @param onComplete 请求完成回调 */ - private void fetchAndSaveUploadFaceMiniQrcode(String token, int hardwareId, Dialog dialog, View buttonEnter, TextView buttonText, String originalText) { + private void fetchAndSaveUploadFaceMiniQrcode(String token, int hardwareId, Dialog dialog, View buttonEnter, TextView buttonText, String originalText, Runnable onComplete) { // 获取品牌ID int brandId = loginDataManager.getBrandId(); @@ -1266,8 +1329,10 @@ public class MainActivity extends AppCompatActivity { if (brandId <= 0) { android.util.Log.e("MainActivity", "无效的品牌ID: " + brandId); LogManager.logError("MainActivity", "获取上传人脸小程序码失败 - 无效的品牌ID: " + brandId); - // 即使获取上传人脸小程序码失败,也继续执行后续流程 - initializeFaceSDKIfNeeded(dialog, buttonEnter, buttonText, originalText); + // 即使获取上传人脸小程序码失败,也执行完成回调 + if (onComplete != null) { + onComplete.run(); + } return; } @@ -1298,8 +1363,10 @@ public class MainActivity extends AppCompatActivity { LogManager.logWarning("MainActivity", "获取到的上传人脸小程序码数据为空或URL为空"); } - // 继续执行后续流程 - initializeFaceSDKIfNeeded(dialog, buttonEnter, buttonText, originalText); + // 执行完成回调 + if (onComplete != null) { + onComplete.run(); + } } @Override @@ -1308,8 +1375,10 @@ public class MainActivity extends AppCompatActivity { android.util.Log.e("MainActivity", "获取上传人脸小程序码失败 - 错误码: " + errorCode + ", 错误信息: " + errorMessage); LogManager.logError("MainActivity", "获取上传人脸小程序码失败 - 错误码: " + errorCode + ", 错误信息: " + errorMessage); - // 即使获取上传人脸小程序码失败,也继续执行后续流程 - initializeFaceSDKIfNeeded(dialog, buttonEnter, buttonText, originalText); + // 即使获取上传人脸小程序码失败,也执行完成回调 + if (onComplete != null) { + onComplete.run(); + } } @Override diff --git a/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java b/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java index 70b4b52..caea3ad 100644 --- a/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/OXFaceOnlineActivity.java @@ -1,8 +1,10 @@ package com.ouxuan.oxface; import android.app.ActivityManager; +import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -165,6 +167,7 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi private int modeType = 0; // 1验证码验证 2人脸验证 3扫码验证 4扫码器验证 private String verifyCode = ""; // 验证码 private com.ouxuan.oxface.data.LoginDataManager loginDataManager; // 新增LoginDataManager实例 + private CameraControlReceiver cameraControlReceiver; // 新增摄像头控制广播接收器实例 @Override protected void onCreate(Bundle savedInstanceState) { @@ -1040,6 +1043,15 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi if (base64img != null) { // 这里可以处理base64数据,如上传到服务器等 Log.i(TAG, "checkResultOnline: 获取到人脸base64数据"); + + // 保存人脸base64数据到verifyCode变量 + verifyCode = base64img; + + // 设置模式为2(人脸验证) + modeType = 2; + + // 自动调用订单核销方法 + getCheckOrder(); // 处理完成后重置标志 needSendFaceImage = false; @@ -1550,9 +1562,8 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi */ private void handleFaceCheck(String token, int hardwareId) { LogManager.logInfo(TAG, "人脸验证"); - // 注意:在实际实现中,需要传入人脸base64数据 - // 这里只是示例,实际应用中需要获取当前检测到的人脸base64数据 - String faceBase64 = ""; // 需要从当前检测到的人脸获取base64数据 + // 从verifyCode变量中获取人脸base64数据 + String faceBase64 = verifyCode; // 使用verifyCode变量中保存的人脸base64数据 if (faceBase64 == null || faceBase64.isEmpty()) { LogManager.logError(TAG, "人脸数据为空"); @@ -1570,12 +1581,14 @@ public class OXFaceOnlineActivity extends BaseActivity implements View.OnClickLi @Override public void onSuccess(com.ouxuan.oxface.network.api.PadApiService.CheckOrderResult data) { LogManager.logInfo(TAG, "人脸验证成功"); + LogManager.logInfo(TAG, "人脸验证接口返回数据: " + (data != null ? data.toString() : "null")); handleCheckOrderSuccess(data, modeType); } @Override public void onError(int errorCode, String errorMessage) { LogManager.logError(TAG, "人脸验证失败: " + errorMessage); + LogManager.logError(TAG, "人脸验证错误码: " + errorCode + ", 错误信息: " + errorMessage); handleCheckOrderError(errorCode, errorMessage, modeType); } diff --git a/app/src/main/java/com/ouxuan/oxface/data/DeviceSelectDataManager.java b/app/src/main/java/com/ouxuan/oxface/data/DeviceSelectDataManager.java index 2471495..307fbc2 100644 --- a/app/src/main/java/com/ouxuan/oxface/data/DeviceSelectDataManager.java +++ b/app/src/main/java/com/ouxuan/oxface/data/DeviceSelectDataManager.java @@ -373,20 +373,7 @@ public class DeviceSelectDataManager { // 新增:加载小程序码链接 miniQrcodeUrl = preferences.getString(KEY_MINI_QRCODE_URL, null); uploadFaceMiniQrcodeUrl = preferences.getString(KEY_UPLOAD_FACE_MINI_QRCODE_URL, null); - - // 确保sessionToken也被正确加载到内存中 - String sessionToken = preferences.getString(KEY_SESSION_TOKEN, ""); - Log.d(TAG, "从SharedPreferences加载sessionToken: " + (sessionToken != null ? sessionToken.length() : 0) + "字符"); - - if (currentSelectResponse != null && (currentSelectResponse.getSessionToken() == null || currentSelectResponse.getSessionToken().isEmpty())) { - // 如果currentSelectResponse中的sessionToken为空,但SharedPreferences中有,尝试更新 - if (sessionToken != null && !sessionToken.isEmpty()) { - currentSelectResponse.setSessionToken(sessionToken); - Log.d(TAG, "通过setSessionToken更新currentSelectResponse中的sessionToken成功"); - } - } else if (currentSelectResponse != null) { - Log.d(TAG, "currentSelectResponse中已有sessionToken: " + (currentSelectResponse.getSessionToken() != null ? currentSelectResponse.getSessionToken().length() : 0) + "字符"); - } + if (apiResponseCode > 0 || (apiResponseDataJson != null && !apiResponseDataJson.isEmpty())) { Log.d(TAG, "从本地存储恢复API响应数据成功"); diff --git a/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java b/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java index 7010f59..b1cc97d 100644 --- a/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java +++ b/app/src/main/java/com/ouxuan/oxface/network/NetworkManager.java @@ -235,7 +235,7 @@ public class NetworkManager { } } catch (Exception e) { // 解析异常 - LogManager.logError(TAG, "网络请求解析异常: " + e.getMessage(), e); + android.util.Log.e(TAG, "网络请求解析异常: " + e.getMessage(), e); mainHandler.post(() -> { callback.onException(e); callback.onComplete(); @@ -246,7 +246,7 @@ public class NetworkManager { @Override public void onFailure(Call call, java.io.IOException e) { // 网络请求失败 - LogManager.logError(TAG, "网络请求失败: " + e.getMessage(), e); + android.util.Log.e(TAG, "网络请求失败: " + e.getMessage(), e); mainHandler.post(() -> { callback.onException(e); callback.onComplete(); diff --git a/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java b/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java index ade09d6..9a87e12 100644 --- a/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java +++ b/app/src/main/java/com/ouxuan/oxface/network/api/PadApiService.java @@ -501,6 +501,16 @@ public interface PadApiService { public long getValidUntil() { return validUntil; } public void setValidUntil(long validUntil) { this.validUntil = validUntil; } + + @Override + public String toString() { + return "PadSelectResponse{" + + "hardwareId=" + hardwareId + + ", hardwareName='" + hardwareName + '\'' + + ", name='" + name + '\'' + + ", sessionToken='" + sessionToken + '\'' + + '}'; + } } /** @@ -568,13 +578,13 @@ public interface PadApiService { private int isPvfaceManyLeave; @SerializedName("support_verify_modules") - private String supportVerifyModules; + private java.util.List supportVerifyModules; // 修改为List类型 @SerializedName("mark") private String mark; @SerializedName("extension") - private String extension; + private PadExtension extension; @SerializedName("username") private String username; @@ -679,14 +689,15 @@ public interface PadApiService { public int getIsPvfaceManyLeave() { return isPvfaceManyLeave; } public void setIsPvfaceManyLeave(int isPvfaceManyLeave) { this.isPvfaceManyLeave = isPvfaceManyLeave; } - public String getSupportVerifyModules() { return supportVerifyModules; } - public void setSupportVerifyModules(String supportVerifyModules) { this.supportVerifyModules = supportVerifyModules; } + // 修改getter和setter方法 + public java.util.List getSupportVerifyModules() { return supportVerifyModules; } + public void setSupportVerifyModules(java.util.List supportVerifyModules) { this.supportVerifyModules = supportVerifyModules; } public String getMark() { return mark; } public void setMark(String mark) { this.mark = mark; } - public String getExtension() { return extension; } - public void setExtension(String extension) { this.extension = extension; } + public PadExtension getExtension() { return extension; } + public void setExtension(PadExtension extension) { this.extension = extension; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } @@ -732,6 +743,204 @@ public interface PadApiService { } /** + * Pad配置扩展信息模型 + */ + public static class PadExtension { + @SerializedName("pad_setting") + private PadSetting padSetting; + + // Getters and Setters + public PadSetting getPadSetting() { return padSetting; } + public void setPadSetting(PadSetting padSetting) { this.padSetting = padSetting; } + } + + /** + * Pad设置信息模型 + */ + public static class PadSetting { + @SerializedName("device_detail") + private String deviceDetail; + + @SerializedName("device_type") + private int deviceType; + + @SerializedName("gateCheckLoopOn") + private boolean gateCheckLoopOn; + + @SerializedName("gate_a_close_time") + private int gateACloseTime; + + @SerializedName("gate_ab_always_check") + private boolean gateAbAlwaysCheck; + + @SerializedName("gate_ab_always_check_user_enter") + private boolean gateAbAlwaysCheckUserEnter; + + @SerializedName("gate_ab_camera_score") + private double gateAbCameraScore; + + @SerializedName("gate_ab_close") + private boolean gateAbClose; + + @SerializedName("gate_ab_enable") + private boolean gateAbEnable; + + @SerializedName("gate_ab_enter01_enable") + private boolean gateAbEnter01Enable; + + @SerializedName("gate_ab_gpio") + private boolean gateAbGpio; + + @SerializedName("gate_ab_people_count") + private Object gateAbPeopleCount; + + @SerializedName("gate_ab_people_detect_type") + private int gateAbPeopleDetectType; + + @SerializedName("gate_ab_test_on") + private boolean gateAbTestOn; + + @SerializedName("gate_ab_udp") + private boolean gateAbUdp; + + @SerializedName("gate_camera_485_OX_on") + private boolean gateCamera485OXOn; + + @SerializedName("gate_camera_config_arr") + private java.util.List gateCameraConfigArr; + + @SerializedName("gate_camera_config_index") + private int gateCameraConfigIndex; + + @SerializedName("gate_camera_detect_hard_level") + private boolean gateCameraDetectHardLevel; + + @SerializedName("gate_enter_open_enable") + private boolean gateEnterOpenEnable; + + @SerializedName("gate_open_enable") + private boolean gateOpenEnable; + + @SerializedName("is_auto_detect") + private boolean isAutoDetect; + + @SerializedName("living_control") + private boolean livingControl; + + @SerializedName("timerCheckGateABClose") + private Object timerCheckGateABClose; + + // Getters and Setters + public String getDeviceDetail() { return deviceDetail; } + public void setDeviceDetail(String deviceDetail) { this.deviceDetail = deviceDetail; } + + public int getDeviceType() { return deviceType; } + public void setDeviceType(int deviceType) { this.deviceType = deviceType; } + + public boolean isGateCheckLoopOn() { return gateCheckLoopOn; } + public void setGateCheckLoopOn(boolean gateCheckLoopOn) { this.gateCheckLoopOn = gateCheckLoopOn; } + + public int getGateACloseTime() { return gateACloseTime; } + public void setGateACloseTime(int gateACloseTime) { this.gateACloseTime = gateACloseTime; } + + public boolean isGateAbAlwaysCheck() { return gateAbAlwaysCheck; } + public void setGateAbAlwaysCheck(boolean gateAbAlwaysCheck) { this.gateAbAlwaysCheck = gateAbAlwaysCheck; } + + public boolean isGateAbAlwaysCheckUserEnter() { return gateAbAlwaysCheckUserEnter; } + public void setGateAbAlwaysCheckUserEnter(boolean gateAbAlwaysCheckUserEnter) { this.gateAbAlwaysCheckUserEnter = gateAbAlwaysCheckUserEnter; } + + public double getGateAbCameraScore() { return gateAbCameraScore; } + public void setGateAbCameraScore(double gateAbCameraScore) { this.gateAbCameraScore = gateAbCameraScore; } + + public boolean isGateAbClose() { return gateAbClose; } + public void setGateAbClose(boolean gateAbClose) { this.gateAbClose = gateAbClose; } + + public boolean isGateAbEnable() { return gateAbEnable; } + public void setGateAbEnable(boolean gateAbEnable) { this.gateAbEnable = gateAbEnable; } + + public boolean isGateAbEnter01Enable() { return gateAbEnter01Enable; } + public void setGateAbEnter01Enable(boolean gateAbEnter01Enable) { this.gateAbEnter01Enable = gateAbEnter01Enable; } + + public boolean isGateAbGpio() { return gateAbGpio; } + public void setGateAbGpio(boolean gateAbGpio) { this.gateAbGpio = gateAbGpio; } + + public Object getGateAbPeopleCount() { return gateAbPeopleCount; } + public void setGateAbPeopleCount(Object gateAbPeopleCount) { this.gateAbPeopleCount = gateAbPeopleCount; } + + public int getGateAbPeopleDetectType() { return gateAbPeopleDetectType; } + public void setGateAbPeopleDetectType(int gateAbPeopleDetectType) { this.gateAbPeopleDetectType = gateAbPeopleDetectType; } + + public boolean isGateAbTestOn() { return gateAbTestOn; } + public void setGateAbTestOn(boolean gateAbTestOn) { this.gateAbTestOn = gateAbTestOn; } + + public boolean isGateAbUdp() { return gateAbUdp; } + public void setGateAbUdp(boolean gateAbUdp) { this.gateAbUdp = gateAbUdp; } + + public boolean isGateCamera485OXOn() { return gateCamera485OXOn; } + public void setGateCamera485OXOn(boolean gateCamera485OXOn) { this.gateCamera485OXOn = gateCamera485OXOn; } + + public java.util.List getGateCameraConfigArr() { return gateCameraConfigArr; } + public void setGateCameraConfigArr(java.util.List gateCameraConfigArr) { this.gateCameraConfigArr = gateCameraConfigArr; } + + public int getGateCameraConfigIndex() { return gateCameraConfigIndex; } + public void setGateCameraConfigIndex(int gateCameraConfigIndex) { this.gateCameraConfigIndex = gateCameraConfigIndex; } + + public boolean isGateCameraDetectHardLevel() { return gateCameraDetectHardLevel; } + public void setGateCameraDetectHardLevel(boolean gateCameraDetectHardLevel) { this.gateCameraDetectHardLevel = gateCameraDetectHardLevel; } + + public boolean isGateEnterOpenEnable() { return gateEnterOpenEnable; } + public void setGateEnterOpenEnable(boolean gateEnterOpenEnable) { this.gateEnterOpenEnable = gateEnterOpenEnable; } + + public boolean isGateOpenEnable() { return gateOpenEnable; } + public void setGateOpenEnable(boolean gateOpenEnable) { this.gateOpenEnable = gateOpenEnable; } + + public boolean isAutoDetect() { return isAutoDetect; } + public void setAutoDetect(boolean autoDetect) { isAutoDetect = autoDetect; } + + public boolean isLivingControl() { return livingControl; } + public void setLivingControl(boolean livingControl) { this.livingControl = livingControl; } + + public Object getTimerCheckGateABClose() { return timerCheckGateABClose; } + public void setTimerCheckGateABClose(Object timerCheckGateABClose) { this.timerCheckGateABClose = timerCheckGateABClose; } + } + + /** + * 摄像头配置模型 + */ + public static class CameraConfig { + @SerializedName("cameraIP") + private String cameraIP; + + @SerializedName("method") + private String method; + + @SerializedName("password") + private String password; + + @SerializedName("uri") + private String uri; + + @SerializedName("username") + private String username; + + // Getters and Setters + public String getCameraIP() { return cameraIP; } + public void setCameraIP(String cameraIP) { this.cameraIP = cameraIP; } + + public String getMethod() { return method; } + public void setMethod(String method) { this.method = method; } + + public String getPassword() { return password; } + public void setPassword(String password) { this.password = password; } + + public String getUri() { return uri; } + public void setUri(String uri) { this.uri = uri; } + + public String getUsername() { return username; } + public void setUsername(String username) { this.username = username; } + } + + /** * 订单列表响应模型 */ public static class CheckOrderResponse { diff --git a/app/src/main/java/com/ouxuan/oxface/network/debug/NetworkDebugLogger.java b/app/src/main/java/com/ouxuan/oxface/network/debug/NetworkDebugLogger.java index a346085..123adab 100644 --- a/app/src/main/java/com/ouxuan/oxface/network/debug/NetworkDebugLogger.java +++ b/app/src/main/java/com/ouxuan/oxface/network/debug/NetworkDebugLogger.java @@ -7,6 +7,8 @@ import okhttp3.ResponseBody; import okio.Buffer; import java.io.IOException; import java.net.URLDecoder; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * 网络请求调试日志工具类 @@ -56,7 +58,9 @@ public class NetworkDebugLogger { // 打印响应信息 Log.e(TAG, " 服务端返回:"); if (responseBody != null && !responseBody.isEmpty()) { - Log.e(TAG, responseBody); + // 直接替换掉extension字段的具体数据,统一返回字符串"extension_fixed" + String filteredResponseBody = replaceExtensionField(responseBody); + Log.e(TAG, filteredResponseBody); } else { Log.e(TAG, "空响应"); } @@ -70,6 +74,142 @@ public class NetworkDebugLogger { } /** + * 直接替换掉responseBody中extension字段的具体数据 + * @param responseBody 原始响应体内容 + * @return 替换后的响应体内容 + */ + private static String replaceExtensionField(String responseBody) { + try { + // 使用简单的字符串操作直接替换extension字段 + // 查找extension字段的位置 + int extensionIndex = responseBody.indexOf("\"extension\""); + if (extensionIndex == -1) { + // 如果没有找到extension字段,直接返回原始内容 + return responseBody; + } + + // 查找冒号的位置 + int colonIndex = responseBody.indexOf(":", extensionIndex); + if (colonIndex == -1) { + return responseBody; + } + + // 查找值的开始位置 + int valueStartIndex = colonIndex + 1; + // 跳过空格和制表符 + while (valueStartIndex < responseBody.length() && + (responseBody.charAt(valueStartIndex) == ' ' || responseBody.charAt(valueStartIndex) == '\t')) { + valueStartIndex++; + } + + // 查找值的结束位置 + int valueEndIndex = findValueEndIndex(responseBody, valueStartIndex); + if (valueEndIndex == -1) { + return responseBody; + } + + // 构造新的字符串 + String beforeValue = responseBody.substring(0, valueStartIndex); + String afterValue = responseBody.substring(valueEndIndex); + + return beforeValue + "\"extension_fixed\"" + afterValue; + } catch (Exception e) { + Log.e(TAG, "替换extension字段失败: " + e.getMessage()); + return responseBody; + } + } + + /** + * 查找值的结束位置 + * @param json JSON字符串 + * @param startIndex 值的开始位置 + * @return 值的结束位置 + */ + private static int findValueEndIndex(String json, int startIndex) { + if (startIndex >= json.length()) { + return -1; + } + + char firstChar = json.charAt(startIndex); + + // 处理对象类型 + if (firstChar == '{') { + return findMatchingBracket(json, startIndex, '{', '}'); + } + + // 处理数组类型 + if (firstChar == '[') { + return findMatchingBracket(json, startIndex, '[', ']'); + } + + // 处理字符串类型 + if (firstChar == '"') { + return findEndOfString(json, startIndex); + } + + // 处理其他类型(数字、布尔值、null等) + return findEndOfPrimitiveValue(json, startIndex); + } + + /** + * 查找匹配的括号 + * @param json JSON字符串 + * @param startIndex 开始位置 + * @param openChar 开始括号 + * @param closeChar 结束括号 + * @return 匹配括号的位置,如果未找到返回-1 + */ + private static int findMatchingBracket(String json, int startIndex, char openChar, char closeChar) { + int bracketCount = 1; + for (int i = startIndex + 1; i < json.length(); i++) { + if (json.charAt(i) == openChar) { + bracketCount++; + } else if (json.charAt(i) == closeChar) { + bracketCount--; + if (bracketCount == 0) { + return i + 1; // 包含结束括号 + } + } + } + return -1; // 未找到匹配的括号 + } + + /** + * 查找字符串的结束位置 + * @param json JSON字符串 + * @param startIndex 字符串开始位置(引号位置) + * @return 字符串结束位置(引号后一位) + */ + private static int findEndOfString(String json, int startIndex) { + for (int i = startIndex + 1; i < json.length(); i++) { + if (json.charAt(i) == '"') { + // 检查是否是转义的引号 + if (i == startIndex + 1 || json.charAt(i - 1) != '\\') { + return i + 1; // 包含结束引号 + } + } + } + return -1; // 未找到结束引号 + } + + /** + * 查找基本类型值(数字、布尔值、null)的结束位置 + * @param json JSON字符串 + * @param startIndex 值的开始位置 + * @return 值的结束位置 + */ + private static int findEndOfPrimitiveValue(String json, int startIndex) { + for (int i = startIndex; i < json.length(); i++) { + char c = json.charAt(i); + // 基本类型值的结束标志 + if (c == ',' || c == '}' || c == ']') { + return i; + } + } + return json.length(); // 到达字符串末尾 + } + + /** * 获取请求数据(包括请求体和查询参数) * @param request 请求对象 * @return 请求数据字符串 diff --git a/app/src/main/java/com/ouxuan/oxface/utils/LogManager.java b/app/src/main/java/com/ouxuan/oxface/utils/LogManager.java index d41a820..00d8a0a 100644 --- a/app/src/main/java/com/ouxuan/oxface/utils/LogManager.java +++ b/app/src/main/java/com/ouxuan/oxface/utils/LogManager.java @@ -141,7 +141,7 @@ public class LogManager { */ public static void logInfo(String tag, String message) { if (instance != null) { -// instance.addLogEntry("INFO", tag, message, null); + instance.addLogEntry("INFO", tag, message, null); } android.util.Log.d(tag,message); //切换为logcat输入日志 } @@ -160,7 +160,7 @@ public class LogManager { */ public static void logError(String tag, String message) { if (instance != null) { -// instance.addLogEntry("ERROR", tag, message, null); + instance.addLogEntry("ERROR", tag, message, null); } android.util.Log.e(tag,message); //切换为logcat输入日志 }