鸿蒙真机调试救命两行命令:一行代码把屏幕调成"永不睡觉"

封面:鸿蒙真机熄屏超时速解

一句话总结:hdc shell power-shell timeout -o 86400000 —— 就把当前鸿蒙真机的熄屏时间改成 24 小时,不需要 root、不需要改系统设置、不需要重启。

适用:HarmonyOS 7.0 / OpenHarmony 4.x ~ 6.0 · 真机 & 模拟器

标签:HarmonyOS、OpenHarmony、hdc、power-shell、熄屏超时、PowerManager、真机调试、XTS、自动化测试


一、先说痛点:跑测试跑到一半,屏幕又熄了 😩

不知道你们有没有过这种崩溃:

  • 花了 30 分钟搭好自动化测试环境,脚本刚跑起来,10 分钟到了,屏幕"啪"一下就熄了,整套测试白搭;
  • 抓一批 UI 截图,抓了一半被锁屏打断;
  • 24h soak 稳定性测试直接开跑,结果设备在第 11 分钟锁屏,报告一片红;
  • 想用 Android 那套老办法 adb shell settings put system screen_off_timeout ...,结果鸿蒙 shell 里 settings 压根不存在:/bin/sh: settings: inaccessible or not found;
  • 想搜 param key,param ls -r 被直接怼回来一句 Error: Forbid to list parameters,想靠 grep 猜 key 也行不通。

然后你 Google 了一圈,发现网上那些"从 Android 抄过来"的答案一半是错的,剩下的要么要求 root,要么要求编译源码 —— 太麻烦了。

别急。我踩了整整一天的坑之后,把正确的姿势整理出来了。只要两行命令:

# 设成 24 小时(86400000 毫秒)
hdc shell power-shell timeout -o 86400000

# 用完恢复默认
hdc shell power-shell timeout -r

就这两行,完事。剩下的篇幅就是在解释:这两行到底改了什么东西,为什么重启就没了,想永久的该怎么做,以及我踩过哪些坑——免得你再踩一遍。

📌 亲测环境:HarmonyOS 7.0 真机,设备号留空,2026 年 8 月实测。


二、快速上手:三步搞定

Step 1:确认设备连着

hdc list targets
# 输出示例:xxxxx(你的设备号)

没输出的话先连上,再往下走。

Step 2:一行改超时

hdc shell power-shell timeout -o 86400000
# 输出:Override screen off time to 86400000

单位是毫秒。几个常用值:

时长毫秒值
1 分钟60000
10 分钟600000
24 小时86400000
7 天604800000
“永不息屏”(int32 上限)2147483647

Step 3:验证是否生效

hdc shell "hidumper -s 3301 -a -a" | grep ScreenOffTime

改之前:

ScreenOffTime: Timeout=600000ms

改之后:

ScreenOffTime: Timeout=600000ms  OverrideTimeout=86400000ms

看到 OverrideTimeout=86400000ms 就说明生效了 ✅。


三、工具全貌:power-shell 五个子命令

先看看 power-shell 到底能干啥:

$ hdc shell "power-shell help"
usage: power-shell
command list:
  setmode :    Set power mode.
  wakeup  :    Wakeup system and turn screen on.
  suspend :    Suspend system and turn screen off.
  timeout :    Override or Restore screen off time.
  help    :    Show this help menu.

官方文档(docs/en/application-dev/tools/power-shell.md)对每个子命令的定位很清楚:

子命令干啥典型用法
setmode <id>切电源模式,间接影响熄屏默认值power-shell setmode 602
wakeup唤醒、点亮屏幕power-shell wakeup
suspend挂起、熄灭屏幕power-shell suspend
timeout -o <ms>覆盖熄屏超时(单位 ms)power-shell timeout -o 86400000
timeout -r恢复系统默认power-shell timeout -r

小坑:timeout 参数必须显式给 -o-r,不给你就啥也不做;不带子命令直接跑 power-shell,也不会输出任何提示,别以为 hdc 挂了。


四、四种电源模式:600 / 601 / 602 / 603

除了 timeout -o 直接覆盖之外,还有一条"间接路"——切电源模式。OpenHarmony 定义了 4 档:

Mode ID语义典型场景
600Normal(正常)日常使用,默认档
601Power-saving(省电)缩短熄屏时间,更长待机
602Performance(性能)熄屏时间最长,常用来"永不息屏"
603Super power-saving(超级省电)熄屏时间最短

