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

android 屏幕亮度调节方法详解

程序员文章站 2024-02-11 14:12:58
屏幕亮度自动调节:主要是从sensor分析之中分离出来分析light 光线感应器,因此就分析一下自动调节屏幕亮度(手机随着光线的强度自我调节,也就是在亮的光线下屏幕自动调亮...

屏幕亮度自动调节
主要是从sensor分析之中分离出来分析light 光线感应器,因此就分析一下自动调节屏幕亮度(手机随着光线的强度自我调节,也就是在亮的光线下屏幕自动调亮一些,暗的时候就自动调暗一些,省得光线对眼睛有刺激).....

    (本人从历经挫折才大概了解流程),现在就开始讲一下流程,如果有不对地方希望牛人指出来。。。

    先从sttings入手吧,在diaplay中有屏幕亮度调节,有一个进度调,上面有一个checkbox(自动调节屏幕亮度的),
android 屏幕亮度调节方法详解
那么我们当然去找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);
                }
。。。。。
   }