Compare commits

...

19 Commits

Author SHA1 Message Date
da66cea1e5 详细解析说明 2026-03-18 12:05:42 +08:00
5eb7441dc7 更新说明书 2026-03-18 12:03:32 +08:00
5f3168e17f 更新说明书 2026-03-18 11:49:58 +08:00
e3c4bab6c9 更正项目说明书。 2026-03-18 11:41:23 +08:00
2af6427ca8 精简nfc action 数量 2026-03-17 04:03:20 +08:00
b8c70bef98 调整NFC接口窗体根据动作类型指定对应的脚本运行。 2026-03-16 16:42:02 +08:00
7713d6c460 基本实现NFC Build View 模块功能。 2026-03-15 20:25:16 +08:00
73c69bd665 20260315_193958_991 2026-03-15 19:40:11 +08:00
a076fe50cd 调整Termux 调用模块 UI显示与环境参数配置。 2026-03-15 13:45:49 +08:00
1512b76c36 编译参数修复 2026-03-15 11:55:10 +08:00
850b9af6ec 编译参数修复 2026-03-15 11:52:51 +08:00
31c1592086 Termux终端调用接口完成 2026-03-15 11:50:01 +08:00
b3976a8633 <winboll>APK 15.11.25 release Publish. 2026-03-15 11:48:40 +08:00
ea896228d7 <winboll>APK 15.11.24 release Publish. 2026-03-15 11:46:14 +08:00
d49ecb3943 <winboll>APK 15.11.23 release Publish. 2026-03-15 11:09:40 +08:00
ad3aecf867 <winboll>APK 15.11.22 release Publish. 2026-03-15 11:07:05 +08:00
c417d9732a <winboll>APK 15.11.21 release Publish. 2026-03-15 10:52:23 +08:00
7bd1357c8c <winboll>APK 15.11.20 release Publish. 2026-03-15 10:46:25 +08:00
16a2c3c0c8 <winboll>APK 15.11.19 release Publish. 2026-03-15 10:36:01 +08:00
7 changed files with 363 additions and 77 deletions

View File

