Termux终端调用接口完成
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
#Created by .winboll/winboll_app_build.gradle
|
#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
|
stageCount=15
|
||||||
libraryProject=
|
libraryProject=
|
||||||
baseVersion=15.11
|
baseVersion=15.11
|
||||||
publishVersion=15.11.14
|
publishVersion=15.11.14
|
||||||
buildCount=0
|
buildCount=9
|
||||||
baseBetaVersion=15.11.15
|
baseBetaVersion=15.11.15
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
tools:ignore="QueryAllPackagesPermission" />
|
tools:ignore="QueryAllPackagesPermission" />
|
||||||
<!-- 可选:兼容低版本系统 -->
|
<!-- 可选:兼容低版本系统 -->
|
||||||
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
|
<uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@drawable/ic_launcher"
|
android:icon="@drawable/ic_launcher"
|
||||||
@@ -291,6 +291,15 @@
|
|||||||
|
|
||||||
<activity android:name="cc.winboll.studio.winboll.unittest.TermuxEnvTestActivity"/>
|
<activity android:name="cc.winboll.studio.winboll.unittest.TermuxEnvTestActivity"/>
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".termux.NfcTermuxBridgeActivity"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="cc.winboll.nfc.ACTION_EXEC_TERMUX" />
|
||||||
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -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)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package cc.winboll.studio.winboll.unittest;
|
package cc.winboll.studio.winboll.unittest;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@@ -7,11 +8,11 @@ import android.view.View;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.appcompat.widget.Toolbar;
|
import androidx.appcompat.widget.Toolbar;
|
||||||
import cc.winboll.studio.libaes.utils.WinBoLLActivityManager;
|
|
||||||
import cc.winboll.studio.libappbase.LogUtils;
|
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.R;
|
||||||
import cc.winboll.studio.winboll.activities.BaseWinBoLLActivity;
|
import cc.winboll.studio.winboll.activities.BaseWinBoLLActivity;
|
||||||
|
import cc.winboll.studio.winboll.termux.NfcTermuxBridgeActivity;
|
||||||
import cc.winboll.studio.winboll.termux.TermuxCommandExecutor;
|
import cc.winboll.studio.winboll.termux.TermuxCommandExecutor;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@@ -19,7 +20,6 @@ import java.io.FileInputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import android.app.Activity;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
* @Author 豆包&ZhanGSKen<zhangsken@qq.com>
|
||||||
@@ -103,12 +103,12 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity {
|
|||||||
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||||
|
|
||||||
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
LogUtils.d(TAG, "initToolbar() 导航栏返回按钮点击");
|
LogUtils.d(TAG, "initToolbar() 导航栏返回按钮点击");
|
||||||
getActivity().finish();
|
getActivity().finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
LogUtils.d(TAG, "initToolbar() 初始化完成");
|
LogUtils.d(TAG, "initToolbar() 初始化完成");
|
||||||
}
|
}
|
||||||
@@ -216,7 +216,12 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity {
|
|||||||
tvMessage.append("💡 若未实时输出,请在Termux中执行:pkg install coreutils(安装stdbuf)\n");
|
tvMessage.append("💡 若未实时输出,请在Termux中执行:pkg install coreutils(安装stdbuf)\n");
|
||||||
tvMessage.append("-------------------------\n");
|
tvMessage.append("-------------------------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onTestWinBoLLProjectBuild(View view) {
|
||||||
|
ToastUtils.show("onOpenTermuxBash");
|
||||||
|
NfcTermuxBridgeActivity.testCommand(this);
|
||||||
|
}
|
||||||
|
|
||||||
public void onOpenTermuxBash(View view) {
|
public void onOpenTermuxBash(View view) {
|
||||||
LogUtils.d(TAG, "onTestTermuxCMD() 按钮点击,执行Gradle命令(实时输出)");
|
LogUtils.d(TAG, "onTestTermuxCMD() 按钮点击,执行Gradle命令(实时输出)");
|
||||||
tvMessage.append("\n【测试:执行Gradle命令(实时输出)】\n");
|
tvMessage.append("\n【测试:执行Gradle命令(实时输出)】\n");
|
||||||
@@ -275,7 +280,7 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity {
|
|||||||
tvMessage.append("💡 若未实时输出,请在Termux中执行:pkg install coreutils(安装stdbuf)\n");
|
tvMessage.append("💡 若未实时输出,请在Termux中执行:pkg install coreutils(安装stdbuf)\n");
|
||||||
tvMessage.append("-------------------------\n");
|
tvMessage.append("-------------------------\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 跨包读取Termux命令结果文件(保留原功能,兼容其他场景)
|
* 跨包读取Termux命令结果文件(保留原功能,兼容其他场景)
|
||||||
*/
|
*/
|
||||||
@@ -399,7 +404,7 @@ public class TermuxEnvTestActivity extends BaseWinBoLLActivity {
|
|||||||
String filePath = file.getAbsolutePath();
|
String filePath = file.getAbsolutePath();
|
||||||
String fileSize = file.isFile() ? " | 大小:" + formatFileSize(file.length()) : "";
|
String fileSize = file.isFile() ? " | 大小:" + formatFileSize(file.length()) : "";
|
||||||
String filePerm = " | 权限:r:" + file.canRead() + "/w:" + file.canWrite();
|
String filePerm = " | 权限:r:" + file.canRead() + "/w:" + file.canWrite();
|
||||||
|
|
||||||
result.append(fileType);
|
result.append(fileType);
|
||||||
result.append(" ");
|
result.append(" ");
|
||||||
result.append(fileName);
|
result.append(fileName);
|
||||||
|
|||||||
@@ -34,6 +34,12 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="TestTermuxEnv"
|
android:text="TestTermuxEnv"
|
||||||
android:onClick="onTestTermuxEnv"/>
|
android:onClick="onTestTermuxEnv"/>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Test WinBoLL Project Build"
|
||||||
|
android:onClick="onTestWinBoLLProjectBuild"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user