android 屏幕亮度调节方法详解
屏幕亮度自动调节:
主要是从sensor分析之中分离出来分析light 光线感应器,因此就分析一下自动调节屏幕亮度(手机随着光线的强度自我调节,也就是在亮的光线下屏幕自动调亮一些,暗的时候就自动调暗一些,省得光线对眼睛有刺激).....
(本人从历经挫折才大概了解流程),现在就开始讲一下流程,如果有不对地方希望牛人指出来。。。
先从sttings入手吧,在diaplay中有屏幕亮度调节,有一个进度调,上面有一个checkbox(自动调节屏幕亮度的),
那么我们当然去找settings下的文件开始看了,先找到
diaplaysettings.java文件以及display_setting.xml文件,display_setting.xml里面能找到相应的组件,但是 在diaplaysettings.java文件中却不能找到调用相应组件的代码,
那么我们再到settings中去找,能找到brightnesspreference.java文件,没错这个文件就是自动调节亮度的文件,我们先看看代码:
构造函数中有mautomaticavailable = context.getresources().getboolean(com.android.internal.r.bool.config_automatic_brightness_available);
开始以为mautomaticavailabl的值(为true,在config.xml中)是判断是否自动调节亮度,因为在我跟进到powermanagerservice.java中,在initinthread() 中
musesoftwareautobrightness = resources.getboolean(
com.android.internal.r.bool.config_automatic_brightness_available);
if (musesoftwareautobrightness) {
mautobrightnesslevels = resources.getintarray(
com.android.internal.r.array.config_autobrightnesslevels);//得到自动化调节的值调用 getautobrightnessvalue(int sensorvalue, int[] values) 方法
mlcdbacklightvalues = resources.getintarray(
com.android.internal.r.array.config_autobrightnesslcdbacklightvalues);
mbuttonbacklightvalues = resources.getintarray(
com.android.internal.r.array.config_autobrightnessbuttonbacklightvalues);
mkeyboardbacklightvalues = resources.getintarray(。。。。。
。。。。。。这里看起来好像是当musesoftwareautobrightness为true时就取得config.xml文件config_autobrightnesslevels的值,再去根据光线自动调节,但是mautomaticavailabl的值只是说明有没有自动调节屏幕的功能(比如说你将config.xml文件的config_automatic_brightness_available的值改为false,编译替换framework-res.apk那么在屏幕亮度调节中将没有自动调节的checkbox),这也能解释构造函数一开始就初始化mautomaticavailabl的值。
接下来在brightnesspreference.java文件中有onprogresschanged,onstarttrackingtouch(seekbar seekbar),onstoptrackingtouch(seekbar seekbar)方法,这些一看也能懂就不介绍了,在onbinddialogview(view view)方法中有
mcheckbox = (checkbox)view.findviewbyid(r.id.automatic_mode);
if (mautomaticavailable) {//当有自动调节功能
mcheckbox.setoncheckedchangelistener(this);//为checkbox添加监听事件
try {
moldautomatic = settings.system.getint(getcontext().getcontentresolver(),
settings.system.screen_brightness_mode);
。。。。。。
主要看public void oncheckedchanged(compoundbutton buttonview, boolean ischecked) {
setmode(ischecked ? settings.system.screen_brightness_mode_automatic
: settings.system.screen_brightness_mode_manual);
if (!ischecked) {
setbrightness(mseekbar.getprogress() + minimum_backlight);
}
}
这里才是你选择自动调节亮度的checkbox,如果选择则setmode(settings.system.screen_brightness_mode_automatic);并将数据存放到中。
这里是重点:这里有个数据库,当监测到数据库中的值发生改变时也就是变为settings.system.screen_brightness_mode_automatic时,就会跳到
powermanagerservice.java的initinthread()中contentresolver resolver = mcontext.getcontentresolver();
cursor settingscursor = resolver.query(settings.system.content_uri, null,
"(" + settings.system.name + "=?) or ("
+ settings.system.name + "=?) or ("
+ settings.system.name + "=?) or ("
+ settings.system.name + "=?) or ("
+ settings.system.name + "=?) or ("
+ settings.system.name + "=?) or ("
+ settings.system.name + "=?)",
new string[]{stay_on_while_plugged_in, screen_off_timeout, dim_screen, xec_dls_control,
screen_brightness_mode, window_animation_scale, transition_animation_scale},
null);
msettings = new contentquerymap(settingscursor, settings.system.name, true, mhandler);
settingsobserver settingsobserver = new settingsobserver();
msettings.addobserver(settingsobserver);
数据库中数据发生改变时触发事件的发生。
在 powermanagerservice.java的systemready()(只在开机调用一次就不再调用)中
if (musesoftwareautobrightness) {
log.i("frist","frist="+"aaaa");
mlightsensor = msensormanager.getdefaultsensor(sensor.type_light);
enablelightsensor(true);
}
而musesoftwareautobrightness是在initinthread()线程中取得了true值,那么就到enablelightsensor(true);方法去看
if (enable) {
msensormanager.registerlistener(mlightlistener, mlightsensor,
sensormanager.sensor_delay_normal);
}
如果传递来的值为true也就是enable=true就监听而且用匹配屏幕方向变化的感应sensor_delay_normal。
再看mlightlistener事件:sensoreventlistener mlightlistener = new sensoreventlistener() {
public void onsensorchanged(sensorevent event) {
synchronized (mlocks) {
int value = (int)event.values[0];//从event里面获取当前数据
log.i("value","value="+value);
long milliseconds = systemclock.elapsedrealtime();
if (mdebuglightsensor) {
slog.d(tag, "onsensorchanged: light value: " + value);
}
mhandler.removecallbacks(mautobrightnesstask);
if (mlightsensorvalue != value) {//mlightsensorvalue是当前的屏幕亮度
if (mlightsensorvalue == -1 ||
milliseconds < mlastscreenontime + mlightsensorwarmuptime) {
// process the value immediately if screen has just turned on
lightsensorchangedlocked(value);
} else {
// delay processing to debounce the sensor
mlightsensorpendingvalue = value;//mlightsensorpendingvalue是准备要设置的亮度
mhandler.postdelayed(mautobrightnesstask, light_sensor_delay);//到mautobrightnesstask线程去完成自动调节
}
} else {
mlightsensorpendingvalue = -1;
}
}
}
当前屏幕亮度肯定不等与-1,所以做else中的mhandler.postdelayed(mautobrightnesstask, light_sensor_delay),那么我们再到mautobrightnesstask
线程看:private runnable mautobrightnesstask = new runnable() {
public void run() {
synchronized (mlocks) {
int value = (int)mlightsensorpendingvalue;
log.i("mlightsensorpendingvalue","mlightsensorpendingvalue"+mlightsensorpendingvalue);
if (value >= 0) {
mlightsensorpendingvalue = -1;
lightsensorchangedlocked(value);
}
}
}
};就是不断的去调用lightsensorchangedlocked(value)
private void lightsensorchangedlocked(int value) {
。。。。。。。
if (mlightsensorvalue != value) {
mlightsensorvalue = value;
if ((mpowerstate & battery_low_bit) == 0) {
// use light sensor value no matter it is in a dock or not.
int lcdvalue = getautobrightnessvalue(
value,
mlcdbacklightvalues);// 取得mlcdbacklightvalues里面的值
int buttonvalue = getautobrightnessvalue(value, mbuttonbacklightvalues);
int keyboardvalue;
if (mkeyboardvisible) {
keyboardvalue = getautobrightnessvalue(value, mkeyboardbacklightvalues);
} else {
keyboardvalue = 0;
}
。。。
if (mautobrightessenabled && mscreenbrightnessoverride < 0) {//设置屏幕亮度
mscreenbrightness.settargetlocked(lcdvalue, autobrightness_anim_steps,
initial_screen_brightness, (int)mscreenbrightness.curvalue);
}
。。。。。
}