@@ -4,26 +4,27 @@ WinBoLL 源生态计划项目说明书
1. 核心定位
【OriginMaster】WinBoLL 源生态计划,旨在通过核心项目 WinBoLL 联动系列开发库,构建手机端 Android 项目开发与多端编译同步的完整生态实现手机与电脑的源码同步开发。
WinBoLL 手机源码计划,旨在通过核心项目 WinBoLL 构建手机端与服务器端的 Android 项目开发源码生态实现手机与服务器的源码的联合开发。
2. 仓库架构
仓库类型 包含仓库 功能说明
开发库 WinBoLL、APPBase、AES、PowerBell、Positions 核心开发依赖库,其中 WinBoLL 可作为应用开发基础继承模板
分支汇总存档库 OriginMaster 仅用于汇总各开发库分支,不适宜作为开发库克隆使用,非应用开发基础库
仓库类型功能说明
基础项目分支 WinBoLL:手机端安卓应用开发基础模板
应用项目分支 APPBase、AES、PowerBell、Positions安卓应用单一管理系列项目。
各类分支源码合并存档 OriginMaster 源码汇总管理,不适宜作为开发库使用。
3. 源码推送路径
3. 源码合并管理推送路线图。仅仅展示不同应用模块源码的综合管理路线。分支合并操作时必须具备Git管理经验。
- WinBoLL → APPBase → OriginMaster
- WinBoLL → AES → OriginMaster
- WinBoLL → PowerBell → OriginMaster
- WinBoLL → Positions → OriginMaster
二、WinBoLL APP 核心信息
二、WinBoLL 项目核心信息
1. 项目简介
WinBoLL Studio Android 应用开源项目,专注于手机端 Android 开发与多端编译同步
WinBoLL 项目是为手机端开发 Android 项目的需求而设计的项目
2. 官方资源
@@ -32,73 +33,71 @@ WinBoLL Studio Android 应用开源项目,专注于手机端 Android 开发与
- Giteahttps://gitea.winboll.cc/Studio/WinBoLL.git
- GitHubhttps://github.com/ZhanGSKen/WinBoLL.git
- 码云https://gitee.com/zhangsken/winboll.git
- 托管类库源码:
- APPBasejitpack.iohttps://github.com/ZhanGSKen/APPBase.git
- AESjitpack.iohttps://github.com/ZhanGSKen/AES.git
三、通用特征文件夹前置(/sdcard
- Linux 系统文件夹直接使用  /sdcard 
- 手机 SD 卡存储( /storage/emulated/0 挂载的别名也可为  /sdcard 
三、WinBoLL 编译环境检查前提:使用通用特征文件夹"/sdcard/WinBoLLStudio/APKs"是否存在为判断条件。
- "/sdcard/WinBoLLStudio/APKs"目录条件设置方法
Linux 服务器端方面:建立 /sdcard/WinBoLLStudio/APKs 目录即可
手机开发端方面:建立 "/sdcard/WinBoLLStudio/APKs"目录(即 "/storage/emulated/0/WinBoLLStudio/APKs"目录) 即可
四、前置条件
1. WinBoLL-APP 配置
1. WinBoLL APP 开发环境配置介绍
- APK 编译输出目录: /sdcard/WinBoLLStudio/APKs/ ,以及  /sdcard/AppProjects/ (命名为  app.apk 
- 签名与命名空间:支持应用签名验证定制化,与衍生 APP 共享  cc.winboll.studio  命名空间
- WinBoLL APK 编译输出内容包括:
  "/sdcard/WinBoLLStudio/APKs" 目录内的所有应用分支的 APK 文件,
与 "/sdcard/AppProjects/app.apk"文件。
- WinBoLL APK 使用 "cc.winboll.studio"  命名空间。
五、核心需求规划
1. 主机端需求
1. WinBoLL 应用安全验证需求
- 支持  https://console.winboll.cc/  访问服务器以校验应用包签名与版本。
- 支持  winboll.cc  域名的用户注册登录服务
- 支持  https://console.winboll.cc/api  访问
2. 手机端源码开发管理需求
2. APP 端需求
- 实现手机端 Android 应用开发与管理功能
- 支持切换不同 WinBoLL 分支,以开发不同安卓应用。
六、编译与使用指南
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 目录
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. 签名设置:
- 调试编译进入 GenKeyStore 目录 bash gen_debug_keystore.sh 
- 非必须clone keystore 模块,拷贝  appkey.jks  appkey.keystore  到项目根目录
- 调试编译秘钥制作:使用 Termux 应用终端 cd 进入 GenKeyStore 目录,运 bash gen_debug_keystore.sh 脚本即可生成应用调试秘钥。
- 应用秘钥配置方法:拷贝调试编译秘钥制作生成的  appkey.jks  appkey.keystore  文件到项目根目录即可。
2. 编译命令
七、应用编译命令介绍
1类库型项目
1类库型模块配置要点
1. 修改测试项目  build.properties 设置  libraryProject=<类库项目模块名> 
2. 编译测试项目: bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名> 
3. 编译类库项目: bash .winboll/bashPublishLIBAddTag.sh <类库项目模块名> 发布至 WinBoLL Nexus Maven 库
1. 优先修改应用测试项目(目录为"<WinBoLl根目录>/<类库测试应用>/")内 build.properties 文件,设置对应的类库项目名称:libraryProject=<类库项目模块名> 
2. 编译优先启动步骤:使用 Termux 应用,进入"<WinBoLl根目录>",运行 $bash .winboll/bashPublishAPKAddTag.sh <类库测试项目模块名> 命令,运行后可生成测试项目与类库项目的编译参数文件 build.properties 。生成的 build.properties 文件有两份,一份在测试项目模块的文件夹内,一份在类库项目本身的模块文件夹内。
3. 类库编译发布步骤:使用 Termux 应用,进入"<WinBoLl根目录>",运行 $bash .winboll/bashPublishLIBAddTag.sh <类库项目模块名> 命令,运行后可发布至 WinBoLL Nexus Maven 库、本地maven目录或者是通用默认的 Gradle Maven 库。
2应用型项目
2单一应用型模块与类库测试型模块配置要点
- 编译命令: bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名> 
- 编译方法:使用 Termux 应用,进入"<WinBoLl根目录>",运行 $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调试编译
3手机端应用调试命令介绍
- Beta 调试: bash gradlew assembleBetaDebug 
- Stage 调试: bash gradlew assembleStageDebug
- 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. 版本号命名规则
4服务器端应用发布命令介绍
- Stage 渠道应用发布命令为("<WinBoLl根目录>/settings.gradle"文件需要配置编译模块开启参数,拷贝 settings.gradle-demo 为 settings.gradle 文件取消对应的分支配置部分即可。):
$bash .winboll/bashPublishAPKAddTag.sh <应用项目模块名> 
或者
$bash gradlew assembleStageRelease
八、WinBoLL 应用 APK 版本号命名规则
- Stage 渠道 V<应用开发环境编号><应用功能变更号><应用调试阶段号> 示例 APPBase_15.7.0 
- Beta 渠道 V<应用开发环境编号><应用功能变更号><应用调试阶段号>-beta<调试编译计数>_<调试编译时间(分钟+秒钟)> 示例 APPBase_15.9.6-beta8_5413 

View File

@@ -1,8 +1,8 @@
#Created by .winboll/winboll_app_build.gradle
#Sun Mar 15 10:26:55 HKT 2026
stageCount=19
#Mon Mar 16 19:52:21 GMT 2026
stageCount=26
libraryProject=
baseVersion=15.11
publishVersion=15.11.18
buildCount=0
baseBetaVersion=15.11.19
publishVersion=15.11.25
buildCount=29
baseBetaVersion=15.11.26

View File

@@ -18,7 +18,7 @@
tools:ignore="QueryAllPackagesPermission" />
<!-- 可选:兼容低版本系统 -->
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
@@ -291,6 +291,18 @@
<activity android:name="cc.winboll.studio.winboll.unittest.TermuxEnvTestActivity"/>
<activity
android:name=".termux.NfcTermuxBridgeActivity"
android:exported="true"> <!-- 必须设置为 true允许外部应用调用 -->
<!-- 接收 ACTION_BUILD 意图 -->
<intent-filter>
<action android:name="cc.winboll.studio.winboll.termux.NfcTermuxBridgeActivity.ACTION_BUILD" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,14 @@
package cc.winboll.studio.winboll.models;
/**
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
* @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
}

View File

@@ -0,0 +1,241 @@
/*
* 源码说明与描述:
* NFC 与 Termux 桥接活动,用于接收外部应用(包调用)传递的 JSON 指令并执行 Termux 脚本命令。
* 支持 ACTION_BUILD后台执行与 ACTION_BUILD_VIEW终端窗口唤起两种动作。
*
* 作者:豆包&ZhanGSKen<zhangsken@qq.com>
* 创建时间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();
}
});
}
}

View File

@@ -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<zhangsken@qq.com>
@@ -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);

View File

@@ -16,25 +16,35 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right">
<Button
android:textAllCaps="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OpenTermuxBash"
android:text="Open Termux Bash"
android:onClick="onOpenTermuxBash"/>
<Button
android:textAllCaps="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestTermuxCMD"
android:onClick="onTestTermuxCMD"/>
android:text="Test Termux Gradle Build CMD"
android:onClick="onTestTermuxGradleBuildCMD"/>
<Button
android:textAllCaps="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TestTermuxEnv"
android:text="Test Termux Env"
android:onClick="onTestTermuxEnv"/>
<Button
android:textAllCaps="false"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test WinBoLL Project Build"
android:onClick="onTestWinBoLLProjectBuild"/>
</LinearLayout>
<ScrollView