欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android亮度调节的几种实现方法

程序员文章站 2024-03-03 19:21:10
最近在做一个app的设置项,亮度调节。真正做时,发现android亮度调节比预想要复杂一些。其实目前网上已有不少这方面的资料,但有些博文具有一定误导性。在此将这块内容按照自...

最近在做一个app的设置项,亮度调节。真正做时,发现android亮度调节比预想要复杂一些。其实目前网上已有不少这方面的资料,但有些博文具有一定误导性。在此将这块内容按照自己理解整理一下。

整体上看,android亮度调节分为三个层次,分别是:android系统亮度调节、android app亮度调节和android当前屏幕(window)亮度调节。

1.android系统亮度调节

android系统亮度调节全局性最高,常见于系统设置中的亮度设置项。android中提供了获取和设置系统亮度值(“手动模式下的亮度值”)的接口,具体如下:

// 获取系统亮度
settings.system.getint(getcontentresolver(), settings.system.screen_brightness);
// 设置系统亮度
settings.system.putint(getcontentresolver(), settings.system.screen_brightness,systembrightness);

其中,需要注意的是,返回的亮度值是处于0-255之间的整型数值。

android 2.1以后的系统中,系统亮度调节中新增了“自动亮度”选项。“自动亮度”是依据外界光源来自动的改变系统亮度,目前大部分手机中对“自动亮度”还可以进行小幅度的调节其值。与自动亮度相对应的是“手动亮度”,当处于“手动亮度”下,设置拖动亮度进度条会大幅度的改变android系统亮度。“手动亮度”和“自动亮度”分别称之为android系统的“亮度模式”。

与之相对应的,android系统中也提供了获取和设置“亮度模式”的接口。

// 获取系统亮度模式
settings.system.getint(getcontentresolver(), settings.system.screen_brightness_mode);

// 设置系统亮度模式
settings.system.putint(getcontentresolver(), settings.system.screen_brightness_mode, systemmode);

可是遗憾的是,android中并未提供处于“自动亮度”模式下的亮度值接口。上面所说的获取系统亮度值接口实际上都是指“手动亮度”模式下的亮度值。

一般而言,通过手动亮度值以及设置系统亮度模式接口,可以满足常规的大部分针对android系统亮度设置编码需求,以完成系统亮度调节。

 2.android app亮度调节

与系统亮度不同的是,android中并未直接提供针对于app层面的亮度调节方式。因此,对于需要进行app的亮度调节,可以通过系统亮度调节或当前屏幕的亮度调节方式间接来实现。

3.android当前屏幕(window)亮度调节

android针对当前屏幕(window)提供了设置亮度的接口,常见写法如下:

window window = activity.getwindow();
windowmanager.layoutparams lp = window.getattributes();
lp.screenbrightness = brightness;
window.setattributes(lp);

其中,需要注意的是此处的brightness是一个0.0-1.0之间的一个float类型数值。

默认情况下,当我们直接修改了系统亮度值后,当前window中是可以即时反应出来亮度效果的,这是因为默认情况下,windowmanager.layoutparams的screenbrightness的默认值为windowmanager.layoutparams.brightness_override_none。

即表示window没有自己的亮度参数,将依随系统亮度效果的变化而变化。这也就是我们最常见的:当调整系统亮度后,所有window都即时反应出系统亮度设置效果。

当时,实际项目中我们还会遇到此类需求:系统设置亮度时只针对当前window或app内生效,而不影响到系统本身的亮度设置。

假设当前window内有一个seekbar,ui与系统亮度调节ui基本类似,用户可以滑动此seekbar,使得当前window亮度即时发生变化,且不影响到系统亮度效果。如何实现呢?

此时我们需要启用windowmanager.layoutparams的screenbrightness参数,使之具有自动的特定亮度值,设置此值后在当前window范围内,其将覆盖掉系统亮度设置。

因此,有必要将用户选择的亮度值转换为相应的window亮度值(为与系统亮度值相一致,假设seekbar的最大值为255)。

// 根据亮度值修改当前window亮度
public void changeappbrightness(context context, int brightness) {
  window window = ((activity) context).getwindow();
  windowmanager.layoutparams lp = window.getattributes();
  if (brightness == -1) {
    lp.screenbrightness = windowmanager.layoutparams.brightness_override_none;
  } else {
    lp.screenbrightness = (brightness <= 0 ? 1 : brightness) / 255f;
  }
  window.setattributes(lp);
}

其中,brightness形参为用户选择的亮度值。

那么,上述代码中为什么有一个"brightness == -1"的判断呢?在此主要是考虑到app设置项中可能出现的“跟随系统亮度”或“恢复系统默认亮度”此类设置,当用户进行此类操作时,直接将screenbrightness参数还原成默认参数值即可。因为由前文描述“自动亮度”模式下系统亮度值是不能直接得到的,那么当系统处于“自动亮度”模式下,此时brightness参数值将无法准确确定,因此,将screenbrightness参数还原成默认参数值成为一个行之有效的方法。

 4.android app亮度调节可行方案分析

目前网上有不少博文中提到app亮度调节时,提出的方案是在app设置项中,首先记录下设置之前的系统亮度值和亮度模式,用户在app设置项进行亮度调节时,直接修改系统亮度值,当用户退出此app,或app至于后台(如按下home按键等),再将系统亮度还原。初看起来貌似一个可行的方案。但是主要存在如下几个问题:

1.如何获取到设置之前的系统亮度值和亮度模式(因为之后在此app外部要恢复系统亮度值到此初始值)?当用户每次进入到设置页时获取?严格意义上来说,是没法准确记录的。因为android的用户操作不可预知性,如进入到设置页,拖动seekbar设置了一个亮度值,此时直接修改了系统的亮度值,如果此时用户在未将应用至于后台或未将应用退出的情况下直接在app外部修改了系统亮度设置,如小米中可以通过下拉标题栏,直接就可以设置系统亮度。因此,app亮度设置之前的系统亮度初始值获取存在困难。

2.如何判断用户来到了app外部?因为此时需要恢复系统亮度设置到初始系统亮度。如用户可以按下home按键,长按home按键直接切换app,直接back按键等一步步退出此app,下拉标题栏直接点击其他app通知信息进入到其他app,手机自动锁屏后解锁时用户直接进入其他应用等等,此类操作场景也具有不可预知性,因此,判断用户来到了app外部以恢复系统亮度到初始值的时机上也存在一定困难。

由此,app亮度调节方案推荐通过设置当前屏幕(window)方式进行。

大致思路如下:用户在设置项中进行亮度调节时,调用changeappbrightness()方法,将改变当前屏幕(window)的亮度,此时对系统亮度无任何影响,接下来存在的问题终于要就集中于当用户来到本app其他activity中,如果使得刚刚设置的亮度值得以即时反应出来。

 当用户进行亮度调节后,将当前亮度设置值保存起来(如保存到sharedpreferences中),在基类activity中的onresume方法中,可以取出sharedpreferences中的用户所设置的app亮度值,然后changeappbrightness()方法以实现每个当前屏幕的亮度调节。

 总体说来,通过设置当前屏幕(window)的方式来设置app亮度更加简单有效。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。