每档对应 power_mode_config.xml 里的一套默认参数(DisplayOffTime / DimTime / DimLevel 等)。各厂商配置差异很大,我看到的社区配置里 mode 602 一般是 30 秒,但我机器上的默认 600 就 10 分钟了,厂商配置真的不一样,hidumper 实测为准

hdc shell "power-shell setmode 602"
hdc shell "hidumper -s 3301 -a -a" | grep ScreenOffTime

五、原理拆解:OverrideTimeout 到底是怎么"加上去"的

这是本文最有价值的一块,理解了它,你就能解释为什么重启就没了为什么切模式不清 override这些反直觉行为。

原理:PowerManagerService 内存级覆盖

打开 OpenHarmony 源码看 base/powermgr/power_manager/,核心是 PowerManagerService 里维护的三个内存字段:

systemDefaultTimeout   // 系统配置里的默认值,来自 power_mode_config.xml
currentPowerMode       // 当前电源模式(600/601/602/603)
overrideTimeout        // 被 power-shell timeout -o 覆盖的值

最终生效值的计算逻辑大致是:

effective_timeout = overrideTimeout != 0 ? overrideTimeout : systemDefaultTimeout(currentPowerMode)

power-shell timeout -o 走 IPC 发给 PowerManagerService,让它把这个内存字段改一下 —— 只在内存里,不落盘

这解释了几件事:

  1. 重启即失效 —— 进程一重启,内存清零,overrideTimeout 归 0,回到 systemDefaultTimeout;
  2. setmode 不会清 override —— 我实测从 600 切到 601 602 603 来回,OverrideTimeout=86400000ms 一直都在。这是好事,但也容易让人误以为"切了模式应该也跟着变"——记住 OverrideTimeout 是独立覆盖层;
  3. PowerManager 崩溃也会丢 —— 一般碰不到,但系统崩溃恢复时要意识到;
  4. UI 里的"屏幕休眠时间"不会同步 —— 因为你改的是运行时内存,不是设置数据库。UI 里显示的还是系统默认。这是调试用工具,不是用户设置入口;
  5. mode 600 下 override 同样生效 —— 这是很多人踩的坑:setmode 602(性能模式)在商用真机上设不进去,于是以为只有性能模式才能 override,其实 mode 600(默认)下一样生效。见下方"坑 5"里的对照实验。

想看完整状态,除了 ScreenOffTime,还会给你 Current State / Reason / Time 以及 INACTIVE / SLEEP / DIM 各子态的时间戳,排查息屏相关 bug 时超有用。


六、持久化方案:三种姿势按场景选

改完了想一劳永逸?看你的场景:

三种持久化方案对比

方案 A:timeout -o 拉满(临时,重启失效)

hdc shell power-shell timeout -o 2147483647
# 2147483647 ms ≈ 24.8 天,是 int32 上限,官方文档就这么用的

优点:一行搞定,普通 shell 就行。
缺点:重启即失效。
适合:99% 的调试场景,自动化测试、抓图、录屏、临时验证。

方案 B:setmode 602(性能模式)

hdc shell power-shell setmode 602

某些厂商的 Performance 模式里 DisplayOffTime = -1 语义就是"永不息屏"。但注意:HarmonyOS 7.0 上这个技巧可能失效,取决于厂商的 XML 配置,不保险。而且会切到性能模式,可能带来额外耗电。

方案 C:改 XML 后重推(持久,重启也在)

# 需要 root / debug 模式的 remount 权限
hdc shell "mount -o remount,rw /vendor/etc"
hdc file recv /vendor/etc/power_config/power_mode_config.xml ./
# 编辑:把 <switch id=="101" value=="..." 改成 value=="-1"
hdc file send ./power_mode_config.xml /vendor/etc/power_config/
hdc shell reboot

id=101 对应 DisplayOffTime,value=-1 表示永不息屏。这是唯一"重启也在"的做法,但要求设备允许 remount —— 商用真机通常给不了,调试版开发板可以

一张表总结:

维度方案 A方案 B方案 C
重启失效✅ 会✅ 会❌ 不会
需要 root❌ 不需要❌ 不需要✅ 需要
操作难度极低极低较高
适合场景临时调试长时间调试量产/开发板

七、踩坑实录:我实际踩过的 6 个坑

🕳 坑 1:settings put system 在鸿蒙上不存在

