diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c9d3f36..32446a6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -97,6 +97,12 @@ android:name=".debug.DirectBootTestActivity" android:exported="true" android:theme="@style/Theme.OxFaceLogin" /> + + + \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/DebugActivity.java b/app/src/main/java/com/ouxuan/oxface/DebugActivity.java new file mode 100644 index 0000000..efa8945 --- /dev/null +++ b/app/src/main/java/com/ouxuan/oxface/DebugActivity.java @@ -0,0 +1,373 @@ +package com.ouxuan.oxface; + +import android.app.Activity; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.ScrollView; +import android.widget.TextView; +import android.widget.Toast; + +import com.ouxuan.oxface.device.DeviceUtils; +import com.ouxuan.oxface.network.utils.NetworkUtils; +import com.ouxuan.oxface.utils.AutoStartManager; +import com.ouxuan.oxface.utils.BootSimulationHelper; +import com.ouxuan.oxface.utils.LogManager; +import com.ouxuan.oxface.utils.UtilCodeHelper; + +import java.io.File; +import java.util.Date; + +public class DebugActivity extends Activity { + private static final String TAG = "DebugActivity"; + + private TextView tvLogOutput; + private ScrollView logScrollView; + private AutoStartManager autoStartManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_debug); + + initViews(); + initManagers(); + setupClickListeners(); + } + + private void initViews() { + tvLogOutput = findViewById(R.id.tvLogOutput); + logScrollView = findViewById(R.id.logScrollView); + + // 初始化日志显示 + tvLogOutput.setText("调试界面已启动 - " + new Date().toString() + "\n"); + } + + private void initManagers() { + autoStartManager = AutoStartManager.getInstance(this); + } + + private void setupClickListeners() { + // 测试自启动按钮 + Button btnTestAutoStart = findViewById(R.id.btnTestAutoStart); + btnTestAutoStart.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + logMessage("触发自启动测试..."); + triggerAutoStartTest(); + } + }); + + // 测试直接启动按钮 + Button btnTestDirectStart = findViewById(R.id.btnTestDirectStart); + btnTestDirectStart.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + logMessage("触发直接启动测试..."); + triggerDirectStartTest(); + } + }); + + // 显示日志路径按钮 + Button btnShowLogPath = findViewById(R.id.btnShowLogPath); + btnShowLogPath.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showLogPathInfo(); + } + }); + + // 写入测试日志按钮 + Button btnWriteTestLog = findViewById(R.id.btnWriteTestLog); + btnWriteTestLog.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + writeTestLogs(); + } + }); + + // 显示自启动状态按钮 + Button btnShowAutoStartStatus = findViewById(R.id.btnShowAutoStartStatus); + btnShowAutoStartStatus.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showAutoStartStatus(); + } + }); + + // 重置统计信息按钮 + Button btnResetAutoStartStats = findViewById(R.id.btnResetAutoStartStats); + btnResetAutoStartStats.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + resetAutoStartStats(); + } + }); + + // 显示设备信息按钮 + Button btnShowDeviceInfo = findViewById(R.id.btnShowDeviceInfo); + btnShowDeviceInfo.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + showDeviceInfo(); + } + }); + + // 测试网络连接按钮 + Button btnTestNetwork = findViewById(R.id.btnTestNetwork); + btnTestNetwork.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + testNetworkConnection(); + } + }); + + // 清空日志按钮 + Button btnClearLogs = findViewById(R.id.btnClearLogs); + btnClearLogs.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + clearLogs(); + } + }); + + // 测试Shell命令按钮 + Button btnTestShellCommand = findViewById(R.id.btnTestShellCommand); + btnTestShellCommand.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + testShellCommand(); + } + }); + + // 测试闹钟按钮 + Button btnTestAlarm = findViewById(R.id.btnTestAlarm); + btnTestAlarm.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + testAlarm(); + } + }); + + // 关闭按钮 + Button btnClose = findViewById(R.id.btnClose); + btnClose.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + } + }); + } + + /** + * 触发自启动测试 + */ + private void triggerAutoStartTest() { + try { + BootSimulationHelper.simulateBootCompleted(this); + logMessage("自启动测试已触发"); + showToast("自启动测试已触发"); + } catch (Exception e) { + Log.e(TAG, "触发自启动测试失败", e); + logMessage("触发自启动测试失败: " + e.getMessage()); + showToast("触发自启动测试失败"); + } + } + + /** + * 直接启动应用测试 + */ + private void triggerDirectStartTest() { + try { + BootSimulationHelper.directStartApp(this); + logMessage("直接启动测试已触发"); + showToast("直接启动测试已触发"); + } catch (Exception e) { + Log.e(TAG, "触发直接启动测试失败", e); + logMessage("触发直接启动测试失败: " + e.getMessage()); + showToast("触发直接启动测试失败"); + } + } + + /** + * 显示日志路径信息 + */ + private void showLogPathInfo() { + String pathInfo = LogManager.getLogPathInfo(this); + logMessage("日志路径信息:\n" + pathInfo); + + // 写入一条测试日志 + LogManager.logOperation("调试", "用户查看日志路径信息"); + + // 复制日志目录路径到剪贴板 + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + if (clipboard != null) { + LogManager logManager = LogManager.getInstance(this); + String logDirPath = logManager.getLogDirectory().getAbsolutePath(); + ClipData clip = ClipData.newPlainText("日志目录路径", logDirPath); + clipboard.setPrimaryClip(clip); + showToast("日志目录路径已复制: " + logDirPath); + } + } + + /** + * 写入测试日志 + */ + private void writeTestLogs() { + // 写入一些测试日志 + LogManager.logInfo("DEBUG", "这是一条测试信息日志 - " + new Date()); + LogManager.logWarning("DEBUG", "这是一条测试警告日志 - " + new Date()); + LogManager.logError("DEBUG", "这是一条测试错误日志 - " + new Date()); + LogManager.logOperation("测试操作", "用户触发测试日志写入"); + LogManager.logPerformance("测试性能", 88); + logMessage("测试日志已写入,请稍后再查看路径信息"); + showToast("测试日志已写入"); + } + + /** + * 显示自启动状态 + */ + private void showAutoStartStatus() { + if (autoStartManager != null) { + String statusInfo = autoStartManager.getAutoStartStatusInfo(); + logMessage("自启动状态信息:\n" + statusInfo); + showToast("自启动状态信息已显示"); + } else { + logMessage("自启动管理器未初始化"); + showToast("自启动管理器未初始化"); + } + } + + /** + * 重置统计信息 + */ + private void resetAutoStartStats() { + if (autoStartManager != null) { + autoStartManager.resetAutoStartStats(); + logMessage("自启动统计信息已重置"); + showToast("自启动统计信息已重置"); + } else { + logMessage("自启动管理器未初始化"); + showToast("自启动管理器未初始化"); + } + } + + /** + * 显示设备信息 + */ + private void showDeviceInfo() { + String deviceInfo = DeviceUtils.getDeviceInfo(this); + logMessage("设备信息:\n" + deviceInfo); + showToast("设备信息已显示"); + } + + /** + * 测试网络连接 + */ + private void testNetworkConnection() { + logMessage("正在测试网络连接..."); + boolean isConnected = UtilCodeHelper.Network.isConnected(); + logMessage("网络连接状态: " + (isConnected ? "已连接" : "未连接")); + showToast("网络连接测试完成"); + } + + /** + * 清空日志 + */ + private void clearLogs() { + // 删除日志目录中的所有文件 + LogManager logManager = LogManager.getInstance(this); + File logDir = logManager.getLogDirectory(); + if (logDir.exists() && logDir.isDirectory()) { + File[] logFiles = logDir.listFiles(); + if (logFiles != null) { + for (File file : logFiles) { + if (file.isFile()) { + file.delete(); + } + } + } + } + logMessage("日志已清空"); + showToast("日志已清空"); + } + + /** + * 测试Shell命令 + */ + private void testShellCommand() { + logMessage("测试Shell命令执行..."); + try { + // 执行简单的Shell命令 + String result = UtilCodeHelper.Device.getModel(); + logMessage("设备型号: " + result); + showToast("设备信息获取完成"); + } catch (Exception e) { + Log.e(TAG, "设备信息获取失败", e); + logMessage("设备信息获取失败: " + e.getMessage()); + showToast("设备信息获取失败"); + } + } + + /** + * 测试闹钟 + */ + private void testAlarm() { + logMessage("测试闹钟功能..."); + try { + // 设置一个5秒后的闹钟测试 + Intent intent = new Intent(this, MainActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra("auto_start", true); + intent.putExtra("boot_reason", "alarm_test"); + intent.putExtra("start_source", "debug_test"); + + // 使用BootSimulationHelper来设置测试闹钟 + BootSimulationHelper.simulateBootCompleted(this); + logMessage("闹钟测试已触发,将在系统启动模拟后执行"); + showToast("闹钟测试已触发"); + } catch (Exception e) { + Log.e(TAG, "闹钟测试失败", e); + logMessage("闹钟测试失败: " + e.getMessage()); + showToast("闹钟测试失败"); + } + } + + /** + * 在日志输出区域添加消息 + * @param message 要添加的消息 + */ + private void logMessage(String message) { + runOnUiThread(new Runnable() { + @Override + public void run() { + String currentTime = android.text.format.DateFormat.format("HH:mm:ss", new Date()).toString(); + String logEntry = "[" + currentTime + "] " + message + "\n"; + tvLogOutput.append(logEntry); + + // 滚动到底部 + logScrollView.post(new Runnable() { + @Override + public void run() { + logScrollView.fullScroll(View.FOCUS_DOWN); + } + }); + } + }); + } + + /** + * 显示Toast消息 + * @param message 要显示的消息 + */ + private void showToast(String message) { + Toast.makeText(this, message, Toast.LENGTH_SHORT).show(); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/ouxuan/oxface/MainActivity.java b/app/src/main/java/com/ouxuan/oxface/MainActivity.java index 9fa8df1..47d9ed6 100644 --- a/app/src/main/java/com/ouxuan/oxface/MainActivity.java +++ b/app/src/main/java/com/ouxuan/oxface/MainActivity.java @@ -18,6 +18,7 @@ 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; @@ -768,11 +769,60 @@ public class MainActivity extends AppCompatActivity { } }); + // 添加长按版本号打开调试界面的功能 + 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() { diff --git a/app/src/main/res/drawable/log_background.xml b/app/src/main/res/drawable/log_background.xml new file mode 100644 index 0000000..fdfb5c2 --- /dev/null +++ b/app/src/main/res/drawable/log_background.xml @@ -0,0 +1,8 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_debug.xml b/app/src/main/res/layout/activity_debug.xml new file mode 100644 index 0000000..a2184f7 --- /dev/null +++ b/app/src/main/res/layout/activity_debug.xml @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + +