oxFaceAndroid
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1717 lines
76 KiB

package com.ouxuan.oxface;
import androidx.appcompat.app.AppCompatActivity;
import android.animation.ObjectAnimator;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.InputType;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
import com.bumptech.glide.request.RequestOptions;
import com.google.gson.Gson;
import com.ouxuan.oxface.data.DeviceSelectDataManager;
import com.ouxuan.oxface.data.LoginDataManager;
import com.ouxuan.oxface.device.DeviceUtils;
import com.ouxuan.oxface.network.api.PadApiService;
import com.ouxuan.oxface.network.api.UserApiService;
import com.ouxuan.oxface.network.callback.CompleteApiResponseCallback;
import com.ouxuan.oxface.network.callback.NetworkCallback;
import com.ouxuan.oxface.network.model.ApiResponse;
import com.ouxuan.oxface.network.utils.NetworkUtils;
import com.ouxuan.oxface.utils.KeepAliveManager;
import com.ouxuan.oxface.utils.AutoStartManager;
import com.ouxuan.oxface.utils.LogManager;
import com.ouxuan.oxface.utils.UtilCodeHelper;
import org.json.JSONException;
import org.json.JSONObject;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private EditText editTextUsername;
private EditText editTextPassword;
private View buttonLogin;
private ImageView imageViewPasswordToggle;
private Toast currentToast; // 用于管理Toast显示状态
private boolean isPasswordVisible = false; // 密码显示状态
private LoginDataManager loginDataManager; // 登录数据管理器
private DeviceSelectDataManager deviceSelectDataManager; // 设备选择数据管理器
private KeepAliveManager keepAliveManager; // 保持活跃管理器
private AutoStartManager autoStartManager; // 自启动管理器
private Dialog currentDialog; // 用于跟踪当前显示的Dialog,防止WindowLeaked错误
// 添加自动启动状态变量
private boolean isAutoStart = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
// 在setContentView之前切换到正常主题,解决白屏问题
setTheme(R.style.Theme_OxFaceLogin);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 隐藏ActionBar以获得全屏效果
if (getSupportActionBar() != null) {
getSupportActionBar().hide();
}
// 初始化视图组件
initViews();
// 初始化登录数据管理器
loginDataManager = LoginDataManager.getInstance(this);
// 初始化设备选择数据管理器
deviceSelectDataManager = DeviceSelectDataManager.getInstance(this);
// 初始化保持活跃管理器并启动(用于24小时无人值守)
keepAliveManager = KeepAliveManager.getInstance(this);
keepAliveManager.startKeepAlive(this);
// 初始化自启动管理器并检查权限
autoStartManager = AutoStartManager.getInstance(this);
autoStartManager.checkAndRequestAutoStartPermission();
// 记录应用启动
LogManager.logOperation("MainActivity", "主界面已初始化,开始24小时无人值守模式");
// 检查是否为自启动
checkAutoStartStatus();
// 检查是否可以自动登录
checkAutoLogin();
// 设置登录按钮点击事件
setupLoginButton();
// 设置按钮触摸动画
setupButtonAnimation();
// 设置密码显示/隐藏切换
setupPasswordToggle();
// 设置长按登录按钮显示日志路径信息(调试功能)
setupLogPathDebug();
//切换第六批设备(0-5)
switchCameraByDeviceType(5);
}
/**
* 初始化视图组件
*/
private void initViews() {
editTextUsername = findViewById(R.id.editTextUsername);
editTextPassword = findViewById(R.id.editTextPassword);
buttonLogin = findViewById(R.id.buttonLogin);
imageViewPasswordToggle = findViewById(R.id.imageViewPasswordToggle);
}
/**
* 检查自启动状态
*/
private void checkAutoStartStatus() {
Intent intent = getIntent();
if (intent != null) {
isAutoStart = intent.getBooleanExtra("auto_start", false);
if (isAutoStart) {
String bootReason = intent.getStringExtra("boot_reason");
String startSource = intent.getStringExtra("start_source");
long bootTime = intent.getLongExtra("boot_time", 0);
long serviceStartTime = intent.getLongExtra("service_start_time", 0);
LogManager.logOperation("MainActivity", "检测到自动启动:" +
(bootReason != null ? bootReason : "无") +
", 来源:" + (startSource != null ? startSource : "直接启动"));
// 显示自启动提示
if ("system_reboot".equals(bootReason)) {
showToast("系统重启后自动恢复,24小时无人值守模式已启动");
} else {
showToast("应用自动启动成功");
}
// 清除Intent中的自启动标识,防止重复处理
intent.removeExtra("auto_start");
intent.removeExtra("boot_reason");
intent.removeExtra("start_source");
intent.removeExtra("boot_time");
intent.removeExtra("service_start_time");
}
}
}
/**
* 检查是否可以自动登录
*/
private void checkAutoLogin() {
if (loginDataManager.canAutoLogin()) {
android.util.Log.d("MainActivity", "检测到有效的本地登录数据,尝试自动登录, isAutoStart: " + isAutoStart);
// 显示自动登录提示
showToast("检测到登录信息,正在自动登录...");
// 延迟一下显示登录成功弹框,给用户看到自动登录的提示
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
// 检查Activity是否仍然有效
if (!isFinishing() && !isDestroyed()) {
if (loginDataManager.isLoggedIn()) {
android.util.Log.d("MainActivity", "自动登录成功!isAutoStart: " + isAutoStart);
showToast("自动登录成功!");
// isAutoStart = true;
// 更新isAutoStart字段为true
isAutoStart = true;
showLoginSuccessDialog(loginDataManager.getLoginData());
} else {
android.util.Log.w("MainActivity", "自动登录失败,本地数据可能已失效");
showToast("自动登录失败,请手动登录");
// 清除可能已失效的登录数据
loginDataManager.clearLoginData();
}
}
}
}, 1000); // 延迟1秒
} else {
android.util.Log.d("MainActivity", "无有效本地登录数据,需要手动登录");
}
}
private void setupLoginButton() {
buttonLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username = editTextUsername.getText().toString().trim();
String password = editTextPassword.getText().toString().trim();
// 在测试环境下,如果用户名和密码都为空,自动填充默认账号
if (isTestEnvironment() && username.isEmpty() && password.isEmpty()) {
username = "00167";
password = "123456";
// 更新输入框显示
editTextUsername.setText(username);
editTextPassword.setText(password);
// 显示提示信息
showToast("测试环境:已自动填充默认账号");
android.util.Log.d("MainActivity", "Test environment: Auto-filled default credentials");
}
if (validateInput(username, password)) {
performLogin(username, password);
}
}
});
}
private void setupButtonAnimation() {
buttonLogin.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 按下时缩小
ObjectAnimator scaleDownX = ObjectAnimator.ofFloat(v, "scaleX", 0.95f);
ObjectAnimator scaleDownY = ObjectAnimator.ofFloat(v, "scaleY", 0.95f);
scaleDownX.setDuration(100);
scaleDownY.setDuration(100);
scaleDownX.start();
scaleDownY.start();
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// 释放时恢复
ObjectAnimator scaleUpX = ObjectAnimator.ofFloat(v, "scaleX", 1.0f);
ObjectAnimator scaleUpY = ObjectAnimator.ofFloat(v, "scaleY", 1.0f);
scaleUpX.setDuration(100);
scaleUpY.setDuration(100);
scaleUpX.start();
scaleUpY.start();
break;
}
return false; // 返回false以确保onClick事件仍然被触发
}
});
}
private boolean validateInput(String username, String password) {
// if (username.isEmpty()) {
// showToast("请输入登录账号");
// editTextUsername.requestFocus();
// return false;
// }
// if (password.isEmpty()) {
// showToast("请输入密码");
// editTextPassword.requestFocus();
// return false;
// }
// if (password.length() < 6) {
// showToast("密码长度至少6位");
// editTextPassword.requestFocus();
// return false;
// }
return true;
}
/**
* 判断是否为测试环境
* @return true 如果是测试环境
*/
private boolean isTestEnvironment() {
// 根据 NetworkConfig 中的 BASE_URL 判断是否为测试环境
return com.ouxuan.oxface.network.NetworkConfig.BASE_URL.contains("testmanager");
}
private void performLogin(String username, String password) {
// 使用DeviceUtils获取设备ID进行真实的API调用
String deviceId = DeviceUtils.getFormattedDeviceId(this);
// 打印设备信息到日志(便于调试)
DeviceUtils.logDeviceInfo(this);
NetworkUtils.padLogin(username, password, deviceId, new NetworkCallback<PadApiService.PadLoginResponse>() {
@Override
public void onStart() {
// 显示loading状态
showToast("正在登录...");
}
@Override
public void onSuccess(PadApiService.PadLoginResponse data) {
// 登录成功,使用LoginDataManager保存登录数据
android.util.Log.d("MainActivity", "Login success - data: " + (data != null ? data.toString() : "null"));
if (data != null) {
android.util.Log.d("MainActivity", "Token: " + data.getToken());
android.util.Log.d("MainActivity", "Name: " + data.getName());
android.util.Log.d("MainActivity", "Brand ID: " + data.getBrandId());
}
// 使用LoginDataManager保存登录数据
loginDataManager.saveLoginData(data);
// 打印存储的data
android.util.Log.d("MainActivity", "Login Data: " + data.toString());
// 检查Activity是否仍然有效再显示Dialog
if (!isFinishing() && !isDestroyed()) {
// 显示登录成功弹框,传入登录数据
showToast("登录成功!");
showLoginSuccessDialog(data);
}
}
@Override
public void onError(int errorCode, String errorMessage) {
// 登录失败,打印详细错误日志并显示错误信息
android.util.Log.e("MainActivity", "=== 登录接口请求异常 ===");
android.util.Log.e("MainActivity", "Error Code: " + errorCode);
android.util.Log.e("MainActivity", "Error Message: " + errorMessage);
android.util.Log.e("MainActivity", "===========================");
// 根据错误代码显示不同的提示信息
String displayMessage;
switch (errorCode) {
case 502:
displayMessage = "服务器暂时不可用,请稍后再试";
break;
case 400:
displayMessage = "请求参数错误";
break;
case 401:
displayMessage = "用户名或密码错误";
break;
case 403:
displayMessage = "访问被禁止";
break;
case 404:
displayMessage = "登录接口未找到";
break;
case 500:
displayMessage = "服务器内部错误";
break;
case 503:
displayMessage = "服务暂时不可用";
break;
case 504:
displayMessage = "网关超时";
break;
default:
// 如果errorMessage包含具体的错误信息,则显示具体信息,否则显示通用信息
if (errorMessage != null && !errorMessage.isEmpty() && !errorMessage.equals("请求失败: ")) {
displayMessage = errorMessage;
} else {
displayMessage = "登录失败,请检查网络连接";
}
break;
}
// 显示Toast错误信息
showToast(displayMessage);
}
@Override
public void onComplete() {
// 请求完成
}
});
}
/**
* 显示Toast消息,确保只显示最新的消息
* @param message 要显示的消息
*/
private void showToast(String message) {
// 如果之前有Toast正在显示,先取消它
if (currentToast != null) {
currentToast.cancel();
}
// 创建新的Toast并显示
currentToast = Toast.makeText(this, message, Toast.LENGTH_SHORT);
currentToast.show();
}
/**
* 设置密码显示/隐藏切换功能
*/
private void setupPasswordToggle() {
imageViewPasswordToggle.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
togglePasswordVisibility();
}
});
}
/**
* 切换密码的显示/隐藏状态
*/
private void togglePasswordVisibility() {
if (isPasswordVisible) {
// 当前是显示状态,切换为隐藏
editTextPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
imageViewPasswordToggle.setImageResource(R.drawable.ic_eye_closed);
isPasswordVisible = false;
} else {
// 当前是隐藏状态,切换为显示
editTextPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD);
imageViewPasswordToggle.setImageResource(R.drawable.ic_eye_open);
isPasswordVisible = true;
}
// 保持光标在文本末尾
editTextPassword.setSelection(editTextPassword.getText().length());
}
/**
* 显示登录成功弹框
* @param loginData 登录响应数据
*/
private void showLoginSuccessDialog(PadApiService.PadLoginResponse loginData) {
android.util.Log.d("MainActivity", "显示登录成功弹框, isAutoStart: " + isAutoStart);
// 创建自定义弹框
Dialog dialog = new Dialog(this);
currentDialog = dialog; // 保存Dialog引用以防止WindowLeaked错误
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_login_success);
// 设置弹框背景透明并调整尺寸
if (dialog.getWindow() != null) {
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
// 设置弹框宽度为屏幕宽度的85%,确保在屏幕中自然居中
android.view.WindowManager.LayoutParams layoutParams = dialog.getWindow().getAttributes();
android.util.DisplayMetrics displayMetrics = new android.util.DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int screenWidth = displayMetrics.widthPixels;
layoutParams.width = (int) (screenWidth * 0.85); // 设置为屏幕宽度的85%
layoutParams.height = android.view.WindowManager.LayoutParams.WRAP_CONTENT;
dialog.getWindow().setAttributes(layoutParams);
}
// 初始化弹框的组件
Spinner spinnerPlatform = dialog.findViewById(R.id.spinnerPlatform);
View buttonEnter = dialog.findViewById(R.id.buttonEnter);
View buttonClose = dialog.findViewById(R.id.buttonClose);
TextView textViewStoreName = dialog.findViewById(R.id.textViewStoreName);
ImageView imageViewStoreLogo = dialog.findViewById(R.id.imageViewStoreLogo);
// 更新店铺信息
if (loginData != null) {
// 更新店铺名称
if (loginData.getName() != null && !loginData.getName().isEmpty()) {
textViewStoreName.setText("尊敬的" + loginData.getName());
}
// 加载店铺 Logo(如果有的话)
if (loginData.getLogo() != null && !loginData.getLogo().isEmpty()) {
android.util.Log.d("MainActivity", "Loading store logo from: " + loginData.getLogo());
// 使用 Glide 加载网络图片,设置圆形裁剪和默认图片
Glide.with(this)
.load(loginData.getLogo())
.apply(RequestOptions.bitmapTransform(new CircleCrop()))
.placeholder(R.drawable.ic_warriors_logo) // 加载中显示默认图片
.error(R.drawable.ic_warriors_logo) // 加载失败显示默认图片
.into(imageViewStoreLogo);
} else {
// 如果没有 Logo URL,使用默认图片
imageViewStoreLogo.setImageResource(R.drawable.ic_warriors_logo);
}
}
// 设置关闭按钮点击事件
buttonClose.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
currentDialog = null; // 清除引用
}
});
// 设置平台选择下拉框的数据
loadPadList(dialog, spinnerPlatform);
// 设置进入使用按钮点击事件
buttonEnter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int selectedPosition = spinnerPlatform.getSelectedItemPosition();
if (selectedPosition == 0) {
showToast("请选择设备");
} else {
// 获取选中的设备名称
String selectedPlatform = spinnerPlatform.getSelectedItem().toString();
// 显示loading动画
showLoadingInDialog(dialog, buttonEnter, selectedPlatform);
}
}
});
// 显示弹框
dialog.show();
}
/**
* 在弹框中显示loading动画
* @param dialog 弹框实例
* @param buttonEnter 进入按钮
* @param selectedPlatform 选中的平台
*/
private void showLoadingInDialog(Dialog dialog, View buttonEnter, String selectedPlatform) {
// 禁用按钮防止重复点击
buttonEnter.setEnabled(false);
// 禁用设置平台选择下拉框
Spinner spinnerPlatform = dialog.findViewById(R.id.spinnerPlatform);
spinnerPlatform.setEnabled(false);
// 保存原始按钮文字
TextView buttonText = (TextView) buttonEnter;
String originalText = buttonText.getText().toString();
// 显示loading文字
buttonText.setText("正在进入...");
// 注意:这里不再使用延时,而是通过设备选择和SDK初始化流程来控制
// 实际的进入操作会在selectPadAndEnter方法中处理
}
/**
* 获取用户ID
* @return 用户ID
*/
private String getUserId() {
return loginDataManager.getUserId();
}
/**
* 获取认证Token(统一认证方式)
* @return Token字符串
*/
private String getAuthToken() {
return loginDataManager.getAuthToken();
}
/**
* 加载Pad列表数据
* @param dialog 弹框实例
* @param spinner 下拉框组件
*/
private void loadPadList(Dialog dialog, Spinner spinner) {
android.util.Log.d("MainActivity", "开始加载Pad列表, isAutoStart: " + isAutoStart);
// 首先设置默认的加载中选项
String[] loadingItems = {"正在加载设备列表..."};
ArrayAdapter<String> loadingAdapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, loadingItems);
loadingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(loadingAdapter);
// 调用API获取Pad列表,传入登录时获取的stadium_id、device_id和token
if (loginDataManager.isLoggedIn()) {
int stadiumId = loginDataManager.getStadiumId();
String token = loginDataManager.getAuthToken();
String deviceId = DeviceUtils.getFormattedDeviceId(this);
android.util.Log.d("MainActivity", "Loading pad list with stadium_id: " + stadiumId +
", device_id: " + deviceId + ", token: " + (token != null ? "present" : "null"));
NetworkUtils.getPadList(stadiumId, deviceId, token, new NetworkCallback<PadApiService.PadListResponse>() {
@Override
public void onStart() {
// 加载开始
}
@Override
public void onSuccess(PadApiService.PadListResponse data) {
android.util.Log.d("MainActivity", "Pad列表加载成功, isAutoStart: " + isAutoStart);
// 加载成功,更新下拉框数据
java.util.List<PadApiService.PadInfo> padList = data.getPads(); // 使用getPads()而不是getPadList()
java.util.List<String> padNames = new java.util.ArrayList<>();
padNames.add("请选择设备"); // 默认选项
if (padList != null && !padList.isEmpty()) {
for (PadApiService.PadInfo padInfo : padList) {
// 使用hardware_name和status字段
String displayName = padInfo.getHardwareName();
if (padInfo.getStatus() != null && !padInfo.getStatus().equals("unknown")) {
displayName += " (" + padInfo.getStatus() + ")";
}
padNames.add(displayName);
}
android.util.Log.d("MainActivity", "成功加载 " + padList.size() + " 个设备");
android.util.Log.d("MainActivity", "店铺Logo: " + data.getLogo());
android.util.Log.d("MainActivity", "店铺名称: " + data.getName());
} else {
padNames.add("暂无可用设备");
android.util.Log.w("MainActivity", "服务器返回的设备列表为空");
}
// 更新Spinner数据
ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this,
android.R.layout.simple_spinner_item, padNames);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
// 检查是否为自动登录且只有一个真实设备,如果是则自动选择
android.util.Log.d("MainActivity", "检查自动选择条件: isAutoStart=" + isAutoStart +
", padList.size()=" + (padList != null ? padList.size() : 0) +
", padList=" + (padList != null ? padList.toString() : "null"));
if (isAutoStart && padList != null && padList.size() == 1) {
// 清除padNames.add("请选择设备");
android.util.Log.d("MainActivity", "满足自动选择条件,开始自动选择设备");
// 自动选择唯一设备(忽略"请选择设备"这类提示项)
autoSelectSingleDevice(dialog, padList.get(0));
} else {
android.util.Log.d("MainActivity", "不满足自动选择条件,显示设备选择界面");
// 更新进入按钮的点击事件,传入真实的Pad数据
updateEnterButtonClickListener(dialog, padList);
}
}
@Override
public void onError(int errorCode, String errorMessage) {
// 加载失败,打印详细错误日志并显示错误信息
android.util.Log.e("MainActivity", "=== 获取设备列表接口请求异常 ===");
android.util.Log.e("MainActivity", "Error Code: " + errorCode);
android.util.Log.e("MainActivity", "Error Message: " + errorMessage);
android.util.Log.e("MainActivity", "================================");
// 显示错误信息
String[] errorItems = {"加载失败,请重试"};
ArrayAdapter<String> errorAdapter = new ArrayAdapter<>(MainActivity.this,
android.R.layout.simple_spinner_item, errorItems);
errorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(errorAdapter);
showToast("获取设备列表失败: " + errorMessage);
}
});
} else {
// 如果没有登录数据,显示错误
String[] errorItems = {"登录数据丢失,请重新登录"};
ArrayAdapter<String> errorAdapter = new ArrayAdapter<>(this,
android.R.layout.simple_spinner_item, errorItems);
errorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(errorAdapter);
showToast("登录数据丢失,请重新登录");
}
}
/**
* 自动选择唯一设备并进入使用
* @param dialog 弹框实例
* @param padInfo 唯一的Pad信息
*/
private void autoSelectSingleDevice(Dialog dialog, PadApiService.PadInfo padInfo) {
android.util.Log.d("MainActivity", "自动登录且只有一个设备,自动选择设备: " + padInfo.getHardwareName());
showToast("自动选择设备: " + padInfo.getHardwareName());
// 获取进入按钮并设置为加载状态
View buttonEnter = dialog.findViewById(R.id.buttonEnter);
if (buttonEnter != null) {
// buttonEnter.setEnabled(false);
TextView buttonText = (TextView) buttonEnter;
buttonText.setText("正在进入...");
}
// 直接调用选择Pad并进入的方法
selectPadAndEnter(dialog, buttonEnter, padInfo);
}
/**
* 更新进入按钮的点击事件
* @param dialog 弹框实例
* @param padList Pad列表数据
*/
private void updateEnterButtonClickListener(Dialog dialog, java.util.List<PadApiService.PadInfo> padList) {
View buttonEnter = dialog.findViewById(R.id.buttonEnter);
Spinner spinnerPlatform = dialog.findViewById(R.id.spinnerPlatform);
buttonEnter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int selectedPosition = spinnerPlatform.getSelectedItemPosition();
if (selectedPosition == 0) {
showToast("请选择设备");
} else if (padList != null && selectedPosition <= padList.size()) {
// 获取选中的Pad信息
PadApiService.PadInfo selectedPad = padList.get(selectedPosition - 1); // 减1因为第0个是"请选择设备"
// 调用Pad选择API
selectPadAndEnter(dialog, buttonEnter, selectedPad);
} else {
showToast("请选择有效的设备");
}
}
});
}
/**
* 选择Pad并进入使用
* @param dialog 弹框实例
* @param buttonEnter 进入按钮
* @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);
// 保存原始按钮文字
TextView buttonText = (TextView) buttonEnter;
String originalText = buttonText.getText().toString();
// 显示loading文字
buttonText.setText("已自动选择设备...");
// 获取所需参数
int hardwareId = selectedPad.getHardwareId();
String deviceId = DeviceUtils.getFormattedDeviceId(this);
String token = getAuthToken();
// 输出调试日志
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<PadApiService.PadSelectResponse>() {
@Override
public void onSuccessWithFullResponse(ApiResponse<PadApiService.PadSelectResponse> apiResponse) {
// 选择成功,保存完整的API响应数据(code和data)
showToast("进入 " + selectedPad.getHardwareName() + " 成功!");
android.util.Log.d("MainActivity", "=== onSuccessWithFullResponse ===");
// 保存完整的API响应数据到本地进行持久化保存
deviceSelectDataManager.saveCompleteApiResponse(apiResponse, selectedPad);
// 记录操作日志
LogManager.logOperation("MainActivity", "设备选择成功: " + selectedPad.getHardwareName() +
", Hardware ID: " + hardwareId +
", API Code: " + apiResponse.getCode() +
", Data Size: " + (apiResponse.getData() != null ? "present" : "null"));
// 输出保存的数据信息用于调试
android.util.Log.d("MainActivity", "=== 保存的API响应数据 ===");
android.util.Log.d("MainActivity", "API Code: " + deviceSelectDataManager.getApiResponseCode());
android.util.Log.d("MainActivity", "API Data JSON长度: " + deviceSelectDataManager.getApiResponseDataJson().length());
android.util.Log.d("MainActivity", "API Message: " + deviceSelectDataManager.getApiResponseMessage());
android.util.Log.d("MainActivity", "===============================");
// 添加成功信息输出到日志
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, onOneRequestComplete);
}
@Override
public void onError(int errorCode, String errorMessage) {
// 选择失败,打印详细错误日志并显示错误信息
android.util.Log.e("MainActivity", "=== 设备选择接口请求异常 ===");
android.util.Log.e("MainActivity", "Error Code: " + errorCode);
android.util.Log.e("MainActivity", "Error Message: " + errorMessage);
android.util.Log.e("MainActivity", "Hardware ID: " + hardwareId);
android.util.Log.e("MainActivity", "Device ID: " + deviceId);
android.util.Log.e("MainActivity", "Selected Pad: " + (selectedPad != null ? selectedPad.getHardwareName() : "null"));
android.util.Log.e("MainActivity", "==============================");
// 显示错误信息
showToast("选择设备失败: 当前设备ID: " + deviceId + errorMessage);
// 恢复按钮状态
buttonEnter.setEnabled(true);
buttonText.setText(originalText);
}
@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());
}
/**
* 检查是否需要初始化人脸SDK并在需要时执行初始化
*/
private void initializeFaceSDKIfNeeded(Dialog dialog, View buttonEnter, TextView buttonText, String originalText) {
try {
// 检查是否有人脸识别许可证
if (deviceSelectDataManager.hasFaceLicense()) {
String faceLicense = deviceSelectDataManager.getFaceLicense();
String logMessage = "检测到人脸识别许可证,开始初始化人脸SDK,许可证长度: " +
(faceLicense != null ? faceLicense.length() : 0);
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
// 在后台线程中初始化人脸SDK
new Thread(new Runnable() {
@Override
public void run() {
initializeFaceSDK(faceLicense, dialog, buttonEnter, buttonText, originalText);
}
}).start();
} else {
String logMessage = "未检测到有效的人脸识别许可证,跳过人脸SDK初始化,直接进入人脸识别界面";
android.util.Log.w("MainActivity", logMessage);
LogManager.logWarning("FaceSDK", logMessage);
// 没有人脸识别许可证,直接进入人脸识别界面
runOnUiThread(new Runnable() {
@Override
public void run() {
enterFaceRecognitionActivity(dialog);
}
});
}
} catch (Exception e) {
String logMessage = "检查人脸SDK初始化条件时发生异常: " + e.getMessage();
android.util.Log.e("MainActivity", logMessage, e);
LogManager.logError("FaceSDK", logMessage, e);
// 即使发生异常,也要确保弹框被关闭
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
currentDialog = null; // 清除引用
}
}
/**
* 初始化人脸SDK
* @param faceLicense 人脸识别许可证
*/
private void initializeFaceSDK(String faceLicense, Dialog dialog, View buttonEnter, TextView buttonText, String originalText) {
try {
String logMessage = "开始人脸SDK初始化流程...";
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
// 先检查和初始化配置文件
final boolean configSuccess = initAndCheckFaceConfig(this);
// 在UI线程显示配置文件状态提示
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,
configSuccess ? "配置文件加载成功" : "已加载默认配置",
Toast.LENGTH_SHORT).show();
}
});
// 获取FaceSDKManager实例
com.baidu.idl.face.main.finance.manager.FaceSDKManager faceSDKManager =
com.baidu.idl.face.main.finance.manager.FaceSDKManager.getInstance();
// 检查设备是否已经授权
if (faceSDKManager.initStatus == com.baidu.idl.face.main.finance.manager.FaceSDKManager.SDK_INIT_SUCCESS ||
faceSDKManager.initStatus == com.baidu.idl.face.main.finance.manager.FaceSDKManager.SDK_MODEL_LOAD_SUCCESS) {
String alreadyAuthorizedMessage = "设备已授权,无需重复授权";
android.util.Log.d("MainActivity", alreadyAuthorizedMessage);
LogManager.logInfo("FaceSDK", alreadyAuthorizedMessage);
// 获取并记录授权信息
String licenseData = faceSDKManager.getLicenseData(this);
LogManager.logInfo("FaceSDK", "设备授权有效期至: " + licenseData);
// 直接进入人脸识别界面
runOnUiThread(new Runnable() {
@Override
public void run() {
showToast("设备已授权");
enterFaceRecognitionActivity(dialog);
}
});
return;
}
// 创建同步锁以等待初始化完成
final Object initLock = new Object();
final boolean[] initCompleted = {false};
final boolean[] initSuccess = {false};
// 在主线程中执行初始化
runOnUiThread(new Runnable() {
@Override
public void run() {
faceSDKManager.init(MainActivity.this, faceLicense, new com.baidu.idl.face.main.finance.listener.SdkInitListener() {
@Override
public void initStart() {
String logMessage = "人脸SDK授权初始化开始...";
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
}
@Override
public void initLicenseSuccess() {
String logMessage = "人脸SDK授权成功";
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
// 授权成功后继续初始化模型
initFaceModels(faceSDKManager, initLock, initCompleted, initSuccess, dialog, buttonEnter, buttonText, originalText);
}
@Override
public void initLicenseFail(int errorCode, String msg) {
String logMessage = "人脸SDK授权失败 - 错误码: " + errorCode + ", 错误信息: " + msg;
android.util.Log.e("MainActivity", logMessage);
LogManager.logError("FaceSDK", logMessage);
synchronized (initLock) {
initCompleted[0] = true;
initSuccess[0] = false;
initLock.notifyAll();
}
// 授权失败时,仍然进入人脸识别界面
runOnUiThread(new Runnable() {
@Override
public void run() {
enterFaceRecognitionActivity(dialog);
}
});
}
@Override
public void initModelSuccess() {
// 这个回调在init方法中不会触发
}
@Override
public void initModelFail(int errorCode, String msg) {
// 这个回调在init方法中不会触发
}
});
}
});
// 等待初始化完成(最多等待30秒)
synchronized (initLock) {
if (!initCompleted[0]) {
try {
initLock.wait(30000); // 等待最多30秒
} catch (InterruptedException e) {
logMessage = "人脸SDK初始化等待被中断: " + e.getMessage();
android.util.Log.e("MainActivity", logMessage);
LogManager.logError("FaceSDK", logMessage);
}
}
}
// 检查初始化结果
if (initSuccess[0]) {
logMessage = "人脸SDK初始化成功";
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
runOnUiThread(new Runnable() {
@Override
public void run() {
showToast("人脸SDK初始化成功");
// 进入人脸识别界面
enterFaceRecognitionActivity(dialog);
}
});
} else {
logMessage = "人脸SDK初始化失败,但仍进入人脸识别界面";
android.util.Log.e("MainActivity", logMessage);
LogManager.logError("FaceSDK", logMessage);
runOnUiThread(new Runnable() {
@Override
public void run() {
showToast("人脸SDK初始化失败,但仍进入人脸识别界面");
// 即使初始化失败,也进入人脸识别界面
enterFaceRecognitionActivity(dialog);
}
});
}
} catch (Exception e) {
String logMessage = "初始化人脸SDK时发生异常: " + e.getMessage();
android.util.Log.e("MainActivity", logMessage, e);
LogManager.logError("FaceSDK", logMessage, e);
runOnUiThread(new Runnable() {
@Override
public void run() {
showToast("人脸SDK初始化异常: " + e.getMessage());
// 发生异常时,仍然进入人脸识别界面
enterFaceRecognitionActivity(dialog);
}
});
}
}
/**
* 初始化人脸模型
* @param faceSDKManager FaceSDKManager实例
* @param initLock 初始化同步锁
* @param initCompleted 初始化完成标志
* @param initSuccess 初始化成功标志
*/
private void initFaceModels(com.baidu.idl.face.main.finance.manager.FaceSDKManager faceSDKManager,
Object initLock, boolean[] initCompleted, boolean[] initSuccess,
Dialog dialog, View buttonEnter, TextView buttonText, String originalText) {
try {
String logMessage = "开始初始化人脸模型...";
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
// 在初始化模型前再次检查配置文件,确保配置已正确加载
initAndCheckFaceConfig(this);
faceSDKManager.initModel(this, new com.baidu.idl.face.main.finance.listener.SdkInitListener() {
@Override
public void initStart() {
String logMessage = "人脸模型初始化开始...";
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
}
@Override
public void initLicenseSuccess() {
// 授权已在initFaceSDK中处理
}
@Override
public void initLicenseFail(int errorCode, String msg) {
// 授权已在initFaceSDK中处理
}
@Override
public void initModelSuccess() {
String logMessage = "人脸SDK模型初始化成功";
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
synchronized (initLock) {
initCompleted[0] = true;
initSuccess[0] = true;
initLock.notifyAll();
}
// 模型初始化成功后,进入人脸识别界面
runOnUiThread(new Runnable() {
@Override
public void run() {
enterFaceRecognitionActivity(dialog);
}
});
}
@Override
public void initModelFail(int errorCode, String msg) {
String logMessage = "人脸SDK模型初始化失败 - 错误码: " + errorCode + ", 错误信息: " + msg;
android.util.Log.e("MainActivity", logMessage);
LogManager.logError("FaceSDK", logMessage);
synchronized (initLock) {
initCompleted[0] = true;
initSuccess[0] = false;
initLock.notifyAll();
}
// 即使模型初始化失败,也进入人脸识别界面
runOnUiThread(new Runnable() {
@Override
public void run() {
enterFaceRecognitionActivity(dialog);
}
});
}
});
} catch (Exception e) {
String logMessage = "初始化人脸模型时发生异常: " + e.getMessage();
android.util.Log.e("MainActivity", logMessage, e);
LogManager.logError("FaceSDK", logMessage, e);
synchronized (initLock) {
initCompleted[0] = true;
initSuccess[0] = false;
initLock.notifyAll();
}
// 发生异常时,仍然进入人脸识别界面
runOnUiThread(new Runnable() {
@Override
public void run() {
enterFaceRecognitionActivity(dialog);
}
});
}
}
/**
* 进入人脸识别界面
* @param dialog 弹框实例
*/
private void enterFaceRecognitionActivity(Dialog dialog) {
try {
String logMessage = "准备进入人脸识别界面";
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
// 检查人脸SDK状态
com.baidu.idl.face.main.finance.manager.FaceSDKManager faceSDKManager =
com.baidu.idl.face.main.finance.manager.FaceSDKManager.getInstance();
String sdkStatus = "SDK状态 - 授权: " + faceSDKManager.initStatus + ", 模型: " + faceSDKManager.initModelSuccess;
android.util.Log.d("MainActivity", sdkStatus);
LogManager.logInfo("FaceSDK", sdkStatus);
// 关闭弹框
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
currentDialog = null; // 清除引用
// 跳转到人脸识别界面
Intent intent = new Intent(MainActivity.this, OXFaceOnlineActivity.class);
startActivity(intent);
logMessage = "已启动人脸识别界面";
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
} catch (Exception e) {
String logMessage = "进入人脸识别界面时发生异常: " + e.getMessage();
android.util.Log.e("MainActivity", logMessage, e);
LogManager.logError("FaceSDK", logMessage, e);
// 即使发生异常,也要确保弹框被关闭
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
currentDialog = null; // 清除引用
}
}
/**
* 根据设备类型切换摄像头配置
* @param deviceType 设备类型,5表示第6批设备,其他值表示非第6批设备
*/
private void switchCameraByDeviceType(int deviceType) {
try {
// 获取FaceSDKManager实例
com.baidu.idl.face.main.finance.manager.FaceSDKManager faceSDKManager =
com.baidu.idl.face.main.finance.manager.FaceSDKManager.getInstance();
// 调用FaceSDKManager中的方法
faceSDKManager.switchCameraByDeviceType(deviceType);
String logMessage = "已根据设备类型(" + deviceType + ")切换摄像头配置";
android.util.Log.d("MainActivity", logMessage);
LogManager.logInfo("FaceSDK", logMessage);
// 显示切换成功提示
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this,
"摄像头配置已切换为" + (deviceType == 5 ? "第6批" : "非第6批") + "设备",
Toast.LENGTH_SHORT).show();
}
});
} catch (Exception e) {
String errorMessage = "切换摄像头配置失败: " + e.getMessage();
android.util.Log.e("MainActivity", errorMessage, e);
LogManager.logError("FaceSDK", errorMessage, e);
}
}
@Override
protected void onResume() {
super.onResume();
// 确保保持活跃功能正常运行
if (keepAliveManager != null && !keepAliveManager.isKeepingAlive()) {
keepAliveManager.startKeepAlive(this);
LogManager.logOperation("MainActivity", "恢复保持活跃状态");
}
}
@Override
protected void onPause() {
super.onPause();
// 24小时无人值守模式下,不停止保持活跃功能
LogManager.logDebug("MainActivity", "应用进入后台,但保持活跃状态继续运行");
}
@Override
protected void onDestroy() {
super.onDestroy();
// 关闭任何正在显示的Dialog以防止WindowLeaked错误
if (currentDialog != null && currentDialog.isShowing()) {
currentDialog.dismiss();
currentDialog = null;
}
LogManager.logOperation("MainActivity", "主界面正在销毁");
// 只在应用真正退出时才停止保持活跃
if (isFinishing() && keepAliveManager != null) {
keepAliveManager.stopKeepAlive(this);
LogManager.logOperation("MainActivity", "应用退出,停止保持活跃功能");
}
}
/**
* 获取并保存小程序码
* @param token 访问令牌
* @param hardwareId 硬件ID
* @param dialog 弹框实例
* @param buttonEnter 进入按钮
* @param buttonText 按钮文字视图
* @param originalText 原始按钮文字
* @param onComplete 请求完成回调
*/
private void fetchAndSaveMiniQrcode(String token, int hardwareId, Dialog dialog, View buttonEnter, TextView buttonText, String originalText, Runnable onComplete) {
// 调用获取小程序码接口
NetworkUtils.miniQrcode(token, hardwareId, new NetworkCallback<PadApiService.MiniQrcodeResponse>() {
@Override
public void onStart() {
// 开始请求
android.util.Log.d("MainActivity", "开始请求小程序码");
}
@Override
public void onSuccess(PadApiService.MiniQrcodeResponse data) {
// 获取小程序码成功
if (data != null && data.getQrcodeUrl() != null && !data.getQrcodeUrl().isEmpty()) {
// 保存小程序码链接到本地
deviceSelectDataManager.saveMiniQrcodeUrl(data.getQrcodeUrl());
android.util.Log.d("MainActivity", "小程序码获取并保存成功: " + data.getQrcodeUrl());
LogManager.logOperation("MainActivity", "小程序码获取并保存成功");
// 添加调试日志,验证保存是否成功
String savedUrl = deviceSelectDataManager.getMiniQrcodeUrl();
boolean hasUrl = deviceSelectDataManager.hasMiniQrcodeUrl();
android.util.Log.d("MainActivity", "验证保存结果 - 是否存在: " + hasUrl + ", 保存的URL: " + savedUrl);
} else {
android.util.Log.w("MainActivity", "获取到的小程序码数据为空或URL为空");
LogManager.logWarning("MainActivity", "获取到的小程序码数据为空或URL为空");
}
// 执行完成回调
if (onComplete != null) {
onComplete.run();
}
}
@Override
public void onError(int errorCode, String errorMessage) {
// 获取小程序码失败
android.util.Log.e("MainActivity", "获取小程序码失败 - 错误码: " + errorCode + ", 错误信息: " + errorMessage);
LogManager.logError("MainActivity", "获取小程序码失败 - 错误码: " + errorCode + ", 错误信息: " + errorMessage);
// 即使获取小程序码失败,也执行完成回调
if (onComplete != null) {
onComplete.run();
}
}
@Override
public void onComplete() {
// 请求完成
}
});
}
/**
* 获取并保存上传人脸小程序码
* @param token 访问令牌
* @param hardwareId 硬件ID
* @param dialog 弹框实例
* @param buttonEnter 进入按钮
* @param buttonText 按钮文字视图
* @param originalText 原始按钮文字
* @param onComplete 请求完成回调
*/
private void fetchAndSaveUploadFaceMiniQrcode(String token, int hardwareId, Dialog dialog, View buttonEnter, TextView buttonText, String originalText, Runnable onComplete) {
// 获取品牌ID
int brandId = loginDataManager.getBrandId();
// 检查brandId是否有效
if (brandId <= 0) {
android.util.Log.e("MainActivity", "无效的品牌ID: " + brandId);
LogManager.logError("MainActivity", "获取上传人脸小程序码失败 - 无效的品牌ID: " + brandId);
// 即使获取上传人脸小程序码失败,也执行完成回调
if (onComplete != null) {
onComplete.run();
}
return;
}
// 调用获取上传人脸小程序码接口
NetworkUtils.getWXACodeUnlimit(token, hardwareId, brandId, new NetworkCallback<PadApiService.GetWXACodeResponse>() {
@Override
public void onStart() {
// 开始请求
android.util.Log.d("MainActivity", "开始请求上传人脸小程序码");
}
@Override
public void onSuccess(PadApiService.GetWXACodeResponse data) {
// 获取上传人脸小程序码成功
if (data != null && data.getUrl() != null && !data.getUrl().isEmpty()) {
// 保存上传人脸小程序码链接到本地
deviceSelectDataManager.saveUploadFaceMiniQrcodeUrl(data.getUrl());
android.util.Log.d("MainActivity", "上传人脸小程序码获取并保存成功: " + data.getUrl());
LogManager.logOperation("MainActivity", "上传人脸小程序码获取并保存成功");
// 添加调试日志,验证保存是否成功
String savedUrl = deviceSelectDataManager.getUploadFaceMiniQrcodeUrl();
boolean hasUrl = deviceSelectDataManager.hasUploadFaceMiniQrcodeUrl();
android.util.Log.d("MainActivity", "验证保存结果 - 是否存在: " + hasUrl + ", 保存的URL: " + savedUrl);
} else {
android.util.Log.w("MainActivity", "获取到的上传人脸小程序码数据为空或URL为空");
LogManager.logWarning("MainActivity", "获取到的上传人脸小程序码数据为空或URL为空");
}
// 执行完成回调
if (onComplete != null) {
onComplete.run();
}
}
@Override
public void onError(int errorCode, String errorMessage) {
// 获取上传人脸小程序码失败
android.util.Log.e("MainActivity", "获取上传人脸小程序码失败 - 错误码: " + errorCode + ", 错误信息: " + errorMessage);
LogManager.logError("MainActivity", "获取上传人脸小程序码失败 - 错误码: " + errorCode + ", 错误信息: " + errorMessage);
// 即使获取上传人脸小程序码失败,也执行完成回调
if (onComplete != null) {
onComplete.run();
}
}
@Override
public void onComplete() {
// 请求完成
}
});
}
/**
* 设置日志路径调试功能(长按登录按钮)
*/
private void setupLogPathDebug() {
buttonLogin.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// 显示自启动状态信息(调试功能)
showAutoStartStatusInfo();
return true;
}
});
// 添加长按版本号打开调试界面的功能
setupVersionLongClick();
// 添加双击测试功能
setupDoubleTapTest();
}
/**
* 设置长按版本号打开调试界面的功能
*/
private void setupVersionLongClick() {
// 查找版本号TextView(在布局文件中没有明确的ID,我们需要通过遍历查找)
View bottomInfoLayout = findViewById(R.id.bottomInfoLayout);
if (bottomInfoLayout instanceof LinearLayout) {
LinearLayout layout = (LinearLayout) bottomInfoLayout;
// 遍历子视图找到包含版本号的LinearLayout
for (int i = 0; i < layout.getChildCount(); i++) {
View child = layout.getChildAt(i);
if (child instanceof LinearLayout) {
LinearLayout versionLayout = (LinearLayout) child;
// 查找版本号TextView
for (int j = 0; j < versionLayout.getChildCount(); j++) {
View versionChild = versionLayout.getChildAt(j);
if (versionChild instanceof TextView) {
TextView versionTextView = (TextView) versionChild;
// 检查是否包含版本号文本
if (versionTextView.getText().toString().contains("Version")) {
// 设置长按监听器
versionTextView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// 打开调试界面
openDebugActivity();
return true;
}
});
break;
}
}
}
}
}
}
}
/**
* 打开调试界面
*/
private void openDebugActivity() {
Intent intent = new Intent(this, DebugActivity.class);
startActivity(intent);
}
/**
* 设置双击测试功能
*/
private void setupDoubleTapTest() {
final long[] taps = new long[3]; // 增加到3个点击点
final int[] tapCount = {0};
buttonLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
long currentTime = System.currentTimeMillis();
taps[tapCount[0] % 3] = currentTime;
tapCount[0]++;
// 检查是否在300ms内三击
if (tapCount[0] >= 3 && (currentTime - taps[(tapCount[0] - 3) % 3]) < 300) {
// 三击触发直接启动测试
triggerDirectStartTest();
tapCount[0] = 0; // 重置计数
}
// 检查是否在300ms内双击
else if (tapCount[0] >= 2 && (currentTime - taps[(tapCount[0] - 2) % 3]) < 300) {
// 双击触发自启动测试
triggerAutoStartTest();
tapCount[0] = 0; // 重置计数
} else {
// 正常的登录按钮点击事件
handleLoginButtonClick();
}
}
});
}
/**
* 处理登录按钮点击事件
*/
private void handleLoginButtonClick() {
String username = editTextUsername.getText().toString().trim();
String password = editTextPassword.getText().toString().trim();
// 在测试环境下,如果用户名和密码都为空,自动填充默认账号
if (isTestEnvironment() && username.isEmpty() && password.isEmpty()) {
username = "00167";
password = "123456";
// 更新输入框显示
editTextUsername.setText(username);
editTextPassword.setText(password);
// 显示提示信息
showToast("测试环境:已自动填充默认账号");
android.util.Log.d("MainActivity", "Test environment: Auto-filled default credentials");
}
if (validateInput(username, password)) {
performLogin(username, password);
}
}
/**
* 触发自启动测试
*/
private void triggerAutoStartTest() {
try {
// 使用反射调用测试辅助类
Class<?> testHelperClass = Class.forName("com.ouxuan.oxface.utils.BootSimulationHelper");
java.lang.reflect.Method testMethod = testHelperClass.getMethod("simulateBootCompleted", android.content.Context.class);
testMethod.invoke(null, this);
showToast("自启动测试已触发");
} catch (Exception e) {
android.util.Log.e(TAG, "触发自启动测试失败", e);
showToast("触发自启动测试失败");
}
}
/**
* 直接启动应用测试
*/
private void triggerDirectStartTest() {
try {
// 使用反射调用测试辅助类
Class<?> testHelperClass = Class.forName("com.ouxuan.oxface.utils.BootSimulationHelper");
java.lang.reflect.Method testMethod = testHelperClass.getMethod("directStartApp", android.content.Context.class);
testMethod.invoke(null, this);
showToast("直接启动测试已触发");
} catch (Exception e) {
android.util.Log.e(TAG, "触发直接启动测试失败", e);
showToast("触发直接启动测试失败");
}
}
/**
* 显示日志路径信息
*/
private void showLogPathInfo() {
String pathInfo = LogManager.getLogPathInfo(this);
// 在日志中记录
android.util.Log.i("MainActivity", "日志路径信息:\n" + pathInfo);
// 写入一条测试日志
LogManager.logOperation("调试", "用户查看日志路径信息");
// 创建对话框显示路径信息
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);
builder.setTitle("日志路径信息(调试)");
builder.setMessage(pathInfo);
builder.setPositiveButton("复制路径", new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(android.content.DialogInterface dialog, int which) {
// 复制日志目录路径到剪贴板
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) getSystemService(android.content.Context.CLIPBOARD_SERVICE);
if (clipboard != null) {
LogManager logManager = LogManager.getInstance(MainActivity.this);
String logDirPath = logManager.getLogDirectory().getAbsolutePath();
android.content.ClipData clip = android.content.ClipData.newPlainText("日志目录路径", logDirPath);
clipboard.setPrimaryClip(clip);
showToast("日志目录路径已复制: " + logDirPath);
}
}
});
builder.setNegativeButton("关闭", null);
builder.setNeutralButton("写入测试日志", new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(android.content.DialogInterface dialog, int which) {
// 写入一些测试日志
LogManager.logInfo("DEBUG", "这是一条测试信息日志 - " + new java.util.Date());
LogManager.logWarning("DEBUG", "这是一条测试警告日志 - " + new java.util.Date());
LogManager.logError("DEBUG", "这是一条测试错误日志 - " + new java.util.Date());
LogManager.logOperation("测试操作", "用户触发测试日志写入");
LogManager.logPerformance("测试性能", 88);
showToast("测试日志已写入,请稍后再查看路径信息");
}
});
builder.show();
}
/**
* 显示api_response_data_json
*/
private void showToastU_api_response_data()
{
UtilCodeHelper.Toast.cancel();
// 将 device_select_prefs.xml 中的<string name="select_response"> 使用gson转为json,并用toast显示其中的hardware_name
DeviceSelectDataManager deviceSelectDataManager = DeviceSelectDataManager.getInstance(this);
String json = deviceSelectDataManager.getApiResponseDataJson();
try {
JSONObject jsonObject = new JSONObject(json);
String hardware_name = jsonObject.getString("hardware_name");
// Toast.showShort(hardware_name);
UtilCodeHelper.Toast.showLong(hardware_name);
} catch (JSONException e) {
e.printStackTrace();
}
// Gson gson = new Gson();
// String apiResponseDataJson = deviceSelectDataManager.getApiResponseDataJson();
// PadApiService.PadSelectResponse apiResponse = gson.fromJson(apiResponseDataJson, PadApiService.PadSelectResponse.class);
// LogManager.logDebug("api_response_data_json", apiResponseDataJson);
// UtilCodeHelper.Toast.showShort(apiResponseDataJson);
}
/**
* 显示自启动状态信息(调试功能)
*/
private void showAutoStartStatusInfo() {
if (autoStartManager != null) {
String statusInfo = autoStartManager.getAutoStartStatusInfo();
LogManager.logDebug(TAG, "自启动状态信息:\n" + statusInfo);
// 创建弹框显示详细状态
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);
builder.setTitle("自启动功能状态(调试)");
builder.setMessage(statusInfo);
builder.setPositiveButton("测试自启动", new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(android.content.DialogInterface dialog, int which) {
// 执行自启动功能测试
autoStartManager.testAutoStartFunction();
showToast("自启动测试已执行,请查看日志");
}
});
builder.setNegativeButton("关闭", null);
builder.setNeutralButton("重置统计", new android.content.DialogInterface.OnClickListener() {
@Override
public void onClick(android.content.DialogInterface dialog, int which) {
autoStartManager.resetAutoStartStats();
showToast("自启动统计信息已重置");
}
});
builder.show();
} else {
showToast("自启动管理器未初始化");
}
}
/**
* 初始化并检查人脸识别配置文件
* @param context 上下文
* @return 配置文件是否已成功初始化
*/
private boolean initAndCheckFaceConfig(Context context) {
boolean isFinanceConfigExit = com.baidu.idl.face.main.finance.utils.FinanceConfigUtils.isConfigExit(context);
boolean isFinanceInitConfig = com.baidu.idl.face.main.finance.utils.FinanceConfigUtils.initConfig();
String logMessage = "配置文件状态: 存在=" + isFinanceConfigExit + ", 初始化=" + isFinanceInitConfig;
android.util.Log.d("MainActivity", logMessage);
if (isFinanceInitConfig && isFinanceConfigExit) {
LogManager.logInfo("FaceSDK", "配置文件加载成功");
return true;
} else {
LogManager.logWarning("FaceSDK", "初始配置失败,将重置文件内容为默认配置");
// 修改为默认配置
com.baidu.idl.face.main.finance.utils.FinanceConfigUtils.modityJson();
return false;
}
}
}