Android 亮度范围定制
文章目录
- 需求及场景
- 问题分析
- 适配方案
- 一、相关资源参考
- SystemUI基本内容熟悉-Brightness 模块
- 亮度控制部分相关资源
- 二、修改方案
- 修改点一
- 修改点二
- 代码跟踪
需求及场景
自己这几年开发过的几款产品遇到这样的情况,实际场景如下:
- 屏幕最大亮度太亮
- 屏幕最小亮度太暗了,最小亮度调到0%时候,屏幕黑黢黢的看不到屏幕了
- 屏幕亮度在0%到60% 调节亮度发现调节没有用
- 屏幕亮度在90%-100% 调节没有用
问题分析
屏幕亮度用硬件的专业术语就是背光、又是通过pmw 调节的,最终就是给它电压电流来调节。
所以简单理解如下:
针对问题1、2 、4我们可能通过系统调节来更正解决的。这里可能存在问题,不同产品用的不同的屏幕、同一个电池。电池和屏幕硬件没有对齐,比如:低电压限制死了,高电压限制死了,不可调节了。那么就会存在:90%以上的亮度一样的,调节复用;60%以下的亮度一样的,不可调节。
适配方案
在一定范围类取值设置,但是进度条还是一样的控制。比如:0-60% 亮度不变,那么我们把60%-100%的控制范围扩充到0%-100%,控制范围变大,控制区域保持一致。
一、相关资源参考
原创不易,尊重原创,下面提供几个亮度相关的内容,可以参考。不同Android版本对应的逻辑、代码、修改位置可能不一致,但是思想一致
SystemUI基本内容熟悉-Brightness 模块
可以参考我之前的文章,修改必须从亮度条控制的地方开始了解整个流程
Android12_SystemUI下拉框新增音量控制条
查看基础和亮度控制模块的分析
Android13_SystemUI下拉新增音量控制条
查看跟亮度模块相关的部分
亮度控制部分相关资源
android 修改最低亮度值,不要太暗
DisplayManagerService 亮度调节
PowerManagerService
Android framework配置默认屏幕亮度值源码分析
Android10 安卓修改屏幕背光默认亮度
二、修改方案
修改点一
修改位置:\frameworks\base\core\java\com\android\internal\display\BrightnessSynchronizer.java
设置最低亮度为最大亮度的65%,即:255*0.65=166
具体修改如下:
brightnessIntToFloat brightnessFloatToIntRange 方法中最小亮度设置为166
/**
* Converts between the int brightness system and the float brightness system.
*/
public static float brightnessIntToFloat(int brightnessInt) {
if (brightnessInt == PowerManager.BRIGHTNESS_OFF) {
return PowerManager.BRIGHTNESS_OFF_FLOAT;
} else if (brightnessInt == PowerManager.BRIGHTNESS_INVALID) {
return PowerManager.BRIGHTNESS_INVALID_FLOAT;
} else {
final float minFloat = PowerManager.BRIGHTNESS_MIN;
final float maxFloat = PowerManager.BRIGHTNESS_MAX;
//final float minInt = PowerManager.BRIGHTNESS_OFF + 1;
Log.d(TAG," brightnessIntToFloat: minInt:"+PowerManager.BRIGHTNESS_OFF + 1);
float minInt =166;
final float maxInt = PowerManager.BRIGHTNESS_ON;
Log.d(TAG," brightnessIntToFloat: maxInt:"+PowerManager.BRIGHTNESS_ON);
Log.d(TAG," brightnessIntToFloat: brightnessInt:"+brightnessInt);
return MathUtils.constrainedMap(minFloat, maxFloat, minInt, maxInt, brightnessInt);
}
}
/**
* Translates specified value from the float brightness system to the int brightness system,
* given the min/max of each range. Accounts for special values such as OFF and invalid values.
* Value returned as a float primitive (to preserve precision), but is a value within the
* int-system range.
*/
public static float brightnessFloatToIntRange(float brightnessFloat) {
if (floatEquals(brightnessFloat, PowerManager.BRIGHTNESS_OFF_FLOAT)) {
return PowerManager.BRIGHTNESS_OFF;
} else if (Float.isNaN(brightnessFloat)) {
return PowerManager.BRIGHTNESS_INVALID;
} else {
final float minFloat = PowerManager.BRIGHTNESS_MIN;
final float maxFloat = PowerManager.BRIGHTNESS_MAX;
//final float minInt = PowerManager.BRIGHTNESS_OFF + 1;
Log.d(TAG," brightnessFloatToIntRange: minInt:"+PowerManager.BRIGHTNESS_OFF + 1);
float minInt =166;
final float maxInt = PowerManager.BRIGHTNESS_ON;
return MathUtils.constrainedMap(minInt, maxInt, minFloat, maxFloat, brightnessFloat);
}
}
修改点二
修改点二:
/frameworks/base/core/java/android/os/PowerManager.java
BRIGHTNESS_MIN 最小亮度调节范围改为0.65f
其实修改点一已经解决了问题的,修改点二需要追索代码,为啥也需要修改一下。
代码跟踪
代码跟踪建议看一下这篇文章,上面也已经推荐过了:强烈建议 看一下完整的流程,从亮度进度条拖动到设置的完整过程,涉及Service、PowerManager 等。
DisplayManagerService
这里补充下:零时亮度,最终设置是需要走到如下 put 到系统里面取,才是真正的设置亮度,这个方法也是应用层设置亮度的方法呀。
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, newBrightnessInt, UserHandle.USER_CURRENT);
完整代码如下:
BrightnessSynchronizer.java
/**
* Updates both setting values if they have changed
* mDisplayManager.setBrightness automatically checks for changes
* Settings.System.putIntForUser needs to be checked, to prevent an extra callback to this class
*
* @param newBrightnessFloat Brightness setting as float to store in both settings
*/
private void updateBoth(float newBrightnessFloat) {
int newBrightnessInt = brightnessFloatToInt(newBrightnessFloat);
mDisplayManager.setBrightness(Display.DEFAULT_DISPLAY, newBrightnessFloat);
if (getScreenBrightnessInt(mContext) != newBrightnessInt) {
Log.d(TAG," updateBoth: newBrightnessInt:"+newBrightnessInt);
Settings.System.putIntForUser(mContext.getContentResolver(),
Settings.System.SCREEN_BRIGHTNESS, newBrightnessInt, UserHandle.USER_CURRENT);
}
}
最终通过日志打印,查看0-255 的亮度值,因为在brightnessIntToFloat 和 brightnessFloatToIntRange 中,我们设置了最小亮度65,也就是166,所以 我们编译固件,看日志打印就是166-255 的范围。