diff --git a/winboll/build.properties b/winboll/build.properties index b66727c..b8c14ac 100644 --- a/winboll/build.properties +++ b/winboll/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Sun Mar 15 11:38:00 GMT 2026 +#Sun Mar 15 12:22:44 GMT 2026 stageCount=26 libraryProject= baseVersion=15.11 publishVersion=15.11.25 -buildCount=10 +buildCount=21 baseBetaVersion=15.11.26 diff --git a/winboll/src/main/AndroidManifest.xml b/winboll/src/main/AndroidManifest.xml index 5344b59..85c8ebd 100644 --- a/winboll/src/main/AndroidManifest.xml +++ b/winboll/src/main/AndroidManifest.xml @@ -293,7 +293,8 @@ + android:exported="true" + android:launchMode="singleTop"> diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/termux/NfcTermuxBridgeActivity.java b/winboll/src/main/java/cc/winboll/studio/winboll/termux/NfcTermuxBridgeActivity.java index 5a5be24..7020525 100644 --- a/winboll/src/main/java/cc/winboll/studio/winboll/termux/NfcTermuxBridgeActivity.java +++ b/winboll/src/main/java/cc/winboll/studio/winboll/termux/NfcTermuxBridgeActivity.java @@ -1,222 +1,202 @@ +/* + * 源码说明与描述: + * NFC 与 Termux 桥接活动,用于接收 NFC 传递的 JSON 指令并执行 Termux 脚本命令, + * 支持后台执行与终端窗口唤起两种模式,提供测试注入接口。 + * + * 作者:豆包&ZhanGSKen + * 创建时间:2025-03-15 14:00:00 + * 最后编辑时间:2026-03-15 15:22:00 + */ package cc.winboll.studio.winboll.termux; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.os.Bundle; -import android.view.View; import android.widget.Toast; import cc.winboll.studio.libappbase.LogUtils; +import cc.winboll.studio.libappbase.ToastUtils; import cc.winboll.studio.winboll.models.NfcTermuxCmd; import com.google.gson.Gson; public class NfcTermuxBridgeActivity extends Activity { - private static final String TAG = "NfcTermuxBridge"; - private static final String ACTION_BUILD_VIEW = NfcTermuxBridgeActivity.class.getName() + ".ACTION_BUILD_VIEW"; + // ========================= 常量与静态属性 ========================= + public static final String TAG = "NfcTermuxBridgeActivity"; + public static final String ACTION_BUILD_VIEW = NfcTermuxBridgeActivity.class.getName() + ".ACTION_BUILD_VIEW"; private static final Gson GSON = new Gson(); + // ========================= 生命周期方法 ========================= @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - handleNfcIntent(getIntent()); + LogUtils.d(TAG, "onCreate() 调用,savedInstanceState: " + (savedInstanceState != null ? "非空" : "空")); + dispatchIntent(getIntent()); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - if (intent.getAction().equals(ACTION_BUILD_VIEW)) { - onOpenTermuxProjectBuildView(intent); - } else { - handleNfcIntent(intent); - } + LogUtils.d(TAG, "onNewIntent() 调用,intent: " + (intent != null ? intent.toString() : "null")); + if (intent != null) { + LogUtils.d(TAG, "onNewIntent() action: " + intent.getAction()); + LogUtils.d(TAG, "onNewIntent() data: " + intent.getDataString()); + LogUtils.d(TAG, "onNewIntent() extras: " + intent.getExtras()); + LogUtils.d(TAG, "onNewIntent() flags: " + intent.getFlags()); + LogUtils.d(TAG, "onNewIntent() component: " + intent.getComponent()); + } else { + LogUtils.w(TAG, "onNewIntent() intent is null"); + } + dispatchIntent(intent); } + // ========================= 统一 Intent 分发(合并去重) ========================= + private void dispatchIntent(Intent intent) { + LogUtils.d(TAG, "dispatchIntent() 分发 intent"); + if (intent == null) { + LogUtils.w(TAG, "dispatchIntent() intent is null"); + return; + } + + if (ACTION_BUILD_VIEW.equals(intent.getAction())) { + ToastUtils.show("ACTION_BUILD_VIEW 命中"); + onOpenTermuxProjectBuildView(intent); + } else { + handleNfcIntent(intent); + } + } + + // ========================= 核心业务方法 ========================= /** * 处理 NFC 传递的 JSON 指令 */ private void handleNfcIntent(Intent intent) { - if (intent == null) return; + LogUtils.d(TAG, "handleNfcIntent() 调用"); + if (intent == null) { + LogUtils.w(TAG, "handleNfcIntent() intent 为空"); + return; + } try { String json = intent.getStringExtra(Intent.EXTRA_TEXT); + LogUtils.d(TAG, "handleNfcIntent() json: " + json); - // 1. 发布版逻辑:正常接收 NFC 传入的 JSON if (json == null || json.isEmpty()) { - LogUtils.e(TAG, "NFC 指令为空"); + LogUtils.e(TAG, "handleNfcIntent() 指令为空"); finish(); return; } - LogUtils.d(TAG, "接收 JSON:" + json); - - // 2. 解析指令 NfcTermuxCmd cmd = GSON.fromJson(json, NfcTermuxCmd.class); + LogUtils.d(TAG, "handleNfcIntent() cmd: " + cmd); + if (cmd.script == null || cmd.script.isEmpty()) { - LogUtils.e(TAG, "script 不能为空"); + LogUtils.e(TAG, "handleNfcIntent() script 为空"); finish(); return; } - // 3. 拼接脚本路径 String scriptPath = "/data/data/com.termux/files/home/TermuxWorkSpaces/BashShells/AutoNFC/" + cmd.script; + LogUtils.d(TAG, "handleNfcIntent() 脚本路径: " + scriptPath); - // 4. 执行 Termux 命令 boolean success = TermuxCommandExecutor.executeCommand( - this, - scriptPath, - cmd.args, - cmd.workDir, - cmd.background, - cmd.resultDir + this, scriptPath, cmd.args, cmd.workDir, cmd.background, cmd.resultDir ); + LogUtils.d(TAG, "handleNfcIntent() 执行结果: " + success); - // 5. 结果反馈 if (success) { - Toast.makeText(this, "指令已发送:" + cmd.script, Toast.LENGTH_SHORT).show(); - LogUtils.i(TAG, "执行成功:" + scriptPath); + Toast.makeText(this, "指令已发送: " + cmd.script, Toast.LENGTH_SHORT).show(); + LogUtils.i(TAG, "执行成功: " + scriptPath); } else { Toast.makeText(this, "指令发送失败", Toast.LENGTH_SHORT).show(); LogUtils.e(TAG, "执行失败"); } } catch (Exception e) { - LogUtils.e(TAG, "处理异常:" + e.getMessage(), e); + LogUtils.e(TAG, "handleNfcIntent() 异常: " + e.getMessage(), e); Toast.makeText(this, "解析失败", Toast.LENGTH_SHORT).show(); } finally { finish(); } } - /** - * 测试执行Gradle命令(实时输出版,唤起Termux窗口) + * 唤起 Termux 窗口执行命令(实时输出版) */ public void onOpenTermuxProjectBuildView(Intent intent) { - try { + LogUtils.d(TAG, "onOpenTermuxProjectBuildView() 调用"); + try { String json = intent.getStringExtra(Intent.EXTRA_TEXT); + LogUtils.d(TAG, "onOpenTermuxProjectBuildView() json: " + json); - // 1. 发布版逻辑:正常接收 NFC 传入的 JSON if (json == null || json.isEmpty()) { - LogUtils.e(TAG, "NFC 指令为空"); + LogUtils.e(TAG, "onOpenTermuxProjectBuildView() 指令为空"); finish(); return; } - LogUtils.d(TAG, "接收 JSON:" + json); - - // 2. 解析指令 NfcTermuxCmd cmd = GSON.fromJson(json, NfcTermuxCmd.class); + LogUtils.d(TAG, "onOpenTermuxProjectBuildView() cmd: " + cmd); + if (cmd.script == null || cmd.script.isEmpty()) { - LogUtils.e(TAG, "script 不能为空"); + LogUtils.e(TAG, "onOpenTermuxProjectBuildView() script 为空"); finish(); return; } - // 3. 拼接脚本路径 -// String scriptPath = "/data/data/com.termux/files/home/TermuxWorkSpaces/BashShells/AutoNFC/" + cmd.script; -// -// // 4. 执行 Termux 命令 -// boolean success = TermuxCommandExecutor.executeCommand( -// this, -// scriptPath, -// cmd.args, -// cmd.workDir, -// cmd.background, -// cmd.resultDir -// ); + StringBuilder targetCmd = new StringBuilder(); + String nfcScriptFolder = "/data/data/com.termux/files/home/TermuxWorkSpaces/BashShells/AutoNFC/"; + targetCmd.append("cd " + nfcScriptFolder + " && "); + targetCmd.append("stdbuf -o0 -e0 -i0 bash ").append(cmd.script).append(" "); + if (cmd.args != null) { + for (String arg : cmd.args) { + targetCmd.append(arg).append(" "); + } + } + //targetCmd.append(" && echo '\n✅ 执行完成!' && echo '\n📌 项目: ").append(cmd.args != null && cmd.args.length > 0 ? cmd.args[0] : "").append("' && read -p '按回车关闭...'"); -// LogUtils.d(TAG, "onTestTermuxCMD() 按钮点击,执行Gradle命令(实时输出)"); -// //tvMessage.append("\n【测试:执行Gradle命令(实时输出)】\n"); -// -// // 1. 校验Termux是否安装 -// if (!TermuxCommandExecutor.isTermuxInstalled(this)) { -// LogUtils.e(TAG, "onTestTermuxCMD() 错误:未安装Termux应用"); -// //tvMessage.append("错误:未安装Termux应用(包名:com.termux)\n"); -// return; -// } + LogUtils.d(TAG, "onOpenTermuxProjectBuildView() 命令: " + targetCmd); + boolean cmdSuccess = TermuxCommandExecutor.executeTerminalCommand(this, targetCmd.toString()); + LogUtils.d(TAG, "onOpenTermuxProjectBuildView() 执行结果: " + cmdSuccess); - // 2. 定义核心路径(确保路径与Termux中一致) -// String gradleFullPath = "/data/data/com.termux/files/home/gradle/gradle-7.5.1/bin/gradle"; -// String projectPath = TERMUX_HOME_PATH + "/"; // 项目目录 -// - // 3. 构造命令(核心:用stdbuf禁用缓冲,实现实时输出) - String targetCmd = ""; - // 步骤1:进入项目目录(不存在则创建) - targetCmd += "cd " + cmd.workDir + " && "; - // 步骤2:加载环境变量 - targetCmd += "source ~/.bashrc && "; - // 步骤3:显式配置PATH - //targetCmd += "export PATH=/data/data/com.termux/files/usr/bin:/data/data/com.termux/files/home/gradle/gradle-7.5.1/bin:$PATH && "; - // 步骤4:用stdbuf禁用stdout/stderr缓冲(关键!),执行Gradle命令 - // -o0:stdout无缓冲;-e0:stderr无缓冲;-i0:stdin无缓冲 - //targetCmd += "stdbuf -o0 -e0 -i0 " + gradleFullPath + " task --all | grep assemble && "; - //targetCmd += "stdbuf -o0 -e0 -i0 " + gradleFullPath + " -Pandroid.aapt2FromMavenOverride=/data/data/com.termux/files/home/android-sdk/build-tools/34.0.4/aapt2 assembleBetaDebug && "; - targetCmd += "stdbuf -o0 -e0 -i0 bash && "; - // 步骤5:执行成功提示 - targetCmd += "echo '\n✅ 命令执行完成!' && echo '\n📌 项目名称:" + cmd.args + "' && read -p '按回车键关闭终端...'"; - - - // 4. 执行命令(终端会话模式,唤起Termux窗口) - boolean cmdSuccess = TermuxCommandExecutor.executeTerminalCommand(this, targetCmd); - - // 5. 结果反馈 if (cmdSuccess) { - Toast.makeText(this, "指令已发送:" + cmd.script + " " + cmd.args, Toast.LENGTH_SHORT).show(); - LogUtils.i(TAG, "执行成功:" + cmd.script + " " + cmd.args); + Toast.makeText(this, "指令已发送: " + cmd.script + " " + (cmd.args != null && cmd.args.length > 0 ? cmd.args[0] : ""), Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "指令发送失败", Toast.LENGTH_SHORT).show(); - LogUtils.e(TAG, "执行失败"); } } catch (Exception e) { - LogUtils.e(TAG, "处理异常:" + e.getMessage(), e); + LogUtils.e(TAG, "onOpenTermuxProjectBuildView() 异常: " + e.getMessage(), e); Toast.makeText(this, "解析失败", Toast.LENGTH_SHORT).show(); } finally { finish(); } - } - // =========================================================== - // 公共静态测试函数:外部可直接调用注入测试 JSON - // =========================================================== + // ========================= 公共静态测试方法 ========================= public static void testCommand(Context context) { + LogUtils.d(TAG, "testCommand()"); try { - // 测试用指令 String testJson = "{\"script\":\"BuildWinBoLLProject.sh\",\"args\":[\"DebugTemp\"],\"workDir\":null,\"background\":true,\"resultDir\":null}"; - - Intent testIntent = new Intent(context, NfcTermuxBridgeActivity.class); - testIntent.putExtra(Intent.EXTRA_TEXT, testJson); - - // 模拟跳转至自身 Activity - context.startActivity(testIntent); - + Intent intent = new Intent(context, NfcTermuxBridgeActivity.class); + intent.putExtra(Intent.EXTRA_TEXT, testJson); + context.startActivity(intent); } catch (Exception e) { - LogUtils.e(TAG, "测试指令注入失败:" + e.getMessage()); + LogUtils.e(TAG, "testCommand() 失败: " + e.getMessage()); } } - - // =========================================================== - // 公共静态测试函数:外部可直接调用注入测试 JSON - // =========================================================== public static void testViewCommand(Context context) { + LogUtils.d(TAG, "testViewCommand()"); try { - // 测试用指令 String testJson = "{\"script\":\"BuildWinBoLLProjectView.sh\",\"args\":[\"DebugTemp\"],\"workDir\":null,\"background\":true,\"resultDir\":null}"; - - Intent testIntent = new Intent(context, NfcTermuxBridgeActivity.class); - testIntent.setAction(ACTION_BUILD_VIEW); - testIntent.putExtra(Intent.EXTRA_TEXT, testJson); - - // 模拟跳转至自身 Activity - context.startActivity(testIntent); - + Intent intent = new Intent(context, NfcTermuxBridgeActivity.class); + intent.setAction(ACTION_BUILD_VIEW); + intent.putExtra(Intent.EXTRA_TEXT, testJson); + context.startActivity(intent); } catch (Exception e) { - LogUtils.e(TAG, "测试指令注入失败:" + e.getMessage()); + LogUtils.e(TAG, "testViewCommand() 失败: " + e.getMessage()); } - } }