时间:2021-05-21
下拉状态栏有个亮度的进度条,如果开启了亮度自动调节开关,会随着周围光线变化,这个进度条也会随着变化,接下来就是看看这个功能是如何实现的。
基于 Android 9.0 分析。
BrightnessDialog,位于:
frameworks/base/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
ToggleSliderView,位于:
frameworks/base/packages/SystemUI/src/com/android/systemui/settings/ToggleSliderView.java
DisplayPowerController,位于:
frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
AutomaticBrightnessController,位于:
frameworks/base/services/core/java/com/android/server/display/AutomaticBrightnessController.java
BrightnessMappingStrategy,
状态栏里亮度页面是 BrightnessDialog,其中进度条设置是 ToggleSliderView,亮度自动调节主要是 DisplayPowerController 和 AutomaticBrightnessController 两个类,当亮度发生变化时,如果关联到 ToggleSliderView,用的是 ContentObserver,Uri 为 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ。
又进行了 BrightnessObserver 初始化:
/** ContentObserver to watch brightness **/private class BrightnessObserver extends ContentObserver { //省略部分代码 private final Uri BRIGHTNESS_FOR_VR_URI = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_FOR_VR); //Add By WuXiaolong for AutomaticBrightness private final Uri BRIGHTNESS_ADJ_URI = Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ); public BrightnessObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange) { onChange(selfChange, null); } @Override public void onChange(boolean selfChange, Uri uri) { if (selfChange) return; if (BRIGHTNESS_MODE_URI.equals(uri)) { mBackgroundHandler.post(mUpdateModeRunnable); mBackgroundHandler.post(mUpdateSliderRunnable); } //省略部分代码 //Add By WuXiaolong for AutomaticBrightness else if (BRIGHTNESS_ADJ_URI.equals(uri) && mAutomatic) { mBackgroundHandler.post(mUpdateSliderRunnable); } else { mBackgroundHandler.post(mUpdateModeRunnable); mBackgroundHandler.post(mUpdateSliderRunnable); } for (BrightnessStateChangeCallback cb : mChangeCallbacks) { cb.onBrightnessLevelChanged(); } } public void startObserving() { final ContentResolver cr = mContext.getContentResolver(); cr.unregisterContentObserver(this); //省略部分代码 cr.registerContentObserver( BRIGHTNESS_FOR_VR_URI, false, this, UserHandle.USER_ALL); //Add By WuXiaolong for AutomaticBrightness cr.registerContentObserver( BRIGHTNESS_ADJ_URI, false, this, UserHandle.USER_ALL); } public void stopObserving() { final ContentResolver cr = mContext.getContentResolver(); cr.unregisterContentObserver(this); }}其实我目前下载的源码,这块功能是不全的,我已经加上了,哪里进行 BrightnessObserver 的 ContentObserver 注册呢?
当亮度有变化时,会走 BrightnessObserver#onChange,最终走到:
private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { mExternalChange = true; try { switch (msg.what) { //省略部分代码 case MSG_UPDATE_SLIDER: updateSlider(msg.arg1, msg.arg2 != 0); break; //省略部分代码 default: super.handleMessage(msg); } } finally { mExternalChange = false; } }};走 updateSlider方法,到 :
private void animateSliderTo(int target) { if (!mControlValueInitialized) { // Don't animate the first value since it's default state isn't mea mControl.setValue(target); mControlValueInitialized = true; } //省略部分代码}接下来就是看看亮度自动调节主要的两个类 DisplayPowerController 和 AutomaticBrightnessController。DisplayPowerController 属于 Display 模块,其控制设备屏幕亮灭、背光、与Power关系密切,这里主要看下屏幕亮度的控制这方面的逻辑。
由于亮屏之后屏幕自动亮度才会生效,所以在亮屏的时候,流程会走到 DisplayPowerController 中的核心函数 updatePowerState():
private void updatePowerState() { // Update the power state request. //省略部分代码 final boolean autoBrightnessAdjustmentChanged = updateAutoBrightnessAdjustment(); if (autoBrightnessAdjustmentChanged) { mTemporaryAutoBrightnessAdjustment = Float.NaN; } // Use the autobrightness adjustment override if set. final float autoBrightnessAdjustment; if (!Float.isNaN(mTemporaryAutoBrightnessAdjustment)) { autoBrightnessAdjustment = mTemporaryAutoBrightnessAdjustment; mAppliedTemporaryAutoBrightnessAdjustment = true; } else { autoBrightnessAdjustment = mAutoBrightnessAdjustment; mAppliedTemporaryAutoBrightnessAdjustment = false; } boolean hadUserBrightnessPoint = false; // Configure auto-brightness. if (mAutomaticBrightnessController != null) { hadUserBrightnessPoint = mAutomaticBrightnessController.hasUserDataPoints(); mAutomaticBrightnessController.configure(autoBrightnessEnabled, mBrightnessConfiguration, mLastUserSetScreenBrightness / (float) PowerManager.BRIGHTNESS_ON, userSetBrightnessChanged, autoBrightnessAdjustment, autoBrightnessAdjustmentChanged, mPowerRequest.policy); } // Apply auto-brightness. boolean slowChange = false; if (brightness < 0) { float newAutoBrightnessAdjustment = autoBrightnessAdjustment; if (autoBrightnessEnabled) { brightness = mAutomaticBrightnessController.getAutomaticScreenBrightness(); newAutoBrightnessAdjustment = mAutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment(); } if (brightness >= 0) { // Use current auto-brightness value and slowly adjust to changes. brightness = clampScreenBrightness(brightness); if (mAppliedAutoBrightness && !autoBrightnessAdjustmentChanged) { slowChange = true; // slowly adapt to auto-brightness } // Tell the rest of the system about the new brightness. Note that we do this // before applying the low power or dim transformations so that the slider // accurately represents the full possible range, even if they range changes what // it means in absolute terms. putScreenBrightnessSetting(brightness); mAppliedAutoBrightness = true; } else { mAppliedAutoBrightness = false; } if (autoBrightnessAdjustment != newAutoBrightnessAdjustment) { // If the autobrightness controller has decided to change the adjustment value // used, make sure that's reflected in settings. putAutoBrightnessAdjustmentSetting(newAutoBrightnessAdjustment); } } else { mAppliedAutoBrightness = false; } //省略部分代码}接下来分别看看 autoBrightnessAdjustment 和 newAutoBrightnessAdjustment 怎么来的?
autoBrightnessAdjustment 是来自 mTemporaryAutoBrightnessAdjustment 或 mAutoBrightnessAdjustment 赋值,mAutoBrightnessAdjustment 在第 7 步mAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();有初始化,看下 getAutoBrightnessAdjustmentSetting():
private float getAutoBrightnessAdjustmentSetting() { final float adj = Settings.System.getFloatForUser(mContext.getContentResolver(), Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT); return Float.isNaN(adj) ? 0.0f : clampAutoBrightnessAdjustment(adj);}继续看下 clampAutoBrightnessAdjustment:
private static float clampAutoBrightnessAdjustment(float value) { return MathUtils.constrain(value, -1.0f, 1.0f);}这里注意下 MathUtils.constrain() 表示百分比缩放函数,比如 MathUtils.constrain(0.5, 0, 255) 表示 (255-0)*0.5。
这样了解了 autoBrightnessAdjustment,接下来看 newAutoBrightnessAdjustment。
看到 newAutoBrightnessAdjustment 调用了 AutomaticBrightnessController.getAutomaticScreenBrightnessAdjustment(),最终是到了 BrightnessMapper#getAutoBrightnessAdjustment() 其中 mAutoBrightnessAdjustment 变量,赋值是在 BrightnessMapper#setAutoBrightnessAdjustment:
@Overridepublic boolean setAutoBrightnessAdjustment(float adjustment) { adjustment = MathUtils.constrain(adjustment, -1, 1); if (adjustment == mAutoBrightnessAdjustment) { return false; } if (DEBUG) { Slog.d(TAG, "setAutoBrightnessAdjustment: " + mAutoBrightnessAdjustment + " => " + adjustment); PLOG.start("auto-brightness adjustment"); } mAutoBrightnessAdjustment = adjustment; computeSpline(); return true;}这个方法调用又回到了 AutomaticBrightnessController#setAutoBrightnessAdjustment:
private boolean setAutoBrightnessAdjustment(float adjustment) { return mBrightnessMapper.setAutoBrightnessAdjustment(adjustment);}AutomaticBrightnessController#setAutoBrightnessAdjustment调用是来到 AutomaticBrightnessController#configure()方法:
public void configure(boolean enable, @Nullable BrightnessConfiguration configuration, float brightness, boolean userChangedBrightness, float adjustment, boolean userChangedAutoBrightnessAdjustment, int displayPolicy) { // While dozing, the application processor may be suspended which will prevent us from // receiving new information from the light sensor. On some devices, we may be able to // switch to a wake-up light sensor instead but for now we will simply disable the sensor // and hold onto the last computed screen auto brightness. We save the dozing flag for // debugging purposes. boolean dozing = (displayPolicy == DisplayPowerRequest.POLICY_DOZE); boolean changed = setBrightnessConfiguration(configuration); changed |= setDisplayPolicy(displayPolicy); if (userChangedAutoBrightnessAdjustment) { changed |= setAutoBrightnessAdjustment(adjustment); } if (userChangedBrightness && enable) { // Update the brightness curve with the new user control point. It's critical this // happens after we update the autobrightness adjustment since it may reset it. changed |= setScreenBrightnessByUser(brightness); } final boolean userInitiatedChange = userChangedBrightness || userChangedAutoBrightnessAdjustment; if (userInitiatedChange && enable && !dozing) { prepareBrightnessAdjustmentSample(); } changed |= setLightSensorEnabled(enable && !dozing); if (changed) { updateAutoBrightness(false ); }}AutomaticBrightnessController#configure()调用来到了 DisplayPowerController #updatePowerState()。
这样也知道了 newAutoBrightnessAdjustment,继续 putAutoBrightnessAdjustmentSetting:
private void putAutoBrightnessAdjustmentSetting(float adjustment) { mAutoBrightnessAdjustment = adjustment; Settings.System.putFloatForUser(mContext.getContentResolver(), Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adjustment, UserHandle.USER_CURRENT);}就调到第 4 步 BrightnessObserver#onChange,进度条随之变化,Over!
以上就是Android 如何实现亮度自动调节的详细内容,更多关于Android 亮度自动调节的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了Android开发实现调节屏幕亮度功能。分享给大家供大家参考,具体如下:在很多app中进入二维码显示界面时会自动调整屏幕亮度,那么如何实现调节ap
iPhone5怎么自动调节亮度?很多人都发现iPhone5自带的自动调节亮度没有用,现在iPhone5亮度调节插件可以非常轻易让iPhone5自动调节亮度。免费
打开亮度自动调节之后,手机屏幕的亮度会根据周围环境的亮度自动调节,如果在比较亮的环境下,手机屏幕亮度会变大,这个时候就比较费电了。我们可以选择关闭亮度自动调节,
ipad显示亮度调节的方法有: 1、首先依次点击“设置、亮度与墙纸”,然后打开“自动亮度调节”即可。如果“自动亮度调节”已打开,ipad会使用内建的环境光感应
打开亮度自动调节之后,手机屏幕的亮度会根据周围环境的亮度自动调节,如果在比较亮的环境下,手机屏幕亮度会变大,这个时候就比较费电了。我们可以选择关闭亮度自动调节,