Termux RunCommandService 回调的结果 Bundle 为什么为空?
结论:结果回调需要可变的 PendingIntent
所给代码中的 PendingIntent.FLAG_IMMUTABLE 会阻止 Termux 发送回调时补入结果数据。应移除该标志,并在 Android 12(API 31)及以上使用 PendingIntent.FLAG_MUTABLE。
Android 文档说明,设置 FLAG_IMMUTABLE 后,调用方通过 send() 传入、用于补充原始 Intent 的数据会被忽略。这可以解释当前现象:预先设置的 execution_id 仍然存在,后来加入的结果 Bundle 却没有进入回调。PendingIntent 官方说明
修改 PendingIntent 的创建代码
在 TermuxUtils.java 中添加:
import android.os.Build;
将创建回调 Intent 和 PendingIntent 的部分替换为:
int execId = TermuxPluginResultsService.getNextExecutionId();
Intent pluginResultsService =
new Intent(context, TermuxPluginResultsService.class);
pluginResultsService.putExtra(
TermuxPluginResultsService.EXTRA_EXECUTION_ID,
execId
);
int flags = PendingIntent.FLAG_ONE_SHOT;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
flags |= PendingIntent.FLAG_MUTABLE;
}
PendingIntent pendingIntent = PendingIntent.getService(
context,
execId,
pluginResultsService,
flags
);
intent.putExtra(
TermuxConstants.TERMUX_APP.RUN_COMMAND_SERVICE.EXTRA_PENDING_INTENT,
pendingIntent
);
context.startForegroundService(intent);
要引用 Build.VERSION_CODES.S 和 FLAG_MUTABLE,compileSdk 需要至少为 31。API 30 及以下在未设置 FLAG_IMMUTABLE 时默认允许修改;API 31 及以上则通过上述分支显式设置可变性。不要同时设置 FLAG_MUTABLE 和 FLAG_IMMUTABLE。PendingIntent 可变性说明
保留原来的显式组件 new Intent(context, TermuxPluginResultsService.class),使回调继续指向指定服务。
保留结果 Bundle 的读取方式
现有读取方式符合 Termux 文档:通过请求中的 EXTRA_PENDING_INTENT 指定回调,再从回调 Intent 的 EXTRA_PLUGIN_RESULT_BUNDLE 中读取结果。EXTRA_BACKGROUND 为 true 时,该 Bundle 提供 stdout、stderr 和 exit code。Termux 结果回传说明
先保留现有读取逻辑,用简单命令验证:
TermuxUtils.exec(this, "echo HelloWorld");
验证时依次检查:
onHandleIntent是否被调用。EXTRA_PLUGIN_RESULT_BUNDLE是否存在。stdout是否包含HelloWorld。exitCode是否为0。
这些是正常执行时的预期结果,并非当前设备上已经验证过的日志。stderr 可以为空,不能仅凭它为空判断回传失败。
问题中额外添加的 RUN_COMMAND_RETURN_STDOUT、return_stdout 等键不属于该文档列出的结果回传参数,可以移除。修复重点是回调 PendingIntent 的可变性。
为什么迁移 AndroidX 后才出现
现有材料不足以认定 AndroidX 本身导致了故障。当前代码显式设置了 FLAG_IMMUTABLE,这与回调需要补入结果数据的要求冲突。
可以对比迁移前后的 PendingIntent 创建代码,以及同步调整过的 SDK 配置。如果迁移期间新增了 FLAG_IMMUTABLE,就能解释这次行为变化;仅凭迁移前后是否正常,无法确定是哪一项改动引起的。
修改后仍为空时检查什么
先确认实际运行的构建已使用修改后的代码,再重新发起一次命令请求。如果仍然失败,检查 Termux 版本和基础配置:结果回传要求 Termux >= 0.109;调用应用需要获授 com.termux.permission.RUN_COMMAND,Termux 的 ~/.termux/termux.properties 中需要设置 allow-external-apps=true。Termux 配置与版本要求
当前日志表明接收服务已经进入 onHandleIntent,应先排查回调数据为何未被补入。确认结果 Bundle 能正常收到后,再测试实际的 git 命令及其工作目录。
备注:内容仅供参考。
