安卓屏保调试2

上一年为了研究屏保过程投屏,写了一篇文章:安卓屏保调试 - Wesley's Blog

今年为了做屏保广告又跟屏保打上交道了。

起初发现一台机器 dream 时间到了之后怎么也出不了屏保,直接把 dumpsys power 结果喂给 gpt,一下子就解决了,记录一下。

dumpsys power | grep -i mStayOnWhilePluggedInSetting 这个结果显示 3,改成 0 就可以了。

stay_on_while_plugged_in

java 复制代码
/**
         * Whether we keep the device on while the device is plugged in.
         * Supported values are:
         * <ul>
         * <li>{@code 0} to never stay on while plugged in</li>
         * <li>{@link BatteryManager#BATTERY_PLUGGED_AC} to stay on for AC charger</li>
         * <li>{@link BatteryManager#BATTERY_PLUGGED_USB} to stay on for USB charger</li>
         * <li>{@link BatteryManager#BATTERY_PLUGGED_WIRELESS} to stay on for wireless charger</li>
         * <li>{@link BatteryManager#BATTERY_PLUGGED_DOCK} to stay on for dock charger</li>
         * </ul>
         * These values can be OR-ed together.
         */
@Readable
public static final String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";

基础单值(对应特定的供电方式)

  • 0:关闭状态(默认值)。无论连接什么电源,设备都会遵循常规的休眠和屏保倒计时。
  • 1 :交流电 (AC)。只有在使用电源适配器(插在墙上)充电时,屏幕才保持常亮。对应底层常量 BatteryManager.BATTERY_PLUGGED_AC。
  • 2 :USB。只有在连接到电脑或其他 USB 端口充电时,屏幕才保持常亮。对应底层常量 BatteryManager.BATTERY_PLUGGED_USB。
  • 4 :无线充电 (Wireless)。只有在使用无线充电器时,屏幕才保持常亮。对应底层常量 BatteryManager.BATTERY_PLUGGED_WIRELESS。
  • 8 :底座 (Dock)。插在专用底座上时保持常亮。对应底层常量 BatteryManager.BATTERY_PLUGGED_DOCK。

由于采用了位掩码设计,可以将上述基础值相加(按位或操作 |),以同时支持多种情况:

  • 3 (1 + 2):只要插着交流电或 USB,就不休眠。(最常见的组合值)
  • 7 (1 + 2 + 4):只要连着交流电、USB 或 无线充电中的任意一种,就不休眠。(通常被开发者用来表示"只要通电就不休眠")

对于 Android TV 来说,由于它没有电池,通常被系统视为始终处于"AC 供电"状态。所以只要这个值包含了 1(比如设成了 1, 3 或 7),TV 就永远不会进入 Dream 屏保了。 我碰到的就是这种情况。

另外一些情况

如果上面的值设置为 0 了,还是不行的话,可以继续排查:

dumpsys power | grep -E "mWakefulness|Wake Locks|SCREEN_BRIGHT|FULL_WAKE|WindowManager"

看Wake Locks size是不是 0:

shell 复制代码
YYT:/ #
YYT:/ # dumpsys power | grep -E "mWakefulness|Wake Locks|SCREEN_BRIGHT|FULL_WAKE|WindowManager"
  mWakefulness=Awake
  mWakefulnessChanging=false
  mScreenBrightnessOverrideFromWindowManager=NaN
  mUserActivityTimeoutOverrideFromWindowManager=-1
  mUserInactiveOverrideFromWindowManager=false
Wake Locks: size=0
  03-25 14:38:33.335 - 1000 - ACQ WindowManager/displayId:0 (screen-bright,on-after-release)
  03-25 14:38:35.528 - 1000 - REL WindowManager/displayId:0

UndimDetectorWakeLock

在Android T版本中,系统新增了SCREEN_BRIGHT_WAKE_LOCK(UndimDetectorWakeLock)机制。当设备处于低亮度(dim)状态时,用户两次打断屏幕熄灭操作就会触发系统保持屏幕常亮10分钟。

比如:

  • mKeepScreenOnEnabled = true
  • mKeepScreenOnForMillis = 10min
  • mUndimsRequired = 2
  • mMaxDurationBetweenUndimsMillis = 5min

那就等于:

  1. 屏幕先变暗一次。
  2. 把它点亮,记第 1 次 undim。
  3. 如果 5 分钟内 又发生了第 2 次 undim,系统就判断"用户明显还在用",于是额外保持亮屏 10 分钟。
  4. 如果第 2 次发生在 5 分钟之后,那前面的计数作废,重新从 1 次开始算。

这时候 screen_off_timeout 就会变得不准确了,以 UndimDetectorWakeLock 计时为准。

调试命令

查看屏保是否启用:

settings get secure screensaver_enabled

查看进入的屏保的时间:

settings get system screen_off_timeout

查看进入休眠的时间:

settings get secure sleep_timeout

sleep_timeout 通常应比 screen_off_timeout 更长,不然设备会直接休眠而不是进屏保。

dumpsys dreams

shell 复制代码
YYT:/ # dumpsys dreams
DREAM MANAGER (dumpsys dreams)

mCurrentDream=null
mForceAmbientDisplayEnabled=false
mDreamsOnlyEnabledForDockUser=false
mDreamsEnabledSetting=true
mDreamsActivatedOnDockByDefault=true
mDreamsActivatedOnChargeByDefault=true
mIsDocked=false
mIsCharging=true
mWhenToDream=3
mKeepDreamingWhenUnpluggingDefault=false
getDozeComponent()=null

Dreamland:
  mCurrentDream: null
  mSentStartBroadcast=false
shell 复制代码
YYT:/ # settings list secure | grep screensaver
screensaver_activate_on_dock=1
screensaver_activate_on_sleep=1
screensaver_components=com.media/com.media.ScreensaverService
screensaver_default_component=com.google.android.apps.tv.dreamx/.service.Backdrop
screensaver_enabled=1
YYT:/ #
YYT:/ #
YYT:/ # settings list system | grep screen
dim_screen=1
lockscreen_sounds_enabled=1
screen_brightness=102
screen_brightness_mode=0
screen_off_timeout=30000

参考

Android14 用户两次打断息屏操作后,屏幕将会在10分钟内无法熄灭并持续点亮(关闭Android13新增的dim功能) - 掘金

使屏幕保持开启状态 | Background work | Android Developers

相关推荐
Easyhood16 分钟前
Android 开发入门实践(十四):Compose 副作用入门与四个常用 API
android·开发语言·kotlin·android jetpack·compose
FlightYe1 小时前
音视频修炼之容器与协议(四):RTSP详解
android·linux·ffmpeg·音视频·dash
疯华整猫3 小时前
删掉 LeakCanary 那天,我用 Trae 自己撸了一套:最难的不是分析堆,是决定什么时候 dump
android·人工智能·性能优化
mmsx11 小时前
耳切法切带洞多边形:论文能跑通,真实数据为什么崩
android·kotlin
洞见前行11 小时前
你的 Activity 关了,为什么还活着?Android 内存泄漏从发现、定位到线上治理
android·性能优化·leakcanary
Kapaseker12 小时前
Kotlin 又要加语法糖了:这次轮到 if-else
android·kotlin
恋猫de小郭14 小时前
Flutter 3.50 & Dart 3.14 发布,快来看看有什么更新吧
android·前端·flutter
Starry-sky(jing)1 天前
Vidda ADB 开启:R Pro 65 找不到开发者选项的处理与连接验收
android·adb·远程控制·电视·vidda