Android 系统设置中的休眠和屏保

简介

由于客户在Android 系统设置中发现Timeout设置项没有效果,因此我对此研究了一下。Timeout是定时屏幕亮度降低,而Dream则是进入屏幕保护。如果是机顶盒等设备的开发者发现这个设置项没用,别见外,因为这里的亮度调整对TV是没用的,因此 ‘Screen Timeout’ 和‘brightness’ 是没用的。

Timeout休眠

界面代码

效果:设置固定的时间之后根据根据用户活动的时间、设备的电源政策(如 mDisplayPowerRequest.policy),以及当前时间来决定设备是保持亮屏、降低亮度还是进入其他省电状态。

代码位置:

packages/apps/Settings/res/xml/display_settings.xml

<com.android.settings.display.TimeoutListPreferenceandroid:key="screen_timeout"android:title="@string/screen_timeout"android:summary="@string/summary_placeholder"android:entries="@array/screen_timeout_entries"android:entryValues="@array/screen_timeout_values"//当点击的时候弹出的listView显示的内容settings:keywords="@string/keywords_screen_timeout" />//listView显示的内容对应的时间

这是这个设置项的资源配置文件,它是一个ListPreference 具有七个设置项,具体设置项的代码如下:
packages/apps/Settings/res/values/arrays.xml

//这里是展示出来的字符
<!-- Display settings.  The delay in inactivity before the screen is turned off. These are shown in a list dialog. -->
<string-array name="screen_timeout_entries"><item>15 seconds</item><item>30 seconds</item><item>1 minute</item><item>2 minutes</item><item>5 minutes</item><item>10 minutes</item><item>30 minutes</item>
</string-array>//这里是具体的数值
<!-- Do not translate. -->
<string-array name="screen_timeout_values" translatable="false"><!-- Do not translate. --><item>15000</item><!-- Do not translate. --><item>30000</item><!-- Do not translate. --><item>60000</item><!-- Do not translate. --><item>120000</item><!-- Do not translate. --><item>300000</item><!-- Do not translate. --><item>600000</item><!-- Do not translate. --><item>1800000</item>
</string-array>

它的国际化适配是在每一个语言文件夹下的arrays.xml都定义了一个screen_timeout_entries。因此如果要增加一个新的设置项比如“Never”那么就需要在所有可能使用的语言下都加上,否则切换语言之后可能会空指针异常。

属性值

这里选择之后,属性值的改变是Settings.System.SCREEN_OFF_TIMEOUT
adb shell settings get System screen_off_timeout
在你改变screen_timeout_values值的时候,记得如果想要永不息屏,就设置为2147483647 。这是可以设置的最大值。

延时降低亮度的具体逻辑

延时降低亮度的具体的逻辑基本都在frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java

