diff --git a/winboll/build.properties b/winboll/build.properties index dd56b55..ed66dae 100644 --- a/winboll/build.properties +++ b/winboll/build.properties @@ -1,8 +1,8 @@ #Created by .winboll/winboll_app_build.gradle -#Thu Jan 29 17:03:53 HKT 2026 +#Sun Mar 15 03:45:21 GMT 2026 stageCount=15 libraryProject= baseVersion=15.11 publishVersion=15.11.14 -buildCount=0 +buildCount=9 baseBetaVersion=15.11.15 diff --git a/winboll/src/main/AndroidManifest.xml b/winboll/src/main/AndroidManifest.xml index 74b3ee5..5344b59 100644 --- a/winboll/src/main/AndroidManifest.xml +++ b/winboll/src/main/AndroidManifest.xml @@ -18,7 +18,7 @@ tools:ignore="QueryAllPackagesPermission" /> - + + + + + + + + diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/models/NfcTermuxCmd.java b/winboll/src/main/java/cc/winboll/studio/winboll/models/NfcTermuxCmd.java new file mode 100644 index 0000000..c0ea16d --- /dev/null +++ b/winboll/src/main/java/cc/winboll/studio/winboll/models/NfcTermuxCmd.java @@ -0,0 +1,14 @@ +package cc.winboll.studio.winboll.models; + +/** + * @Author 豆包&ZhanGSKen + * @Date 2026/03/15 08:46 + */ +public class NfcTermuxCmd { + public String script; // 要执行的预制脚本名(如 auth.sh) + public String[] args; // 脚本参数 + public String workDir; // 工作目录 + public boolean background; // 是否后台执行 + public String resultDir; // 结果输出目录(可为 null) +} + 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 new file mode 100644 index 0000000..40eefa2 --- /dev/null +++ b/winboll/src/main/java/cc/winboll/studio/winboll/termux/NfcTermuxBridgeActivity.java @@ -0,0 +1,104 @@ +package cc.winboll.studio.winboll.termux; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.widget.Toast; +import cc.winboll.studio.libappbase.LogUtils; +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 Gson GSON = new Gson(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + handleNfcIntent(getIntent()); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + handleNfcIntent(intent); + } + + /** + * 处理 NFC 传递的 JSON 指令 + */ + private void handleNfcIntent(Intent intent) { + if (intent == null) return; + + try { + String json = intent.getStringExtra(Intent.EXTRA_TEXT); + + // 1. 发布版逻辑:正常接收 NFC 传入的 JSON + if (json == null || json.isEmpty()) { + LogUtils.e(TAG, "NFC 指令为空"); + finish(); + return; + } + + LogUtils.d(TAG, "接收 JSON:" + json); + + // 2. 解析指令 + NfcTermuxCmd cmd = GSON.fromJson(json, NfcTermuxCmd.class); + if (cmd.script == null || cmd.script.isEmpty()) { + LogUtils.e(TAG, "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 + ); + + // 5. 结果反馈 + if (success) { + 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); + Toast.makeText(this, "解析失败", Toast.LENGTH_SHORT).show(); + } finally { + finish(); + } + } + + // =========================================================== + // 公共静态测试函数:外部可直接调用注入测试 JSON + // =========================================================== + public static void testCommand(Context context) { + try { + // 测试用指令 + String testJson = "{\"script\":\"BuildWinBoLLProject.sh\",\"args\":[\"WinBoLL_Demo\"],\"workDir\":null,\"background\":true,\"resultDir\":null}"; + + Intent testIntent = new Intent(context, NfcTermuxBridgeActivity.class); + testIntent.putExtra(Intent.EXTRA_TEXT, testJson); + + // 模拟跳转至自身 Activity + context.startActivity(testIntent); + + } catch (Exception e) { + LogUtils.e(TAG, "测试指令注入失败:" + e.getMessage()); + } + } +} + diff --git a/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TermuxEnvTestActivity.java b/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TermuxEnvTestActivity.java index 16652ed..d24b40c 100644 --- a/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TermuxEnvTestActivity.java +++ b/winboll/src/main/java/cc/winboll/studio/winboll/unittest/TermuxEnvTestActivity.java @@ -1,5 +1,6 @@ package cc.winboll.studio.winboll.unittest; +import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -7,11 +8,11 @@ import android.view.View; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import cc.winboll.studio.libaes.utils.WinBoLLActivityManager; import cc.winboll.studio.libappbase.LogUtils; -import cc.winboll.studio.winboll.MainActivity; +import cc.winboll.studio.libappbase.ToastUtils; import cc.winboll.studio.winboll.R; import cc.winboll.studio.winboll.activities.BaseWinBoLLActivity; +import cc.winboll.studio.winboll.termux.NfcTermuxBridgeActivity; import cc.winboll.studio.winboll.termux.TermuxCommandExecutor; import java.io.BufferedReader; import java.io.File; @@ -19,7 +20,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -import android.app.Activity; /** * @Author 豆包&ZhanGSKen @@ -103,12 +103,12 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity { ((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true); mToolbar.setNavigationOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - LogUtils.d(TAG, "initToolbar() 导航栏返回按钮点击"); - getActivity().finish(); - } - }); + @Override + public void onClick(View v) { + LogUtils.d(TAG, "initToolbar() 导航栏返回按钮点击"); + getActivity().finish(); + } + }); LogUtils.d(TAG, "initToolbar() 初始化完成"); } @@ -216,7 +216,12 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity { tvMessage.append("💡 若未实时输出,请在Termux中执行:pkg install coreutils(安装stdbuf)\n"); tvMessage.append("-------------------------\n"); } - + + public void onTestWinBoLLProjectBuild(View view) { + ToastUtils.show("onOpenTermuxBash"); + NfcTermuxBridgeActivity.testCommand(this); + } + public void onOpenTermuxBash(View view) { LogUtils.d(TAG, "onTestTermuxCMD() 按钮点击,执行Gradle命令(实时输出)"); tvMessage.append("\n【测试:执行Gradle命令(实时输出)】\n"); @@ -275,7 +280,7 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity { tvMessage.append("💡 若未实时输出,请在Termux中执行:pkg install coreutils(安装stdbuf)\n"); tvMessage.append("-------------------------\n"); } - + /** * 跨包读取Termux命令结果文件(保留原功能,兼容其他场景) */ @@ -399,7 +404,7 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity { String filePath = file.getAbsolutePath(); String fileSize = file.isFile() ? " | 大小:" + formatFileSize(file.length()) : ""; String filePerm = " | 权限:r:" + file.canRead() + "/w:" + file.canWrite(); - + result.append(fileType); result.append(" "); result.append(fileName); diff --git a/winboll/src/main/res/layout/activity_termux_env_test.xml b/winboll/src/main/res/layout/activity_termux_env_test.xml index 918a360..a478c68 100644 --- a/winboll/src/main/res/layout/activity_termux_env_test.xml +++ b/winboll/src/main/res/layout/activity_termux_env_test.xml @@ -34,6 +34,12 @@ android:layout_height="wrap_content" android:text="TestTermuxEnv" android:onClick="onTestTermuxEnv"/> + +