admin管理员组

文章数量:1516870

Android屏幕亮度适配

前言

最近由于接手了视频项目中的亮度调整功能,抽空总结了下Android亮度调节的方式,以及在如今系统定制化的情况下会遇到的坑。

亮度调节模式

查看 说明,可以看到,目前Android提供了两种亮度调节模式。

SCREEN_BRIGHTNESS_MODE_AUTOMATIC 自动调节亮度,系统根据环境变化自动调整屏幕的亮度,以适应眼睛的舒适度。

SCREEN_BRIGHTNESS_MODE_MANUAL 手动调节模式,该模式即通过状态栏下拉控制面板或者设置中的亮度调节来改变当前系统的屏幕亮度。

对于这两种模式,系统提供了属性接口来设置亮度调节模式,可以用如下方法实现:

publicstaticvoidsetAutoAdjustBrightness(Context context,boolean auto){int value =0;if(auto){
        value = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;}else{
        value = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL;}
    ContentResolver cr = context.getContentResolver();
    Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS_MODE, value);}

设置亮度值

目前Android提供了两种方式来调亮度值:一是通过调整系统屏幕亮度值,二是通过调整界面当前窗口的亮度值,下面分别介绍这两种方法以及区别。

屏幕亮度值介绍

首先先介绍下屏幕亮度值,查看 的介绍,目前原生系统屏幕的亮度值范围位于:0~255。获取方式如下:

publicstaticintgetSystemBrightness(Context context){int result =0;
    ContentResolver cr = context.getContentResolver();try{
        result = Settings.System.getInt(cr, Settings.System.SCREEN_BRIGHTNESS);}catch(SettingNotFoundException e){
        e.printStackTrace();}return result;}

以下是通过获取当前界面窗口的亮度值,但不一定是系统的亮度值。

publicstaticintgetActivityBrightness(Activity activity){
    WindowManager.LayoutParams params = activity.getWindow().getAttributes();returnint(params.screenBrightness *255);}

调整系统屏幕亮度值

调整系统的屏幕亮度值的方式如下。

publicstaticvoidsetSystemBrightness(Context context,int value){
    ContentResolver cr = context.getContentResolver();// 0 ~ 255
    Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS, value);}

当然有个前提,需要保证AndroidManifest.xml中声明如下权限:

<uses-permissionandroid:name="android.permission.WRITE_SETTINGS"/>

调整当前窗口亮度值

调整界面当前窗口的屏幕亮度值的方式如下。

publicstaticvoidsetActivityBrightness(Activity activity,int value){
    WindowManager.LayoutParams params = activity.getWindow().getAttributes();
    params.screenBrightness = value /255f;
    activity.getWindow().setAttributes(params);}

区别

上述的第一种方式是通过调整系统的亮度值来改变当前页面的亮度值,因此其他页面也会跟着调整亮度,并且会受自动亮度模式影响;而第二种方式是通过设置Window属性的方式来控制页面的亮度值,不会影响其他页面,并且不受自动亮度模式影响。

关于定制化的坑

概述

由于Android系统开源的缘故,许多厂商对其进行了深度的定制,所以安卓的碎片化很严重,并且随着系统版本的不断衍进,定制化、碎片化会越来越严重。而对于屏幕亮度来说,厂商为了适配新功能,对原生规定的亮度值范围0-255进行了扩展,最大扩展至0-2047/0-4095,并且值的计算并不是线性的,大多数是使用原生的HLG算法,因此应用层有屏幕亮度调整功能的,需要对该扩展进行适配。

适配方式

对于前面所说的两种调整屏幕亮度的方式,只有调整系统亮度的方式需要适配厂商的扩展。我们所需做的就是在使用屏幕亮度值时,将HLG算法转换成线性算法,然后应用在应用中,下面提供一个算法解析。

privatestaticfinalint GAMMA_SPACE_MAX =getGammaSpaceMax();privatestaticfinalfloat R =0.2f;privatestaticfinalfloat A =0.314f;privatestaticfinalfloat B =0.06f;privatestaticfinalfloat C =0.221f;/**
 * A function for converting from the gamma space that the slider works in to the
 * linear space that the setting works in.
 * @param val val The slider value.
 * @param min The minimum acceptable value for the setting.
 * @param max The maximum acceptable value for the setting.
 * @return The corresponding setting value.
 */publicstaticintconvertGammaToLinear(int val,int min,int max){finalfloat normalizedVal =norm(0, GAMMA_SPACE_MAX, val);finalfloat ret;if(normalizedVal <= R){
        ret =sq(normalizedVal / R);}else{
        ret =(float)(Math.exp((normalizedVal - C)/ A)+ B);}// HLG is normalized to the range [0, 12], so we need to re-normalize to the range [0, 1]// in order to derive the correct setting value.// MIUI MOD: START// return Math.round(MathUtils.lerp(min, max, ret / 12));int tmpVal = Math.round(lerp(min, max, ret /12));return tmpVal > max ? max : tmpVal;// END}/**
 * A function for converting from the linear space that the setting works in to the
 * gamma space that the slider works in.
 * @param val The brightness setting value.
 * @param min The minimum acceptable value for the setting.
 * @param max The maximum acceptable value for the setting.
 * @return The corresponding slider value
 */publicstaticintconvertLinearToGamma(int val,int min,int max){// For some reason, HLG normalizes to the range [0, 12] rather than [0, 1]finalfloat normalizedVal =norm(min, max, val)*12;finalfloat ret;if(normalizedVal <=1f){
        ret =(float)(Math.sqrt(normalizedVal)* R);}else{
        ret = A *log(normalizedVal - B)+ C;}return Math.round(lerp(0, GAMMA_SPACE_MAX, ret));}privatestaticfloatnorm(float start,float stop,float value){return(value - start)/(stop - start);}privatestaticfloatsq(float v){return v * v;}privatestaticfloatlerp(float start,float stop,float amount){return start +(stop - start)* amount;}publicstaticfloatlog(float a){return(float) Math.log(a);}

本文标签: 系统编程亮度调节