Android 老办法 settings put system screen_off_timeout 在鸿蒙 shell 上:

$ hdc shell settings put system screen_off_timeout 86400000
/bin/sh: settings: inaccessible or not found

社区里那种"从 Android 迁移过来的"博客误导了一大片人。鸿蒙 shell 里就没有 settings 这个工具,别浪费时间去搜。

🕳 坑 2:param ls 想 list key 被拒

$ hdc shell "param ls -r"
Error: Forbid to list parameters

param 允许 get/set/wait 指定 key,但不允许 list。而且熄屏超时根本不在 param 里 —— 它属于 PowerManager 服务的运行时状态,不是系统参数。所以别指望 param get persist.xxx_screen_timeout 这种猜法。

🕳 坑 3:切了 setmode,以为 override 没了

我一开始切 setmode 600 想看看会不会顺便把 override 清掉,结果 hidumperOverrideTimeout=86400000ms 还在 —— override 是独立于 power mode 的一层覆盖,mode 变化不改 override。这是好事,但也容易让人误以为"我切了模式,超时也应该跟着变"。想验证当前生效值,直接看 OverrideTimeout 是否非空。

🕳 坑 4:power-shell 不带子命令输出为空

$ hdc shell "power-shell"
(no output)

不带子命令就啥都不干,得先 power-shell help 或者 power-shell timeout -o ...。别以为是 hdc 出问题。

🕳 坑 5:重启后就没了(而且是"双通道"丢失)

我一开始以为设了 24h 就一劳永逸,结果第二天再看 —— hidumperOverrideTimeout 那一行不见了,变回 Timeout=600000ms

排查后发现 OverrideTimeout两条丢失通道:

通道 A:整机重启 —— 内存清零,override 归 0。

通道 B:PowerManager 进程自己重启 —— 这条更隐蔽!我设备 uptime 显示 4 天没重启,但 ps 一看 powermgr 进程是前一天 00:57 起的:

$ hdc shell uptime
11:43:41 up 4 days, 10:46, ...

$ hdc shell "ps -ef | grep powermgr"
powermgr  1573  1 1 00:57:59 ?  01:27:33 powermgr

系统 4 天没重启,但 PowerManager 进程自己重启过一次(常见于系统更新、系统服务调度、OOM killer、崩溃自动恢复),这一重启就把 override 冲了。

排查命令:

# 对比系统 uptime 和 powermgr 进程启动时间
hdc shell "uptime; ps -o lstart= -p \$(pidof powermgr) 2>/dev/null"

结论:OverrideTimeout内存级状态,任何导致 PowerManagerService 进程重启的事件都会清掉它 —— 包括但不仅限于:整机重启、PowerManager 崩溃自恢复、系统更新后服务重启、OOM 被杀。

排查公式(判断 override 是丢了还是没生效):

hdc shell "hidumper -s 3301 -a -a" | grep -E "ScreenOffTime|Current State"
  • 如果看到 OverrideTimeout= 后面没值 → 丢了,重新 timeout -o 86400000;
  • 如果 OverrideTimeout=86400000Timeout 是个很小的值(比如 15000) → 系统默认被改过,但 override 还在;
  • mode 600 下 override 是否生效? 很多人踩这个坑:setmode 602(性能模式)在商用真机上设不进去,就以为只有性能模式才能 override。实测证明 mode 600(默认)下 override 完全生效,以下是完整对照实验(同一台真机,不做任何模式切换):
场景TimeoutOverrideTimeout25 秒后 Current State
无 override600000msAWAKE(10 分钟未到)
mode 600 + override 86400000600000ms86400000msAWAKE
mode 601 + override 86400000600000ms86400000msAWAKE
mode 603 + override 86400000600000ms86400000msAWAKE

关键结论:override 是否生效与 setmode 无关,只要 OverrideTimeout 那行还写着非零值,熄屏时间就会被它覆盖。之前觉得"不生效",多半是中间某个操作(切 mode、执行 timeout -r、powermgr 重启)把 override 清掉了,系统退回到 600000ms 的默认值 —— 10 分钟后才会熄,不是 15 秒。

要"永久的"就得改 power_mode_config.xml(方案 C),或者写个 boot script(有 root 才行)。如果不想走 XML,可以在 CI/自动化脚本里加一段周期守护,每隔 N 小时重新设一次:

