// 开启深色模式(系统级)
function enableDark() {
var cmd = "settings put secure ui_night_mode 2";
var r = shell(cmd, false);
log("启用深色");
log("code: " + r.code);
log("结果: " + r.result);
toast(r.code == 0 ? "深色已开启" : "失败");
}
// 开启浅色模式
function disableDark() {
var cmd = "settings put secure ui_night_mode 1";
var r = shell(cmd, false);
log("启用浅色");
log("code: " + r.code);
toast(r.code == 0 ? "浅色已开启" : "失败");
}
// 运行
enableDark();
// disableDark(); 这个怎么更改成hamibot能使用?
显示code 255, 没有效果
已经给了ADB授权,WRITE_SECURE_SETTINGS,但还是不成功
回答
这段代码的语法基本符合 Hamibot 规范,主要需要补充脚本头部注释,并注意 shell 命令的权限要求。修改后的代码如下:
// 文档地址 https://docs.hamibot.com/
// 开启深色模式(系统级)
function enableDark() {
var cmd = "settings put secure ui_night_mode 2";
// 第二个参数为 true 表示尝试以 root 权限运行,若设备未 root 可能失败
var r = shell(cmd, true);
log("启用深色");
log("code: " + r.code);
log("结果: " + r.result);
log("错误: " + r.error);
toast(r.code == 0 ? "深色已开启" : "失败");
}
// 开启浅色模式
function disableDark() {
var cmd = "settings put secure ui_night_mode 1";
var r = shell(cmd, true);
log("启用浅色");
log("code: " + r.code);
toast(r.code == 0 ? "浅色已开启" : "失败");
}
// 运行
enableDark();
// disableDark();
关键修改与说明
-
脚本头部注释
Hamibot 脚本建议在开头添加文档地址注释,便于维护和识别。 -
权限要求(重要)
settings put secure命令修改的是系统安全设置,通常需要 Root 权限 或通过电脑 ADB 授予WRITE_SECURE_SETTINGS权限。- 如果设备已 Root:将
shell函数的第二个参数设为true。 - 如果设备未 Root:该命令通常会返回
Permission denied错误,无法生效。未 Root 设备建议通过模拟点击设置界面来实现模式切换。
- 如果设备已 Root:将
-
兼容性注意
- Android 版本差异:不同品牌手机(如 MIUI、ColorOS 等)的深色模式设置命令可能不同,
ui_night_mode适用于原生 Android 及部分定制系统。 - JavaScript 引擎:Hamibot 使用 Rhino 1.7.15 引擎,代码中避免使用箭头函数、默认参数等 ES6+ 特性。当前代码使用
var和常规函数声明,符合兼容性要求。
- Android 版本差异:不同品牌手机(如 MIUI、ColorOS 等)的深色模式设置命令可能不同,
-
运行稳定性
确保 Hamibot 应用在后台保持运行。参考最佳实践,开启自启动、关闭省电策略、打开前台服务,防止脚本执行中途被系统杀死。 -
调试信息
增加了log("错误:" + r.error);,方便在控制台查看具体的失败原因(如权限不足)。
补充回答 1
出现 code: 255 且没有效果,核心原因是 权限不足。settings put secure 属于系统安全设置,普通应用无法直接修改,必须满足以下条件之一才能生效:
- 设备已 Root:且 Hamibot 已获取 Root 授权。
- 通过 ADB 授权:通过电脑 ADB 命令给 Hamibot 授予
WRITE_SECURE_SETTINGS权限(部分 ROM 不支持)。 - 使用 UI 自动化:不修改系统设置,而是模拟点击设置界面(兼容性好,无需 Root)。
解决方案 1:确认 Root 权限(如果设备已 Root)
如果设备已 Root,必须将 shell 函数的第二个参数设为 true,并确保 Hamibot 弹窗请求 Root 权限时点击了“允许”。
// 文档地址 https://docs.hamibot.com/
function enableDark() {
var cmd = "settings put secure ui_night_mode 2";
// 必须设为 true 以请求 Root 权限
var r = shell(cmd, true);
log("启用深色模式");
log("返回码:" + r.code);
log("输出:" + r.result);
log("错误:" + r.error);
if (r.code === 0) {
toast("深色已开启");
} else {
toast("失败,请检查 Root 权限");
}
}
enableDark();
注意:如果 r.error 显示 Permission denied,说明没有 Root 权限或授权失败。
解决方案 2:UI 自动化(推荐非 Root 设备)
如果没有 Root 权限,建议使用 UI 自动化模拟点击设置界面。由于不同品牌手机(小米、华为、OPPO 等)的设置界面路径不同,以下代码以原生 Android 为例,你需要根据实际手机调整文本内容。
// 文档地址 https://docs.hamibot.com/
function toggleDarkModeByUI() {
// 1. 打开设置页面
app.startActivity("android.settings.DISPLAY_SETTINGS");
sleep(2000);
// 2. 查找并点击“深色模式”或“夜间模式”开关
// 注意:不同手机文案不同,可能需要调整为“黑暗模式”、“暗夜模式”等
var switchWidget = text("深色模式").findOne(5000) || text("夜间模式").findOne(5000);
if (switchWidget) {
switchWidget.click();
toast("已尝试切换深色模式");
} else {
toast("未找到深色模式开关,请手动调整");
// 如果找不到,可以尝试滑动屏幕后再找
// scrollDown();
}
}
toggleDarkModeByUI();
解决方案 3:检查 ROM 兼容性
部分定制系统(如 MIUI、ColorOS)不使用 ui_night_mode 这个设置项,或者该设置项被隐藏。
- 小米 (MIUI):可能需要使用
settings put secure dark_mode_enabled 1。 - 三星 (OneUI):可能使用
night_mode。 - 原生 Android:
ui_night_mode通常有效(值为 1 浅色,2 深色,0 自动)。
调试建议
- 查看错误日志:在 Hamibot 控制台查看
r.error的具体内容。如果是Permission denied,则确定是权限问题。 - 验证命令:在电脑连接手机 ADB,手动执行
adb shell settings put secure ui_night_mode 2。如果 ADB 能成功但脚本失败,说明是脚本运行环境权限不足;如果 ADB 也失败,说明该命令不适用于你的手机系统。 - 保持后台运行:确保 Hamibot 应用在后台存活,开启前台服务,防止脚本执行中途被系统杀死。
总结:code: 255 代表命令执行失败。非 Root 设备请直接使用 解决方案 2(UI 自动化),这是最稳定且兼容 Hamibot 标准环境的方式。
补充回答 2
出现 code 255 且已授予 ADB 权限仍失败,通常是因为 Android 系统机制或厂商限制 导致 shell 命令无法继承 ADB 授予的权限。pm grant 授予的权限主要适用于 Java API 调用,而脚本中的 shell() 函数启动的是子进程,部分 ROM(如 MIUI、ColorOS 等)会拦截该子进程的系统设置修改请求。
以下是排查步骤和最终解决方案:
1. 确认 Hamibot 包名是否正确
ADB 授权必须针对 Hamibot 的具体包名。如果包名错误,授权无效。
- Hamibot 常见包名:
com.hamibot.client - 验证命令(在电脑 ADB 执行):
adb shell pm list packages | grep hamibot - 重新授权命令(替换为实际包名):
adb shell pm grant com.hamibot.client android.permission.WRITE_SECURE_SETTINGS
2. 验证设置项是否存在
不同 Android 版本和厂商的设置键值不同。ui_night_mode 并非通用。
- 在脚本中运行以下代码检测键值:
// 文档地址 https://docs.hamibot.com/
// 尝试读取当前设置值
var checkCmd = "settings get secure ui_night_mode";
var r = shell(checkCmd, false);
log("读取结果:" + r.result);
log("错误信息:" + r.error);
// 如果结果为空,尝试 system 表
if (!r.result || r.result.trim() === "") {
var checkCmd2 = "settings get system ui_night_mode";
var r2 = shell(checkCmd2, false);
log("System 表结果:" + r2.result);
}
- 如果读取返回空或错误,说明该键值在你的设备上无效,需寻找对应厂商的键值(如小米可能是
dark_mode_enabled)。
3. 代码调整:尝试不使用 Root 模式
既然已授予 ADB 权限,shell 函数的第二个参数应设为 false(以应用权限运行),而非 true(Root 模式)。true 会尝试调用 su,若未 Root 则直接失败。
// 文档地址 https://docs.hamibot.com/
function enableDark() {
var cmd = "settings put secure ui_night_mode 2";
// 已授权 ADB 权限时,此处应为 false
var r = shell(cmd, false);
log("命令:" + cmd);
log("返回码:" + r.code);
log("错误:" + r.error);
if (r.code === 0) {
toast("设置成功");
} else {
toast("设置失败:" + r.error);
}
}
enableDark();
4. 终极方案:UI 自动化(最稳定)
如果上述方法均无效,说明厂商底层限制了非系统应用修改该设置。此时 UI 自动化 是唯一可靠方案,它模拟人手操作,不依赖系统权限。
// 文档地址 https://docs.hamibot.com/
function toggleDarkByUI() {
// 1. 打开显示设置
// 不同手机可能不同,尝试通用意图
app.startActivity("android.settings.DISPLAY_SETTINGS");
sleep(3000);
// 2. 查找开关文本
// 常见文本:"深色模式"、"夜间模式"、"黑暗模式"、"暗色主题"
var keywords = ["深色模式", "夜间模式", "黑暗模式", "暗色主题", "Dark Mode"];
var found = false;
for (var i = 0; i < keywords.length; i++) {
var widget = text(keywords[i]).findOne(2000);
if (widget) {
// 找到文本后,尝试点击其右侧的开关
// 通常开关是文本的父级或兄弟节点,这里直接点击文本可能进入子菜单
// 更稳妥的是点击文本所在的行
widget.parent().click();
sleep(1000);
found = true;
toast("已尝试切换:" + keywords[i]);
break;
}
}
if (!found) {
// 如果没找到,尝试滑动查找
toast("未找到开关,尝试滑动查找");
scrollDown();
sleep(1000);
// 可在此处添加二次查找逻辑
}
}
toggleDarkByUI();
5. 厂商特定键值参考
如果坚持使用 shell 命令,请根据手机品牌尝试以下键值:
- 原生/三星:
settings put secure ui_night_mode 2 - 小米 (MIUI):
settings put secure dark_mode_enabled 1 - 华为/荣耀:
settings put secure dark_mode_on 1 - OPPO/Vivo:可能无直接命令,必须用 UI 自动化。
总结建议
- 优先使用 UI 自动化:兼容性最好,不受系统权限更新影响。
- 检查错误日志:重点关注
r.error的内容,如果是Permission denied,说明 ADB 授权未生效或被系统拦截。 - 确保后台存活:执行脚本时,确保 Hamibot 应用在后台未被杀死,否则
shell进程可能中途终止。