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"/>
+
+