如何让Android设备实现息屏显示

2023-10-23 14:40

本文主要是介绍如何让Android设备实现息屏显示,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

什么是息屏显示?

息屏显示就是手机在息屏状态下,屏幕上会显示当前时间、日期信息,无需点亮手机屏幕即可查看。息屏显示的原理主要是利用了OLED屏幕像素点自发光的特性,仅显示时间的像素点发光,功耗相比LCD屏幕要低很多。

Android原生的主动显示

玩过Android源码的同学应该知道,在Settings里有一个开关项:
设置 - 显示 - 主动显示

这就是设置 - 显示下的主动显示选项,勾选了这个选项后,当设备在息屏时接到一条新通知会显示这样的效果:

是不是发现与息屏显示的效果一模一样,但触发条件却不一样,需要息屏后有通知才会显示出来,并且过一段时间又会自动消失回归黑屏,那么怎样才能做到像三星那样的息屏后就能一直都显示呢?

源码分析

既然知道主动显示开关是放在设置里面的,那不妨先从Settings的源码看起,首先找到主动显示对应的Preference

<Preferenceandroid:key="ambient_display"android:title="@string/ambient_display_screen_title"android:fragment="com.android.settings.display.AmbientDisplaySettings" />

然后发现在AmbientDisplaySettings里注册了一些controller

    private static List<AbstractPreferenceController> buildPreferenceControllers(Context context,Lifecycle lifecycle, AmbientDisplayConfiguration config,MetricsFeatureProvider metricsFeatureProvider,AmbientDisplayAlwaysOnPreferenceController.OnPreferenceChangedCallback aodCallback) {final List<AbstractPreferenceController> controllers = new ArrayList<>();controllers.add(new AmbientDisplayNotificationsPreferenceController(context, config,metricsFeatureProvider));controllers.add(new AmbientDisplayAlwaysOnPreferenceController(context, config,aodCallback));controllers.add(new DoubleTapScreenPreferenceController(context, lifecycle, config,MY_USER_ID, KEY_AMBIENT_DISPLAY_DOUBLE_TAP));controllers.add(new PickupGesturePreferenceController(context, lifecycle, config,MY_USER_ID, KEY_AMBIENT_DISPLAY_PICK_UP));return controllers;}

先关注里面的两个:AmbientDisplayNotificationsPreferenceController和AmbientDisplayAlwaysOnPreferenceController,看名字大概能知道,第一个与通知有关,应该是上文提到的息屏后来通知才显示;而第二个就是我们要找的“始终开启”。

AmbientDisplayAlwaysOnPreferenceController

public class AmbientDisplayAlwaysOnPreferenceController extendsAbstractPreferenceController implements PreferenceControllerMixin,Preference.OnPreferenceChangeListener {private final int ON = 1;private final int OFF = 0;...// 每次进入该PreferenceScreen都会调用一次刷新开关状态@Overridepublic void updateState(Preference preference) {((SwitchPreference) preference).setChecked(isAlwaysOnEnabled(mConfig));}// 通过AmbientDisplayConfiguration获得当前enable状态public static boolean isAlwaysOnEnabled(AmbientDisplayConfiguration config) {return config.alwaysOnEnabled(MY_USER);}// 每次点击后写入数据@Overridepublic boolean onPreferenceChange(Preference preference, Object newValue) {int enabled = (boolean) newValue ? ON : OFF;Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.DOZE_ALWAYS_ON, enabled);if (mCallback != null) {mCallback.onPreferenceChanged();}return true;}// 该Preference是否可用@Overridepublic boolean isAvailable() {return isAvailable(mConfig);}// 通过AmbientDisplayConfiguration 获得available状态public static boolean isAvailable(AmbientDisplayConfiguration config) {return config.alwaysOnAvailableForUser(MY_USER);}...
}

分析AmbientDisplayAlwaysOnPreferenceController的源码发现,AlwaysOn的enable和available状态都需要通过AmbientDisplayConfiguration 这个类来获得,并且这个类位于framework中。

简单介绍下AmbientDisplayConfiguration 中与alwaysOn有关的几个函数:

    public boolean alwaysOnEnabled(int user) {return boolSettingDefaultOn(Settings.Secure.DOZE_ALWAYS_ON, user) && alwaysOnAvailable()&& !accessibilityInversionEnabled(user);}public boolean alwaysOnAvailable() {return (alwaysOnDisplayDebuggingEnabled() || alwaysOnDisplayAvailable())&& ambientDisplayAvailable();}private boolean alwaysOnDisplayAvailable() {return mContext.getResources().getBoolean(R.bool.config_dozeAlwaysOnDisplayAvailable);}public boolean accessibilityInversionEnabled(int user) {return boolSettingDefaultOff(Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, user);}private boolean ambientDisplayAvailable() {return !TextUtils.isEmpty(ambientDisplayComponent());}public String ambientDisplayComponent() {return mContext.getResources().getString(R.string.config_dozeComponent);}private boolean boolSettingDefaultOn(String name, int user) {return boolSetting(name, user, 1);}private boolean boolSetting(String name, int user, int def) {return Settings.Secure.getIntForUser(mContext.getContentResolver(), name, def, user) != 0;}

alwaysOnAvailable为true需要同时满足两个条件:

处于debug模式,或者config_dozeAlwaysOnDisplayAvailable为true,这个值写在frameworks/base/core/res/res/values/config.xml里,默认是false;
config_dozeComponent取值不为空,这个值同样写在上面讲到的config.xml里,默认是空着的。

alwaysOnEnabled为true需要同时满足三个条件:

DOZE_ALWAYS_ON值写入了1,即Settings里开启了开关;
alwaysOnAvailable为true;
ACCESSIBILITY_DISPLAY_INVERSION_ENABLED值为0,即没有开启颜色反转。

原来源码里面默认把AlwaysOn功能给关闭了,如果想启用这个功能,需要修改config.xml里的两个值或者强制alwaysOnAvailable返回true,修改后设置里的主动显示一栏就会多出一项“始终开启”可以勾选,这样一来我们的设备在息屏之后就能自动开启主动显示功能了。

这篇关于如何让Android设备实现息屏显示的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/268500

相关文章

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

Android kotlin中 Channel 和 Flow 的区别和选择使用场景分析

《Androidkotlin中Channel和Flow的区别和选择使用场景分析》Kotlin协程中,Flow是冷数据流,按需触发,适合响应式数据处理;Channel是热数据流,持续发送,支持... 目录一、基本概念界定FlowChannel二、核心特性对比数据生产触发条件生产与消费的关系背压处理机制生命周期

Android ClassLoader加载机制详解

《AndroidClassLoader加载机制详解》Android的ClassLoader负责加载.dex文件,基于双亲委派模型,支持热修复和插件化,需注意类冲突、内存泄漏和兼容性问题,本文给大家介... 目录一、ClassLoader概述1.1 类加载的基本概念1.2 android与Java Class

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

Python使用pip工具实现包自动更新的多种方法

《Python使用pip工具实现包自动更新的多种方法》本文深入探讨了使用Python的pip工具实现包自动更新的各种方法和技术,我们将从基础概念开始,逐步介绍手动更新方法、自动化脚本编写、结合CI/C... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核