# keep-screen-on-cron.sh —— 每 30 分钟保活一次 override
while true; do
    cur=$(hdc shell "hidumper -s 3301 -a -a" | grep -o 'OverrideTimeout=[0-9]*ms' || echo "")
    if [ "$cur" != "OverrideTimeout=86400000ms" ]; then
        echo "[$(date)] override lost, reapplying..."
        hdc shell "power-shell timeout -o 86400000"
    fi
    sleep 1800
done

🕳 坑 6:混淆了"熄屏"和"锁屏"

power-shell timeout 改的是熄屏时间,不是锁屏时间。灭屏后是否立刻进入锁屏,取决于系统"锁屏安全"设置——华为鸿蒙默认灭屏即锁屏。如果你的目标是"完全保持屏幕常亮不熄屏",直接把值拉到 2147483647 或者用 setmode 602


八、常见问题速查

Q1:单位是秒还是毫秒?
毫秒。10 分钟 = 600000,24 小时 = 86400000,永远 = 2147483647。

Q2:改完多久生效?
立即生效,无需重启。下一次到 timeout 触发点就会按新值走。

Q3:重启后还在吗?
不在。要持久化就得改 power_mode_config.xml(方案 C)。

Q4:改的是"锁屏"还是"熄屏"?
熄屏。锁屏行为由系统设置里的"锁屏安全"决定,power-shell 管不到。

Q5:模拟器能用吗?
可以,只要模拟器支持 hdc 连接。

Q6:改了之后 UI 里"屏幕休眠时间"选项会变吗?
不会。UI 里显示的是系统默认,OverrideTimeout 是运行时内存覆盖,不写回 UI 存储。这是调试用工具,不是用户设置入口。

Q7:多屏设备呢?
PowerManagerService 里 ScreenOffTime 是全局一份,不区分物理屏。

Q8:power-shell timeout 需要 root 吗?
不需要。普通 hdc shell(shell uid=2000)就能执行。

Q9:跑自动化测试前批量开,怎么恢复?
要么脚本末尾加 timeout -r,要么重启设备。测试脚本模板见下一节。


九、自动化脚本模板:一键开跑前先"永不熄屏"

做一个能复用的脚本,自动化测试前调一次:

#!/usr/bin/env bash
# keep-screen-on.sh
set -e

SN=${1:-$(hdc list targets | head -1)}
if [ -z "$SN" ]; then
    echo "No device found. Connect a HarmonyOS device and retry." >&2
    exit 1
fi

TARGET=${2:-86400000}   # 默认 24h

echo "[*] Target: $SN"
echo "[*] Setting screen-off timeout to ${TARGET} ms"
hdc -t "$SN" shell "power-shell timeout -o $TARGET"

echo "[*] Verify:"
hdc -t "$SN" shell "hidumper -s 3301 -a -a" \
    | grep -i ScreenOffTime || true

用法:

chmod +x keep-screen-on.sh
./keep-screen-on.sh                       # 24h,自动选设备
./keep-screen-on.sh <设备号>              # 指定设备
./keep-screen-on.sh "" 2147483647         # 永不息屏

跑完别忘了恢复:

hdc shell "power-shell timeout -r"

十、写在最后

在鸿蒙真机上改熄屏超时,不用猜 param、不用 root、不用改 XML,两行命令就够了:

hdc shell power-shell timeout -o 86400000   # 设 24h
hdc shell power-shell timeout -r             # 恢复默认

底层机制是 PowerManagerService 里有个内存级的 overrideTimeout 覆盖字段,通过 IPC 由 power-shell 下发,不落盘。要持久化就得走 power_mode_config.xml 方案。

  • 调试自动化场景:方案 A 足够;
  • 需要"重启也在"又没 root:只能用 C;
  • B 属于过渡方案,不同厂商表现不一。

希望这篇能省你一两天的坑。有问题欢迎评论区交流 👇


参考资料

  • OpenHarmony 官方文档:power-shell(tools 章节)
    • https://gitcode.com/openharmony/docs/blob/master/en/application-dev/tools/power-shell.md
  • OpenHarmony 源码:base/powermgr/power_manager/
    • services/native/include/power_state_machine.h(DEFAULT_DISPLAY_OFF_TIME)
    • services/native/profile/power_mode_config.xml(各 mode 默认值)
  • hidumper 用法:hidumper -s <service_id> -a -a
  • PowerManagerService service id:3301
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