安卓16屏保中的启用时机,选项不正确

修改的文件

问题描述

复制代码
设置 - 显示 - 启用屏保 - 启用时机中显示的是"一律不",实际点开查看没有该选项,并且实际选中的是"充电时",虽然显示"充电时"被选中,但充电时仍然没有屏保,只有你再点击一次"充电时"选项才会有充电屏保。

同时点开"启用时机"这个选项后,发现只有"充电时",没有"一律不"。

想法

确保图片中这个地方只显示"充电时",且无需进入二级菜单再点击一次"充电时"选项(同时二级菜单只有"充电时"这一个选项)。即目标是,只要打开"启用屏保"按钮。就自动在充电时开启"屏保"。

修改过程

后续代码修改均位于packages/apps/Settings模块

xml 复制代码
res/values/arrays.xml
"启用时机"二级菜单选项的增减示例

<!-- Options for screensaver "When to start" for devices that do not support screensavers
         while on battery -->
    <string-array name="when_to_start_screensaver_entries_no_battery" translatable="false">
        <item>@string/screensaver_settings_summary_sleep</item>
    </string-array>

    <!-- Values for screensaver "When to start" for devices that do not support screensavers
         while on battery -->
    <string-array name="when_to_start_screensaver_values_no_battery" translatable="false">
        <item>while_charging_only</item>
    </string-array>

首先修改 默认提示语

将图片中的"一律不"替换为"充电时"

xml 复制代码
根据"启用时机"名称定位到选项在xml中的位置,跟WhenToDreamPicker这个fragment有关,但这个fragment实际负责的是二级菜单内容,只有你点开这个二级菜单的时候才会执行,因此不修改这个fragment。
<Preference
        android:key="when_to_start"
        android:title="@string/screensaver_settings_when_to_dream"
        android:fragment="com.android.settings.dream.WhenToDreamPicker"/>

实际负责"启用时机"一级菜单显示的是WhenToDreamPreferenceController.java。updateState负责更新一级菜单的ui,调用getSummaryResId,走的是getSummaryResId的else分支,else分支又调用DreamSettings.getDreamSettingDescriptionResId

java 复制代码
实际负责"启用时机"一级菜单显示的是WhenToDreamPreferenceController.java

@Override
public void updateState(Preference preference) {
    Log.d("cmy", "ENTER updateState()");
    super.updateState(preference);

    preference.setSummary(getSummaryResId());
}


private @StringRes int getSummaryResId() {
    if (mDreamsDisabledByAmbientModeSuppression
            && AmbientDisplayAlwaysOnPreferenceController.isAodSuppressedByBedtime(mContext)) {
        Log.d("cmy", "getSummaryResId-R.string.screensaver_settings_when_to_dream_bedtime = "+R.string.screensaver_settings_when_to_dream_bedtime);
        return R.string.screensaver_settings_when_to_dream_bedtime;
    } else {
        final int resId = DreamSettings.getDreamSettingDescriptionResId(
                mBackend.getWhenToDreamSetting(), mDreamsEnabledOnBattery);
        Log.d("cmy", "getSummaryResId-resId = "+resId);
        return resId;
    }
}

java 复制代码
DreamSettings.java

static int getDreamSettingDescriptionResId(@WhenToDream int dreamSetting,
            boolean enabledOnBattery) {
        //enabledOnBattery值一直是false。
        //当显示"一律不"时dreamSetting,dreamSetting=4.
        //当显示"充电时"时dreamSetting,dreamSetting=0.
        Log.d("cmy-"+TAG, "dreamSetting = "+dreamSetting+"   --- enabledOnBattery = "+enabledOnBattery);
        
        switch (dreamSetting) {
            case DreamBackend.WHILE_CHARGING:
                return R.string.screensaver_settings_summary_sleep;
            case DreamBackend.WHILE_DOCKED:
                return enabledOnBattery ? R.string.screensaver_settings_summary_dock
                        : R.string.screensaver_settings_summary_dock_and_charging;
            case DreamBackend.WHILE_CHARGING_OR_DOCKED:
                return R.string.screensaver_settings_summary_either_long;
            case DreamBackend.WHILE_POSTURED:
                return enabledOnBattery ? R.string.screensaver_settings_summary_postured
                        : R.string.screensaver_settings_summary_postured_and_charging;
            case DreamBackend.NEVER:
                // 这里修改为,如果值是"一律不",返回"充电时"的字符串
                Log.d("cmy-"+TAG, "case DreamBackend.NEVER TO CHARGING");
                return R.string.screensaver_settings_summary_sleep;
            default:
                return R.string.screensaver_settings_summary_never;
        }
    }

选项默认值修改

因为要的效果是,当"启用屏保"按钮开启时,打开充电屏保,否则就关闭,因此默认值的设置跟"启用屏保"按钮相关,负责这个按钮的是DreamMainSwitchPreferenceController.java,点击按钮时,其中的setChecked方法都会执行。

java 复制代码
DreamMainSwitchPreferenceController.java

@Override
public boolean setChecked(boolean isChecked) {
    Log.d("cmy", "ENTER setChecked() AND isChecked = "+isChecked);
    mBackend.setEnabled(isChecked);

    // 2. 核心修复逻辑:如果开关被打开 (isChecked 为 true)
    if (isChecked) {
        // 获取当前的启动时机
        int currentSetting = mBackend.getWhenToDreamSetting();

        // 如果当前时机是 4 (WHILE_NEVER / 一律不)
        if (currentSetting == 4) { 
            Log.d("cmy-DMSPC", "Current is Never, forcing to While Charging");
            // 强制将其设置为 0 (WHILE_CHARGING_ONLY / 充电时)
            mBackend.setWhenToDream(0);
        }
    }

    return true;
}
相关推荐
消失的旧时光-19437 小时前
从 Kotlin 到 Dart:为什么 sealed 是处理「多种返回结果」的最佳方式?
android·开发语言·flutter·架构·kotlin·sealed
Jinkxs7 小时前
Gradle - 与Groovy/Kotlin DSL对比 构建脚本语言选择指南
android·开发语言·kotlin
&有梦想的咸鱼&7 小时前
Kotlin委托机制的底层实现深度解析(74)
android·开发语言·kotlin
LDORntKQH7 小时前
基于深度强化学习的混合动力汽车能量管理策略 1.利用DQN算法控制电池和发动机发电机组的功率分配 2
android
冬奇Lab7 小时前
Android 15 ServiceManager与Binder服务注册深度解析
android·源码·源码阅读
2501_916008899 小时前
深入解析iOS机审4.3原理与混淆实战方法
android·java·开发语言·ios·小程序·uni-app·iphone
独行soc10 小时前
2026年渗透测试面试题总结-20(题目+回答)
android·网络·安全·web安全·渗透测试·安全狮
常利兵11 小时前
2026年,Android开发已死?不,它正迎来黄金时代!
android
Risehuxyc11 小时前
备份三个PHP程序
android·开发语言·php
Doro再努力20 小时前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim