settings 设置
settings 设置
settings 是 ScriptX 当前提供的一组“运行时开关”模块。
它不是 Android 那种系统 Settings 数据库读写器,也不是项目里任意键值都能往里塞的通用配置箱;目前脚本侧真正公开出来的能力,只有两个布尔开关的读取与修改。
如果你第一次接触这页,先记住下面 8 条:
- 模块对象名是
settings,兼容别名是$settings。 - 也可以写
require("settings")取到同一个模块对象。 settings.api只是模块对象自己的自引用,方便统一风格调用。- 当前只有两个合法 key:
"stop_all_on_volume_up""foreground_service"
settings.isEnabled(key)只返回布尔值,未知 key 一律返回false。settings.setEnabled(key, enabled)只接受真正的布尔值;第二参数不是布尔值时,当前实现会按false处理。- 修改未知 key 不会抛错,但会直接返回
false,表示这次没有生效。 - 这页所有说明都按当前源码
ScriptSettingsApi.kt与对应设置存储实现整理,不按旧版口径猜。
当前支持哪些设置项
目前只支持下面这两个 key:
| key | 类型 | 默认值 | 作用 |
|---|---|---|---|
"stop_all_on_volume_up" | boolean | true | 控制“音量上键是否可停止无宿主脚本” |
"foreground_service" | boolean | true | 控制“脚本运行保活相关的 keep-alive 开关是否开启” |
"stop_all_on_volume_up" 是什么
这个开关对应的是无宿主脚本运行时的“音量上键停止全部脚本”行为。
源码里它最终落到:
HostlessScriptSettings.stopOnVolumeUpEnabledHostlessScriptRuntimeController.refreshVolumeUpListener(...)
也就是说,你改完这个开关之后,不只是“写进设置”而已,运行时还会立刻刷新音量上键监听逻辑。
"foreground_service" 是什么
这个开关对应的是调度与保活设置里的 keepAliveEnabled。
源码里它最终落到:
它不是“只控制一个通知栏前台服务开关”这么简单,而是参与整条 keep-alive 判定链。
模块对象怎么拿
直接用全局对象
log(settings.isEnabled("foreground_service"));
用兼容别名 $settings
log($settings.isEnabled("stop_all_on_volume_up"));
用 require("settings")
const runtimeSettings = require("settings");
log(runtimeSettings.isEnabled("foreground_service"));
settings.isEnabled(key)
读取某个运行时开关当前是否开启。
参数
| 参数 | 类型 | 必填 | 可填值 | 说明 |
|---|---|---|---|---|
key | string | 是 | "stop_all_on_volume_up"、"foreground_service" | 要查询的设置项 key |
返回值
| 返回值 | 含义 |
|---|---|
true | 该设置项当前已开启 |
false | 该设置项当前已关闭,或者 key 不受支持 |
支持的 key
"stop_all_on_volume_up"
读取“音量上键停止全部无宿主脚本”是否开启。
const enabled = settings.isEnabled("stop_all_on_volume_up");
log(`音量上键停止脚本: ${enabled}`);
"foreground_service"
读取保活相关 keep-alive 开关是否开启。
const enabled = settings.isEnabled("foreground_service");
log(`保活开关: ${enabled}`);
未知 key 会怎样
当前实现不会抛异常,直接返回 false。
log(settings.isEnabled("not_exists")); // false
所以你不能把 false 简单理解成“用户手动关闭了这个设置”。
它也可能表示“你传的 key 根本不支持”。
一个更稳的写法
const SETTINGS_KEY = {
STOP_ALL_ON_VOLUME_UP: "stop_all_on_volume_up",
FOREGROUND_SERVICE: "foreground_service"
};
log(settings.isEnabled(SETTINGS_KEY.STOP_ALL_ON_VOLUME_UP));
settings.setEnabled(key, enabled)
开启或关闭某个运行时设置。
参数
| 参数 | 类型 | 必填 | 可填值 | 说明 |
|---|---|---|---|---|
key | string | 是 | "stop_all_on_volume_up"、"foreground_service" | 要修改的设置项 |
enabled | boolean | 是 | true、false | 要设置成的状态 |
返回值
| 返回值 | 含义 |
|---|---|
true | 设置成功,并且已写入对应存储 |
false | key 不受支持,没有执行任何实际修改 |
最常见写法
settings.setEnabled("foreground_service", true);
settings.setEnabled("stop_all_on_volume_up", false);
第二参数一定要传真正的布尔值
这一点非常重要。当前实现里第二参数不是“宽松转布尔”,而是:
- 只有真正的
true/false布尔值,才会按对应值处理 - 其他类型最终会被当成
false
也就是说下面这些写法都不安全:
settings.setEnabled("foreground_service", "true");
settings.setEnabled("foreground_service", 1);
settings.setEnabled("foreground_service", "1");
上面这些在当前实现里,最终都可能等价于:
settings.setEnabled("foreground_service", false);
正确示例:先转成明确布尔值
const raw = "true";
const enabled = raw === "true";
settings.setEnabled("foreground_service", enabled);
修改 "stop_all_on_volume_up"
settings.setEnabled("stop_all_on_volume_up", false);
if (!settings.isEnabled("stop_all_on_volume_up")) {
toast("已关闭音量上键停止脚本");
}
这个 key 改完之后,运行时会立刻刷新音量键监听状态,不需要你手动再调一次刷新函数。
修改 "foreground_service"
const ok = settings.setEnabled("foreground_service", true);
log(`set result = ${ok}`);
log(`current = ${settings.isEnabled("foreground_service")}`);
它背后修改的是调度设置里的 keepAliveEnabled。
如果你项目里本身还同时开启了局域网服务、MCP 远程调试等能力,最终是否真的能看到保活效果,要和那些模块的启用状态一起看。
未知 key 会怎样
const ok = settings.setEnabled("unknown_key", true);
log(ok); // false
当前行为是:
- 不抛异常
- 不写入任何数据
- 直接返回
false
settings.api
模块自引用。
作用
主要是让下面这两种风格都能成立:
settings.isEnabled("foreground_service");
settings.api.isEnabled("foreground_service");
返回值
settings.api === settings
示例
const api = settings.api;
log(api === settings); // true
log(api.isEnabled("foreground_service"));
"stop_all_on_volume_up" 的存储与生效链
持久化位置
它会写进:
SharedPreferences("hostless_script_settings")- key:
"stop_on_volume_up"
默认值是 true。
生效过程
调用:
settings.setEnabled("stop_all_on_volume_up", false);
背后大致会做这几步:
- 先读当前设置对象
- 把
stopOnVolumeUpEnabled改成你传入的布尔值 - 写回
SharedPreferences - 调
HostlessScriptRuntimeController.refreshVolumeUpListener(...) - 让运行中的音量键监听逻辑立刻跟新状态对齐
适合什么场景
- 你担心运行脚本时误触音量上键
- 你在做常驻脚本,不想让用户太容易停掉
- 你在做调试脚本,反而希望保留“音量上键紧急停止”的保险丝
"foreground_service" 的存储与生效链
持久化位置
它会写进调度管理器自己的设置存储,对应字段:
ScheduledTaskSettings.keepAliveEnabled
默认值也是 true。
生效过程
调用:
settings.setEnabled("foreground_service", true);
背后大致会做这几步:
- 读取当前调度设置
- 把
keepAliveEnabled改成目标值 - 写回调度设置
- 更新调度管理器的内存状态
是否真的让后台保活服务继续活着,还要看整条 shouldKeepAlive(...) 判定链:
- 是否存在启用中的定时任务
rootWatchdogEnabled是否开启- MCP 远程调试是否开启
- 局域网传输服务是否开启
所以这个 key 更像一个“参与保活链判断的重要开关”,而不是单独的“显示通知按钮”。
当前不支持什么
不支持任意 key
下面这种不会成功:
settings.setEnabled("my_custom_flag", true);
返回值会是 false。
不是 Android 系统设置读写器
你不能拿它去改:
- 系统亮度
- 系统音量
- 开发者选项
Settings.Global / Settings.System / Settings.Secure
要做这些事情,应该看:
不是通用项目配置存储
如果你要存自己的业务配置,比如:
- 用户 token
- 开关状态
- 接口地址
- 上次运行时间
更合适的是:
新手最容易踩的坑
把字符串 "true" 当布尔值传
错误示例:
settings.setEnabled("foreground_service", "true");
当前实现里这不等于 true,最终反而会按 false 处理。
看到 false 就以为是“用户关闭了”
settings.isEnabled("xxx");
如果这里返回 false,有两种可能:
- 这个设置确实被关闭了
- 这个 key 根本不受支持
以为 foreground_service 只控制一个通知
它本质上是调度保活设置里的 keepAliveEnabled,要结合整个保活链理解。
一个完整示例:做一个脚本运行设置页
const SETTINGS = {
STOP_ALL_ON_VOLUME_UP: "stop_all_on_volume_up",
FOREGROUND_SERVICE: "foreground_service"
};
function printSettings() {
log("当前运行时设置:");
log(`- stop_all_on_volume_up = ${settings.isEnabled(SETTINGS.STOP_ALL_ON_VOLUME_UP)}`);
log(`- foreground_service = ${settings.isEnabled(SETTINGS.FOREGROUND_SERVICE)}`);
}
function toggle(key) {
const next = !settings.isEnabled(key);
const ok = settings.setEnabled(key, next);
if (!ok) {
toast(`设置失败: ${key}`);
return false;
}
toast(`${key} -> ${next}`);
return true;
}
printSettings();
toggle(SETTINGS.STOP_ALL_ON_VOLUME_UP);
toggle(SETTINGS.FOREGROUND_SERVICE);
printSettings();
