diff --git a/README.md b/README.md index 4cb20e2..5a7755e 100644 --- a/README.md +++ b/README.md @@ -1,104 +1,103 @@ -WinBoLL 源生态计划项目说明书 +# WinBoLL 源生态计划项目说明书 + +## 一、项目概述 + +### 1. 核心定位 +WinBoLL 手机源码计划,旨在通过核心项目 WinBoLL 构建手机端与服务器端的 Android 项目的开发源码生态。实现手机与服务器的源码的联合开发。 + +### 2. 仓库架构 +#### **仓库类型:功能说明** +☆ 基础项目分支 WinBoLL:手机端安卓应用开发基础模板。 +☆ 应用项目分支 APPBase、AES、PowerBell、Positions**:安卓应用单一管理系列项目。 +☆ 源码汇总管理 OriginMaster**:各类分支源码合并存档,不适宜作为开发库使用。 + +### 3. 源码合并管理推送路线图 +⚠️ **注意**:仅仅展示不同应用模块源码的综合管理路线。分支合并操作时,必须具备 Git 管理经验。 + +★ WinBoLL → APPBase → OriginMaster +★ WinBoLL → AES → OriginMaster +★ WinBoLL → PowerBell → OriginMaster +★ WinBoLL → Positions → OriginMaster + +## 二、WinBoLL 项目核心信息 + +### 1. 项目简介 +☆ WinBoLL 项目是为手机端开发Android 项目的需求而设计的项目。 + +### 2. 官方资源 +#### ☆ 官方网站**:https://www.winboll.cc/ +#### ☆ 源码地址: +★ Gitea:https://gitea.winboll.cc/Studio/WinBoLL.git +★ GitHub:https://github.com/ZhanGSKen/WinBoLL.git +★ 码云:https://gitee.com/zhangsken/winboll.git + +## 三、应用编译环境检查问题 +### 核心判断条件: +☆ WinBoLL 项目以文件夹 `"/sdcard/WinBoLLStudio/APKs"` 是否存在为判断环境编译输出条件,因为编译输出的APK文件需要一个可供保存的环境。 + +☆ 文件夹"/sdcard/WinBoLLStudio/APKs" 目录条件设置方法: +***Linux 服务器端方面***:建立 `/sdcard/WinBoLLStudio/APKs` 目录即可。 +***手机开发端方面***:建立 `"/sdcard/WinBoLLStudio/APKs"` 目录(即 `"/storage/emulated/0/WinBoLLStudio/APKs"` 目录) 即可。 + +## 四、前置条件 + +### 1. WinBoLL APP 开发环境配置介绍 +#### WinBoLL APK 编译输出内容包括: +☆ "/sdcard/WinBoLLStudio/APKs"` 目录内的所有应用分支的 APK 文件。 +☆ "/sdcard/AppProjects/app.apk"文件。 +#### WinBoLL APK 源码命名空间规范 +☆ WinBoLL 项目使用 "cc.winboll.studio" 作为源码命名空间。在此命名空间下进行源码定义。 + +## 五、核心需求规划 + +### 1. WinBoLL 应用安全验证需求 +#### ☆ 支持访问 https://console.winboll.cc/ 服务器以校验应用包签名与版本。 + +### 2. 手机端源码开发管理需求 +#### ☆ 支持切换不同 WinBoLL 分支,以开发不同安卓应用。 + +## 六、编译与使用指南 + +### 1. 项目初始化(必须) +#### 1. 复制 `settings.gradle-demo` 为 `settings.gradle`。编辑 `settings.gradle` 文件内容,取消对应项目模块注释。 +#### 2. 复制 `gradle.properties-androidx-demo` (Android X 项目) 或 `gradle.properties-android-demo` (基本 Android 项目) 为 `gradle.properties`。 +#### 3. 复制(可选)`local.properties-demo` 为 `local.properties`,编辑 `local.properties` 文件内容,配置 Android SDK 目录。 +#### 4. **签名设置**: + ☆ **调试编译秘钥制作**:使用 Termux 应用终端,cd 进入 GenKeyStore 目录,运行 `bash gen_debug_keystore.sh` 脚本即可生成应用调试秘钥。 + ☆ **应用秘钥配置方法**:拷贝调试编译秘钥制作生成的 `appkey.jks` 与 `appkey.keystore` 文件到项目根目录即可。 + +## 七、应用编译命令介绍 + +### (1)类库型模块配置要点 +#### 1. **优先修改配置文件**:优先修改应用测试项目(目录为 `"/<类库测试应用>/"`)内 `build.properties` 文件,设置对应的类库项目名称:`libraryProject=<类库项目模块名>`。 +#### 2. **编译优先启动步骤**:使用 Termux 应用,进入 `""`,运行 `$ bash .winboll/bashPublishAPKAddTag.sh <类库测试项目模块名>` 命令。运行后可生成测试项目与类库项目的编译参数文件 `build.properties`。生成的 `build.properties` 文件有两份,一份在测试项目模块的文件夹内,一份在类库项目本身的模块文件夹内。 +#### 3. **最后类库编译发布步骤**:使用 Termux 应用,进入 `""`,运行 `$ bash .winboll/bashPublishLIBAddTag.sh <类库项目模块名>` 命令。运行后可发布至 WinBoLL Nexus Maven 库、本地 maven 目录或者是通用默认的 Gradle Maven 库。 + +### (2)单一应用型模块与类库测试型模块配置要点 +#### ☆ APK 编译方法: +使用 Termux 应用,进入 `""`,运行 `$ bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名>`。 +#### ☆ 运行后的 APK 输出路径: +★ 默认路径 (`$ bash gradlew assembleBetaDebug` 任务):APK 在 `/sdcard/WinBoLLStudio/APKs/<项目根目录名称>/debug/` 目录。 +★ 默认路径 (`$ bash assembleStageRelease` 任务):APK 在 `/sdcard/WinBoLLStudio/APKs/<项目根目录名称>/tag/` 目录。 +★ 额外输出路径:(假设 `winboll.properties` 文件已配置 `ExtraAPKOutputPath` 属性) 输出至 `ExtraAPKOutputPath` 属性配置的目录下。 + +### (3)手机端应用调试命令介绍 +#### ☆ Beta 渠道调试命令 +$bash gradlew assembleBetaDebug + +#### ☆ Stage 渠道调试命令 +$bash gradlew assembleStageDebug + +### (4)服务器端开发命令介绍 +##### ☆ Stage 渠道应用发布命令为: +("/settings.gradle"文件需要配置编译模块开启参数,拷贝 settings.gradle-demo 为 settings.gradle 文件取消对应的分支配置部分即可。) +$bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名>  +或者是 +$bash gradlew assembleStageRelease -一、项目概述 - -1. 核心定位 - -【OriginMaster】WinBoLL 源生态计划,旨在通过核心项目 WinBoLL 联动系列开发库,构建手机端 Android 项目开发与多端编译同步的完整生态,实现手机与电脑的源码同步开发。 - -2. 仓库架构 - -仓库类型 包含仓库 功能说明 -开发库 WinBoLL、APPBase、AES、PowerBell、Positions 核心开发依赖库,其中 WinBoLL 可作为应用开发的基础继承模板 -分支汇总存档库 OriginMaster 仅用于汇总各开发库分支,不适宜作为开发库克隆使用,非应用开发基础库 - -3. 源码推送路径 - -- WinBoLL → APPBase → OriginMaster -- WinBoLL → AES → OriginMaster -- WinBoLL → PowerBell → OriginMaster -- WinBoLL → Positions → OriginMaster - -二、WinBoLL APP 核心信息 - -1. 项目简介 - -WinBoLL Studio Android 应用开源项目,专注于手机端 Android 开发与多端编译同步。 - -2. 官方资源 - -- 官方网站:https://www.winboll.cc/ -- 源码地址: -- Gitea:https://gitea.winboll.cc/Studio/WinBoLL.git -- GitHub:https://github.com/ZhanGSKen/WinBoLL.git -- 码云:https://gitee.com/zhangsken/winboll.git -- 托管类库源码: -- APPBase(jitpack.io):https://github.com/ZhanGSKen/APPBase.git -- AES(jitpack.io):https://github.com/ZhanGSKen/AES.git - -三、通用特征文件夹前置(/sdcard) - -- Linux 系统文件夹直接使用  /sdcard 。 -- 手机 SD 卡存储( /storage/emulated/0 )挂载的别名也可为  /sdcard 。 - -四、前置条件 - -1. WinBoLL-APP 配置 - -- APK 编译输出目录: /sdcard/WinBoLLStudio/APKs/ ,以及  /sdcard/AppProjects/ (命名为  app.apk ) -- 签名与命名空间:支持应用签名验证定制化,与衍生 APP 共享  cc.winboll.studio  命名空间 - -五、核心需求规划 - -1. 主机端需求 - -- 支持  winboll.cc  域名的用户注册登录服务 -- 支持  https://console.winboll.cc/api  访问 - -2. APP 端需求 - -- 实现手机端 Android 应用开发与管理功能 - -六、编译与使用指南 - -1. 项目初始化(必须) - -1. 复制  settings.gradle-demo  为  settings.gradle ,取消对应项目模块注释 -2. 复制  gradle.properties-androidx-demo  或  gradle.properties-android-demo  为  gradle.properties  -3. (可选)复制  local.properties-demo  为  local.properties ,配置 Android SDK 目录 -4. 签名设置: -- 调试编译:进入 GenKeyStore 目录执行  bash gen_debug_keystore.sh  -- 非必须:clone keystore 模块,拷贝  appkey.jks  与  appkey.keystore  到项目根目录 - -2. 编译命令 - -(1)类库型项目 - -1. 修改测试项目  build.properties ,设置  libraryProject=<类库项目模块名>  -2. 编译测试项目: bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名>  -3. 编译类库项目: bash .winboll/bashPublishLIBAddTag.sh <类库项目模块名> (发布至 WinBoLL Nexus Maven 库) - -(2)应用型项目 - -- 编译命令: bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名>  - -(3)调试编译 - -- Beta 调试: bash gradlew assembleBetaDebug  -- Stage 调试: bash gradlew assembleStageDebug -  -(4)发布编译 - -- Stage 发布:bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名>  - 或者执行  bash gradlew assembleStageRelease - -3. 编译输出路径 - -- 默认路径(assembleBetaDebug任务): /sdcard/WinBoLLStudio/APKs/<项目根目录名称>/debug/  -- 默认路径(assembleStageRelease任务): /sdcard/WinBoLLStudio/APKs/<项目根目录名称>/tag/  -- 额外路径:若  winboll.properties  配置  ExtraAPKOutputPath ,APK 同步拷贝至该ExtraAPKOutputPath路径 - -4. 版本号命名规则 - -- Stage 渠道: V<应用开发环境编号><应用功能变更号><应用调试阶段号> (示例: APPBase_15.7.0 ) -- Beta 渠道: V<应用开发环境编号><应用功能变更号><应用调试阶段号>-beta<调试编译计数>_<调试编译时间(分钟+秒钟)> (示例: APPBase_15.9.6-beta8_5413 ) + +## 八、WinBoLL 应用 APK 版本号命名规则 +### ☆ Stage 渠道: +#### V<应用开发环境编号><应用功能变更号><应用调试阶段号> (示例: APPBase_15.7.0 ) +### ☆ Beta 渠道: +#### V<应用开发环境编号><应用功能变更号><应用调试阶段号>-beta<调试编译计数>_<调试编译时间(分钟+秒钟)> (示例: APPBase_15.9.6-beta8_5413 ) diff --git a/winboll/build.properties b/winboll/build.properties index dd56b55..0bd5fb1 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 -stageCount=15 +#Mon Mar 16 19:52:21 GMT 2026 +stageCount=26 libraryProject= baseVersion=15.11 -publishVersion=15.11.14 -buildCount=0 -baseBetaVersion=15.11.15 +publishVersion=15.11.25 +buildCount=29 +baseBetaVersion=15.11.26 diff --git a/winboll/src/main/AndroidManifest.xml b/winboll/src/main/AndroidManifest.xml index 74b3ee5..1477fdc 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..38544f6 --- /dev/null +++ b/winboll/src/main/java/cc/winboll/studio/winboll/termux/NfcTermuxBridgeActivity.java @@ -0,0 +1,241 @@ +/* + * 源码说明与描述: + * NFC 与 Termux 桥接活动,用于接收外部应用(包调用)传递的 JSON 指令并执行 Termux 脚本命令。 + * 支持 ACTION_BUILD(后台执行)与 ACTION_BUILD_VIEW(终端窗口唤起)两种动作。 + * + * 作者:豆包&ZhanGSKen + * 创建时间:2025-03-15 14:00:00 + * 最后编辑时间:2026-03-16 10:00: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.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 { + + // ========================= 常量与静态属性 ========================= + public static final String TAG = "NfcTermuxBridgeActivity"; + + // 外部应用调用时使用的 Action 常量 + public static final String ACTION_BUILD = "cc.winboll.studio.winboll.termux.NfcTermuxBridgeActivity.ACTION_BUILD"; + + private static final Gson GSON = new Gson(); + + // ========================= 生命周期方法 ========================= + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + LogUtils.d(TAG, "onCreate() 调用,savedInstanceState: " + (savedInstanceState != null ? "非空" : "空")); + dispatchIntent(getIntent()); + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(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 分发(合并去重) ========================= + /** + * 统一分发 Intent,根据 Action 路由到不同业务逻辑 + * @param intent 外部传入的 Intent + */ + private void dispatchIntent(Intent intent) { + LogUtils.d(TAG, "dispatchIntent() 分发 intent"); + if (intent == null) { + LogUtils.w(TAG, "dispatchIntent() intent is null"); + return; + } + + String action = intent.getAction(); + if (ACTION_BUILD.equals(action)) { + ToastUtils.show("ACTION_BUILD 命中"); + onOpenTermuxProjectBuild(intent); + } else { + LogUtils.w(TAG, "dispatchIntent() 未知 Action: " + action); + finish(); + } + } + + // ========================= 核心业务方法 ========================= + /** + * 处理 ACTION_BUILD 动作:后台执行 NFC 指令 + */ +// private void handleNfcIntent(Intent intent) { +// 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); +// +// if (json == null || json.isEmpty()) { +// LogUtils.e(TAG, "handleNfcIntent() 指令为空"); +// showToast("指令为空"); +// finish(); +// return; +// } +// +// NfcTermuxCmd cmd = GSON.fromJson(json, NfcTermuxCmd.class); +// LogUtils.d(TAG, "handleNfcIntent() cmd: " + cmd); +// +// if (cmd.script == null || cmd.script.isEmpty()) { +// LogUtils.e(TAG, "handleNfcIntent() script 为空"); +// showToast("script 不能为空"); +// finish(); +// return; +// } +// +// //String scriptPath = "/data/data/com.termux/files/home/TermuxWorkSpaces/BashShells/AutoNFC/" + cmd.script; +// String scriptPath = "/data/data/com.termux/files/home/TermuxWorkSpaces/BashShells/AutoNFC/" + "BuildWinBoLLProject.sh"; +// LogUtils.d(TAG, "handleNfcIntent() 脚本路径: " + scriptPath); +// +// boolean success = TermuxCommandExecutor.executeCommand( +// this, scriptPath, cmd.args, cmd.workDir, cmd.background, cmd.resultDir +// ); +// LogUtils.d(TAG, "handleNfcIntent() 执行结果: " + success); +// +// if (success) { +// showToast("指令已发送: " + cmd.script); +// LogUtils.i(TAG, "执行成功: " + scriptPath); +// } else { +// showToast("指令发送失败"); +// LogUtils.e(TAG, "执行失败"); +// } +// +// } catch (Exception e) { +// LogUtils.e(TAG, "handleNfcIntent() 异常: " + e.getMessage(), e); +// showToast("解析失败"); +// } finally { +// finish(); +// } +// } + + /** + * 处理 ACTION_BUILD_VIEW 动作:唤起 Termux 窗口执行命令 + */ + public void onOpenTermuxProjectBuild(Intent intent) { + LogUtils.d(TAG, "onOpenTermuxProjectBuildView() 调用"); + if (intent == null) { + LogUtils.w(TAG, "onOpenTermuxProjectBuildView() intent 为空"); + return; + } + + try { + String json = intent.getStringExtra(Intent.EXTRA_TEXT); + LogUtils.d(TAG, "onOpenTermuxProjectBuildView() json: " + json); + + if (json == null || json.isEmpty()) { + LogUtils.e(TAG, "onOpenTermuxProjectBuildView() 指令为空"); + showToast("指令为空"); + finish(); + return; + } + + NfcTermuxCmd cmd = GSON.fromJson(json, NfcTermuxCmd.class); + LogUtils.d(TAG, "onOpenTermuxProjectBuildView() cmd: " + cmd); + + if (cmd.script == null || cmd.script.isEmpty()) { + LogUtils.e(TAG, "onOpenTermuxProjectBuildView() script 为空"); + showToast("script 不能为空"); + finish(); + return; + } + + 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(" "); + targetCmd.append("stdbuf -o0 -e0 -i0 bash ").append("BuildWinBoLLProject.sh").append(" "); + if (cmd.args != null) { + for (String arg : cmd.args) { + targetCmd.append(arg).append(" "); + } + } + + LogUtils.d(TAG, "onOpenTermuxProjectBuildView() 命令: " + targetCmd); + boolean cmdSuccess = TermuxCommandExecutor.executeTerminalCommand(this, targetCmd.toString()); + LogUtils.d(TAG, "onOpenTermuxProjectBuildView() 执行结果: " + cmdSuccess); + + if (cmdSuccess) { + showToast("指令已发送: " + cmd.script); + } else { + showToast("指令发送失败"); + } + + } catch (Exception e) { + LogUtils.e(TAG, "onOpenTermuxProjectBuildView() 异常: " + e.getMessage(), e); + showToast("解析失败"); + } finally { + finish(); + } + } + + // ========================= 公共静态测试方法 ========================= + /** + * 内部测试方法:发送 ACTION_BUILD 指令 + */ + 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 intent = new Intent(context, NfcTermuxBridgeActivity.class); + intent.setAction(ACTION_BUILD); // 指定 Action + intent.putExtra(Intent.EXTRA_TEXT, testJson); + context.startActivity(intent); + } catch (Exception e) { + LogUtils.e(TAG, "testCommand() 失败: " + e.getMessage()); + } + } + + /** + * 内部测试方法:发送 ACTION_BUILD_VIEW 指令 + */ +// 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 intent = new Intent(context, NfcTermuxBridgeActivity.class); +// intent.setAction(ACTION_BUILD_VIEW); // 指定 Action +// intent.putExtra(Intent.EXTRA_TEXT, testJson); +// context.startActivity(intent); +// } catch (Exception e) { +// LogUtils.e(TAG, "testViewCommand() 失败: " + e.getMessage()); +// } +// } + + // ========================= 工具方法 ========================= + /** + * 统一显示 Toast,确保在主线程调用 + */ + private void showToast(final String message) { + runOnUiThread(new Runnable() { + @Override + public void run() { + Toast.makeText(NfcTermuxBridgeActivity.this, message, Toast.LENGTH_SHORT).show(); + } + }); + } +} + 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..4b07046 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 @@ -38,8 +38,8 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity { // 常量属性(置顶排列) public static final String TAG = "TermuxEnvTestActivity"; - private static final String TERMUX_HOME_PATH = "/sdcard/WinBoLLStudio"; - private static final String CMD_RESULT_FILE = TERMUX_HOME_PATH + "/.authcenter_cmd_result.tmp"; + private static final String TERMUX_HOME_PATH = "/data/data/com.termux/files/home/TermuxWorkSpaces"; + private static final String CMD_RESULT_FILE = TERMUX_HOME_PATH + "/CMD_RESULT_FILE.log"; // 成员属性(常量后排列) private Toolbar mToolbar; @@ -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() 初始化完成"); } @@ -158,7 +158,7 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity { /** * 测试执行Gradle命令(实时输出版,唤起Termux窗口) */ - public void onTestTermuxCMD(View view) { + public void onTestTermuxGradleBuildCMD(View view) { LogUtils.d(TAG, "onTestTermuxCMD() 按钮点击,执行Gradle命令(实时输出)"); tvMessage.append("\n【测试:执行Gradle命令(实时输出)】\n"); @@ -171,7 +171,7 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity { // 2. 定义核心路径(确保路径与Termux中一致) String gradleFullPath = "/data/data/com.termux/files/home/gradle/gradle-7.5.1/bin/gradle"; - String projectPath = TERMUX_HOME_PATH + "/Sources/WinBoLL"; // 项目目录 + String projectPath = TERMUX_HOME_PATH + "/Sources/DebugTemp"; // 项目目录 // 3. 构造命令(核心:用stdbuf禁用缓冲,实现实时输出) String targetCmd = ""; @@ -216,7 +216,17 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity { tvMessage.append("💡 若未实时输出,请在Termux中执行:pkg install coreutils(安装stdbuf)\n"); tvMessage.append("-------------------------\n"); } + + public void onTestWinBoLLProjectBuild(View view) { + ToastUtils.show("onTestWinBoLLProjectBuild"); + NfcTermuxBridgeActivity.testCommand(this); + } +// public void onTestWinBoLLProjectBuildView(View view) { +// ToastUtils.show("onTestWinBoLLProjectBuildView"); +// NfcTermuxBridgeActivity.testViewCommand(this); +// } + public void onOpenTermuxBash(View view) { LogUtils.d(TAG, "onTestTermuxCMD() 按钮点击,执行Gradle命令(实时输出)"); tvMessage.append("\n【测试:执行Gradle命令(实时输出)】\n"); @@ -230,7 +240,7 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity { // 2. 定义核心路径(确保路径与Termux中一致) String gradleFullPath = "/data/data/com.termux/files/home/gradle/gradle-7.5.1/bin/gradle"; - String projectPath = TERMUX_HOME_PATH + "/Sources/WinBoLL"; // 项目目录 + String projectPath = TERMUX_HOME_PATH + "/"; // 项目目录 // 3. 构造命令(核心:用stdbuf禁用缓冲,实现实时输出) String targetCmd = ""; @@ -275,7 +285,7 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity { tvMessage.append("💡 若未实时输出,请在Termux中执行:pkg install coreutils(安装stdbuf)\n"); tvMessage.append("-------------------------\n"); } - + /** * 跨包读取Termux命令结果文件(保留原功能,兼容其他场景) */ @@ -399,7 +409,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..0ca36f3 100644 --- a/winboll/src/main/res/layout/activity_termux_env_test.xml +++ b/winboll/src/main/res/layout/activity_termux_env_test.xml @@ -16,25 +16,35 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="right"> - +