电源省电策略:/** Get wake lock summary flags that correspond to the given wake lock. */private int getWakeLockSummaryFlags(WakeLock wakeLock) {switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {case PowerManager.PARTIAL_WAKE_LOCK:if (!wakeLock.mDisabled) {// We only respect this if the wake lock is not disabled.return WAKE_LOCK_CPU;}break;case PowerManager.FULL_WAKE_LOCK:return WAKE_LOCK_SCREEN_BRIGHT | WAKE_LOCK_BUTTON_BRIGHT;case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:return WAKE_LOCK_SCREEN_BRIGHT;case PowerManager.SCREEN_DIM_WAKE_LOCK:return WAKE_LOCK_SCREEN_DIM;case PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK:return WAKE_LOCK_PROXIMITY_SCREEN_OFF;case PowerManager.DOZE_WAKE_LOCK:return WAKE_LOCK_DOZE;case PowerManager.DRAW_WAKE_LOCK:return WAKE_LOCK_DRAW;}return 0;}private void updatePowerStateLocked() {
这里省略一段代码.............updateWakeLockSummaryLocked(dirtyPhase1);updateUserActivitySummaryLocked(now, dirtyPhase1);updateAttentiveStateLocked(now, dirtyPhase1);if (!updateWakefulnessLocked(dirtyPhase1)) {break;}}

updateUserActivitySummaryLocked 来更新用户活动状态,这个方法特别重要。这是一个更新用户活动状态的函数。它根据当前时间 (now)、用户活动的最后时间 (mLastUserActivityTime) 以及各种超时设置(如屏幕关闭超时、睡眠超时等),来决定接下来设备的行为(如屏幕变暗、关闭等)。

    private void updateUserActivitySummaryLocked(long now, int dirty) {// Update the status of the user activity timeout timer.if ((dirty & (DIRTY_WAKE_LOCKS | DIRTY_USER_ACTIVITY| DIRTY_WAKEFULNESS | DIRTY_SETTINGS)) != 0) {mHandler.removeMessages(MSG_USER_ACTIVITY_TIMEOUT);long nextTimeout = 0;if (getWakefulnessLocked() == WAKEFULNESS_AWAKE|| getWakefulnessLocked() == WAKEFULNESS_DREAMING|| getWakefulnessLocked() == WAKEFULNESS_DOZING) {final long attentiveTimeout = getAttentiveTimeoutLocked();//超时时间用于检测用户是否仍然关注设备final long sleepTimeout = getSleepTimeoutLocked(attentiveTimeout);//时时间表示设备在用户不活动后进入休眠状态的时间final long screenOffTimeout = getScreenOffTimeoutLocked(sleepTimeout,attentiveTimeout);//表示设备在用户不活动后屏幕关闭的时间。它综合考虑了attentiveTimeout和sleepTimeout,final long screenDimDuration = getScreenDimDurationLocked(screenOffTimeout);final boolean userInactiveOverride = mUserInactiveOverrideFromWindowManager;final long nextProfileTimeout = getNextProfileTimeoutLocked(now);
.....................................if (mLastUserActivityTime >= mLastWakeTime) {nextTimeout = mLastUserActivityTime+ screenOffTimeout - screenDimDuration;if (now < nextTimeout) {mUserActivitySummary = USER_ACTIVITY_SCREEN_BRIGHT;//这里将屏幕设成亮的} else {nextTimeout = mLastUserActivityTime + screenOffTimeout;if (now < nextTimeout) {mUserActivitySummary = USER_ACTIVITY_SCREEN_DIM;//这里将屏幕设成暗的}}}}

这里面还有很多种其他条件我就不一一介绍了。如果想要在时间到的时候执行其他操作,就在这里增加逻辑。

变量和方法解释

  • Attentive Timeout (attentiveTimeout)
    • 变量:mAttentiveTimeoutSetting
    • 方法:getAttentiveTimeoutLocked()
    • 解释:这个超时时间用于检测用户是否仍然关注设备。即使用户没有直接与设备交互,系统也可能通过一些方式(如面部识别)检测到用户的注意力。这种超时策略可以延长屏幕亮起时间,避免在用户依然关注设备时屏幕过早熄灭。
    • 返回值:返回一个非负整数,表示配置的时间(单位:毫秒),如果超时设置为0或负数,返回-1,表示不使用这个超时策略。
  • Sleep Timeout (sleepTimeout)
    • 变量:mSleepTimeoutSetting
    • 方法:getSleepTimeoutLocked(long attentiveTimeout)
    • 解释:这个超时时间表示设备在用户不活动后进入休眠状态的时间。它依赖于attentiveTimeout,如果attentiveTimeout有效(非负),则sleepTimeout不会超过attentiveTimeout。
    • 返回值:返回一个非负整数,表示配置的时间(单位:毫秒),如果超时设置为0或负数,返回-1,表示不使用这个超时策略。这里实际上他返回的就是我们设置中的settings get System screen_off_timeout拿到的值
  • Screen Off Timeout (screenOffTimeout)
    • 变量:mScreenOffTimeoutSetting
    • 方法:getScreenOffTimeoutLocked(long sleepTimeout, long attentiveTimeout)
    • 解释:这个超时时间表示设备在用户不活动后屏幕关闭的时间。它综合考虑了attentiveTimeout和sleepTimeout,并受一些额外设置的影响,如设备管理员强制的最大屏幕关闭时间。
    • 返回值:返回一个非负整数,表示配置的时间(单位:毫秒)。

关系分析

  1. attentiveTimeout 与 sleepTimeout
  • attentiveTimeout 是用户是否仍在关注设备的超时策略。sleepTimeout依赖于attentiveTimeout,即如果attentiveTimeout有效(非负),则sleepTimeout不会超过attentiveTimeout。这意味着只要系统检测到用户还在关注设备,设备就不会进入休眠状态。
  1. sleepTimeout 与 screenOffTimeout
  • screenOffTimeout 表示屏幕关闭的超时时间,它依赖于sleepTimeout。如果sleepTimeout有效(非负),则screenOffTimeout不会超过sleepTimeout。这意味着在用户不活动且系统决定设备应该休眠前,屏幕会先关闭。
  1. screenOffTimeout 的其他影响因素
  • screenOffTimeout 还受其他设置影响,如设备管理员设置的最大屏幕关闭时间(mMaximumScreenOffTimeoutFromDeviceAdmin)和窗口管理器覆盖的用户活动超时(mUserActivityTimeoutOverrideFromWindowManager)。这些设置会进一步约束screenOffTimeout的值,确保设备在合规的时间范围内关闭屏幕。

调试信息

如果想要打印这里的调试信息,系统中给了现成的
frameworks/base/services/core/java/com/android/server/power/PowerManagerService.javaif (DEBUG_SPEW) {Slog.d(TAG, "updateUserActivitySummaryLocked: mWakefulness="+ PowerManagerInternal.wakefulnessToString(getWakefulnessLocked())+ ", mUserActivitySummary=0x" + Integer.toHexString(mUserActivitySummary)+ ", nextTimeout=" + TimeUtils.formatUptime(nextTimeout));}

效果如下

updateUserActivitySummaryLocked: mWakefulness=Awake, mUserActivitySummary=0x1, nextTimeout=920990 (in 892906 ms)

永不休眠

  1. 在 PowerManagerService 和 PhoneWindowManager 处理
  2. 直接配置 Settings.System.SCREEN_OFF_TIMEOUT 为Integer.MAX_VALUE( 2147483647 = 24.855 天 一般没有这么长时间亮屏待机 )

screensaver屏幕保护

界面代码
packages/apps/Settings/res/xml/display_settings.xml

<Preferenceandroid:key="screensaver"android:title="@string/screensaver_settings_title"android:fragment="com.android.settings.dream.DreamSettings" /> 

我们可以看到其中定义了android:fragment,也就是说当点击该item的时候会跳转到DreamSettings这个fragment。

packages/apps/Settings/src/com/android/settings/display/ScreenSaverPreferenceController.java

public boolean isAvailable() {return mContext.getResources().getBoolean(com.android.internal.R.bool.config_dreamsSupported);
}public void updateState(Preference preference) {preference.setSummary(DreamSettings.getSummaryTextWithDreamName(mContext));//获取当前的屏保的名称
}

此处读取com.android.internal.R.bool.config_dreamsSupported的值,true表示支持屏保,false表示不支持
更深入的代码没有去研究了,等待更新。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/862516.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二叉树的方法

目录 一、二叉树的定义 ​编辑 二、二叉树的创建 三、二叉树的遍历 1、前序遍历 2、中序遍历 3、后序遍历 4、层序遍历 四、二叉树遍历方法的使用 五、二叉树的操作 1、节点的个数 2、叶子节点的个数 3、第k层节点的个数 4、二叉树的高度 5、检查值为value的元素…

java生成excel,uniapp微信小程序接收excel并打开

java引包&#xff0c;引的是apache.poi <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency> 写一个测试类&#xff0c;把excel输出到指定路径 public s…

一条SQL查询语句的执行流程

MySQL 中一条 SQL 查询语句的执行流程可以分为以下几个主要步骤&#xff1a; 客户端请求&#xff1a; 客户端通过 MySQL 客户端或应用程序向 MySQL 服务器发送 SQL 查询请求。 连接管理&#xff1a; MySQL 服务器接收到请求后&#xff0c;会首先检查客户端的身份验证信息&…

c++笔记容器详细介绍

C标准库提供了多种容器来存储和管理数据。这些容器属于<vector>, <list>, <deque>, <map>, <set>, <unordered_map>, <unordered_set>等头文件中。这些容器各有优缺点&#xff0c;适用于不同的场景。下面详细介绍几种主要的容器及其…

快20倍还便宜 NVIDIA GPU的“掘墓人”出现了?

芯片初创公司Etched近日宣布推出了一款针对 Transformer架构专用的AISC芯片 “Sohu”&#xff0c;并声称其在AI大语言模型&#xff08;LLM&#xff09;推理性能方面击败了NVIDIA最新的B200 GPU&#xff0c;AI性能达到了H100的20倍。这也意味着Sohu芯片将可以大幅降低现有AI数据…

【面试系列】C++ 高频面试题

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…

精密机器中的交叉导轨负荷与容许负荷的差异!

交叉导轨的设计和制造过程中&#xff0c;负荷及容许负荷是至关重要的参数&#xff0c;只有准确计算出交叉导轨的载荷&#xff0c;才能保证交叉导轨的稳定性和使用寿命。 负荷和容许载荷是两个不同的参数&#xff0c;那这两者的有什么差异呢&#xff1f; 交叉导轨的负荷是指其承…

微信群被恶意举报封了加新群的看这里

由于近期太忙&#xff0c;有时候手机被儿子拿玩看动漫了&#xff0c;被误删或是误踢的朋友说声抱歉。 感谢大家的理解和支持。

JVM专题九:JVM分代知识点梳理

今天开始&#xff0c;咱们开始剖析JVM内存划分的原理细节&#xff0c;以及我们创建的那些对象在JVM中到底是如何分配&#xff0c;如何流动的&#xff0c;首先解决第一个问题&#xff1a;JVM内存的一个分代模型:年轻代、老年代、永久通过之前的专题我们知道&#xff0c;那就是我…

HarmonyOS Next开发学习手册——通过startAbilityByType拉起垂类应用

使用场景 开发者可通过特定的业务类型如导航、金融等&#xff0c;调用startAbilityByType接口拉起对应的垂域面板&#xff0c;该面板将展示目标方接入的垂域应用&#xff0c;由用户选择打开指定应用以实现相应的垂类意图。垂域面板为调用方提供统一的安全、可信的目标方应用&a…

REST API 中的 HTTP 请求参数

当我们在谈论现代 Web 开发时&#xff0c;REST API (Representational State Transfer Application Programming Interface) 扮演着至关重要的角色。它允许不同的系统以一种简洁且高效的方式进行通信。HTTP 请求参数是控制此通信流程中数据如何被发送和接收的重要组成部分。 H…

vue2使用wangEditor5搭建模拟文档的编辑器快速集成

如图 1、下载依赖 2、elm引入&#xff08;可省略&#xff09; main.js 或者 按需引入 3、cv <template><div style"background: #f1f3f4"><div style"width: 100%; height: 42px"><!-- 工具栏 --><Toolbarid"tool-conta…

Linux crontab中* * * * * /usr/local/run.sh这句话5个*号分别代表什么?

在 Linux crontab 中&#xff0c;* * * * * /usr/local/run.sh 这句话里的 5 个*号分别代表的含义如下&#xff1a; 第一个&#xff1a;表示分钟&#xff0c;取值范围是 0 到 59。这里的表示每分钟。 第二个&#xff1a;表示小时&#xff0c;取值范围是 0 到 23。表示每小时。…

AI产品经理需要懂的算法和模型

本篇希望以精准推荐模型为案例通过全面的撰写将AI产品经理需要懂的算法和模型进行了系统的入门讲解。 一个产品经理经常疑惑的概念&#xff1a; 算法和模型的关系&#xff0c;产品经理懂得解决问题时将问题抽象为模型&#xff0c;对模型求解用算法&#xff0c;没有谁大谁小&a…

博睿数据受邀出席GOPS全球运维大会北京站,分享《一体化可观测数据模型和AIOps的融合实践》

2024年6月28日&#xff0c;第二十三届 GOPS 全球运维大会暨 XOps 技术创新峰会在北京顺利召开。大会为期2天&#xff0c;侧重 BizDevOps、XOps、DevOps、持续测试、SRE、可观测性、云原生等热门技术领域。并特别设置大模型运维、银行/证券数字化转型、平台工程、DevOps/AIOps 最…

Linux系统中常用的基本命令

1. 文件与目录管理 ls: 列出目录内容。cd: 切换当前工作目录。pwd: 显示当前工作目录的路径。mkdir: 创建一个新目录。rmdir: 删除空目录。cp: 复制文件或目录。mv: 移动或重命名文件或目录。rm: 删除文件或目录。touch: 创建一个空文件或更新文件时间戳。 2. 文本内容查看 …

bcprov-jdk15on和bcpkix-jdk15on有什么区别

bcprov-jdk15on 和 bcpkix-jdk15on 都是 Bouncy Castle 密码库的不同组件&#xff0c;针对不同的用途和功能。它们之间的主要区别在于提供的功能和目的&#xff1a; bcprov-jdk15on&#xff1a; 这是 Bouncy Castle 的主要提供者&#xff08;Provider&#xff09;模块&#xff…

上海六十中学多功能气膜馆项目:轻空间全速推进

项目进展捷报频传 上海六十中学多功能气膜馆项目土建工作已基本完工&#xff0c;今天轻空间团队正式进场&#xff0c;展开气膜部分的施工。我们将为上海六十中学打造一个现代化、环保、高效的多功能气膜馆&#xff0c;提供优质的运动和活动场所。 现场施工一片繁忙 在施工现场&…

【uniapp】HBuilderx中uniapp项目运行到微信小程序报错Error: Fail to open IDE

HBuilderx中uniapp项目运行到微信小程序报错Error: Fail to open IDE 问题描述 uniapp开发微信小程序&#xff0c;在HBuilderx中运行到微信开发者工具时报错Error: Fail to open IDE 解决方案 1. 查看微信开发者工具端服务端口是否开放 打开微信开发者工具选择&#xff1…

onnx模型转rknn到部署

简介 最近开始用3568的板子&#xff0c;之前是在用3399&#xff0c;cpu的话3399比3568强&#xff0c;但是3568有1T的npu算力&#xff0c;所以模型移植过来用npu使用&#xff0c;之前用ncnn感觉太慢了&#xff0c;rk的npu使用没有开源&#xff0c;所以没法兼容&#xff0c;只能跑…