下拉菜单中自动亮度调节
来源:互联网 发布:淘宝手机版订单回收站 编辑:程序博客网 时间:2024/05/17 08:46
frameworks\base\packages\SystemUI\AndroidManifest.xml
<activity android:name=".settings.BrightnessDialog" android:label="@string/quick_settings_brightness_dialog_title" android:theme="@android:style/Theme.DeviceDefault.Dialog" android:finishOnCloseSystemDialogs="true" android:launchMode="singleInstance" android:excludeFromRecents="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.SHOW_BRIGHTNESS_DIALOG" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter></activity>
frameworks\base\packages\SystemUI\src\com\android\systemui\settings\BrightnessDialog.java
/** A dialog that provides controls for adjusting the screen brightness. */public class BrightnessDialog extends Activity { private BrightnessController mBrightnessController; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Window window = getWindow(); window.setGravity(Gravity.TOP); window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); window.requestFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.quick_settings_brightness_dialog); final ImageView icon = (ImageView) findViewById(R.id.brightness_icon_on); final ToggleSlider slider = (ToggleSlider) findViewById(R.id.brightness_slider); mBrightnessController = new BrightnessController(this, icon, slider); } @Override protected void onStart() { super.onStart(); mBrightnessController.registerCallbacks(); MetricsLogger.visible(this, MetricsEvent.BRIGHTNESS_DIALOG); } @Override protected void onStop() { super.onStop(); MetricsLogger.hidden(this, MetricsEvent.BRIGHTNESS_DIALOG); mBrightnessController.unregisterCallbacks(); }}
// BrightnessController 实现了ToggleSlider监听的类,其内部对象类是赋值传入的slider,从而与ToggleSlider 关联起来
// mBrightnessController.registerCallbacks(); 将BrightnessController 设置为slider 的监听器,同时设置对数据库的监BrightnessController
frameworks\base\packages\SystemUI\src\com\android\systemui\settings\BrightnessController.java
public class BrightnessController implements ToggleSlider.Listener {
public interface BrightnessStateChangeCallback { public void onBrightnessLevelChanged(); }/** ContentObserver to watch brightness **/private class BrightnessObserver extends ContentObserver {
private final Uri BRIGHTNESS_MODE_URI = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE); private final Uri BRIGHTNESS_URI = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); private final Uri BRIGHTNESS_ADJ_URI = Settings.System.getUriFor(Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ);
}
public void registerCallbacks() { if (mListening) { return; } mBrightnessObserver.startObserving(); mUserTracker.startTracking(); // Update the slider and mode before attaching the listener so we don't // receive the onChanged notifications for the initial values. updateMode(); updateSlider(); mControl.setOnChangedListener(this); mListening = true;}
}
// 当注册数据库监听器与ToggleSlider的监听器后,如果数据库改变,onChange 就会更新ToggleSlider ,如果ToggleSlider 改变了,这回调用其onChange函数,这个时候会更新数据库项,反过来由于数据库项变了,就会更新ToggleSlider 到对应的进度位置。
frameworks\base\packages\SystemUI\src\com\android\systemui\settings\ToggleSlider.java
mToggle = (CompoundButton) findViewById(R.id.toggle);mToggle.setOnCheckedChangeListener(mCheckListener);mSlider = (ToggleSeekBar) findViewById(R.id.slider);mSlider.setOnSeekBarChangeListener(mSeekListener);
private final OnCheckedChangeListener mCheckListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton toggle, boolean checked) { mSlider.setEnabled(!checked); if (mListener != null) { mListener.onChanged( ToggleSlider.this, mTracking, checked, mSlider.getProgress(), false); } if (mMirror != null) { mMirror.mToggle.setChecked(checked); } }};
private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (mListener != null) { mListener.onChanged( ToggleSlider.this, mTracking, mToggle.isChecked(), progress, false); } }
ToggleSlider 是由多个控件组成的,这里一个是check控件、一个是进度条控件,并分别绑定对应的监听器。
private ToggleSlider mMirror;private BrightnessMirrorController mMirrorController;ToggleSlider 这两个成员用于下拉设置中设置与隐藏亮度进度条。
public void setMirror(ToggleSlider toggleSlider) { mMirror = toggleSlider; if (mMirror != null) { mMirror.setChecked(mToggle.isChecked()); mMirror.setMax(mSlider.getMax()); mMirror.setValue(mSlider.getProgress()); }}public void setMirrorController(BrightnessMirrorController c) { mMirrorController = c;}
这里将 mToggle、mSlider 值设置到 mMirror
frameworks\base\packages\SystemUI\src\com\android\systemui\qs\QSPanel.java
public void setBrightnessMirror(BrightnessMirrorController c) { mBrightnessMirrorController = c; ToggleSlider brightnessSlider = (ToggleSlider) findViewById(R.id.brightness_slider); ToggleSlider mirror = (ToggleSlider) c.getMirror().findViewById(R.id.brightness_slider); brightnessSlider.setMirror(mirror); brightnessSlider.setMirrorController(c);}frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBar.javamQSPanel.setBrightnessMirror(mBrightnessMirrorController);这里 mBrightnessMirrorController控制 ToggleSlider mirror其在下拉菜单中的显示与隐藏,而其值由 mToggle、mSlider 的值设置。
frameworks\base\packages\SystemUI\src\com\android\systemui\settings\BrightnessController.java
public void onChanged(ToggleSlider view, boolean tracking, boolean automatic, int value, boolean stopTracking) { updateIcon(mAutomatic); if (mExternalChange) return; if (!mAutomatic) { final int val = value + mMinimumBacklight; if (stopTracking) { MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS, val); } setBrightness(val); if (!tracking) { AsyncTask.execute(new Runnable() { public void run() { Settings.System.putIntForUser(mContext.getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, val, UserHandle.USER_CURRENT); } }); } } else { final float adj = value / (BRIGHTNESS_ADJ_RESOLUTION / 2f) - 1; if (stopTracking) { MetricsLogger.action(mContext, MetricsEvent.ACTION_BRIGHTNESS_AUTO, value); } setBrightnessAdj(adj); if (!tracking) { AsyncTask.execute(new Runnable() { public void run() { Settings.System.putFloatForUser(mContext.getContentResolver(), Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, adj, UserHandle.USER_CURRENT); } }); } } for (BrightnessStateChangeCallback cb : mChangeCallbacks) { cb.onBrightnessLevelChanged(); }}
mAutomaticAvailable = context.getResources().getBoolean( com.android.internal.R.bool.config_automatic_brightness_available);
自动亮度是否支持,设置Settings.System.SCREEN_BRIGHTNESS_MODE
public static final String SCREEN_BRIGHTNESS_MODE = "screen_brightness_mode";支持则设置为Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC ,否则设置为 Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL这里监听进度条改变,并记录到数据库中,并调用PMS设置亮度
private class BrightnessObserver extends ContentObserver { private final Uri BRIGHTNESS_MODE_URI = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS_MODE); private final Uri BRIGHTNESS_URI = Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS); 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; try { mExternalChange = true; if (BRIGHTNESS_MODE_URI.equals(uri)) { updateMode(); updateSlider();同时systemUI 中BrightnessController会注册监听器监听数据库改变从而改变进度条的位置
frameworks\base\services\core\java\com\android\server\power\PowerManagerService.java
关闭自动背光:
设置 mTemporaryScreenBrightnessSettingOverride 为当前进度条值,同时会设置 Settings.System.SCREEN_BRIGHTNESS 值为val,但是这个时候值是一样的,所以setBrightness(val);-》mPower.setTemporaryScreenBrightnessSettingOverride(brightness);SCREEN_BRIGHTNESS 不会变化,紧接着会再次调用这个函数,设置的值为用户点击位置的值,从而马上更新SCREEN_BRIGHTNESS ,
这个时候PMS 监听数据库值Settings.System.SCREEN_BRIGHTNESS 改变,并执行以下
mScreenBrightnessSetting = Settings.System.getIntForUser(resolver, Settings.System.SCREEN_BRIGHTNESS, mScreenBrightnessSettingDefault,
if (oldScreenBrightnessSetting != mScreenBrightnessSetting) { mTemporaryScreenBrightnessSettingOverride = -1;}mDirty |= DIRTY_SETTINGS;updatePowerStateLocked(); //这个时候亮度值不一样,从而调节亮度。
当用户点击进度条到不同位置时,
1、进度条会调用setBrightness(val),但是值还是当前进度条的值。这样会调用如下方法:
setBrightness(val); //设置 mTemporaryScreenBrightnessSettingOverride 为当前进度条的值。
mDirty |= DIRTY_SETTINGS; //设置标记,这样才会调用updatePowerStateLocked();updatePowerStateLocked(); //更新设置屏膜亮度,但是由于设置的为当前进度条的值,即前后亮度一致,所以这次并不会改变屏膜亮度。2、这个时候进度条更新到用户设置的值,这个时候会重复1、3、PMS中监听到SCREEN_BRIGHTNESS 数据库改变,从而将mTemporaryScreenAutoBrightnessAdjustmentSettingOverride 改为 -1,这个时候从数据库中读取的 SCREEN_BRIGHTNESS 更上次保存的不一样,从而调用mDirty |= DIRTY_SETTINGS;updatePowerStateLocked();
将亮度调到用户设置的亮度值。
如果打开自动背光:与手动一样
阶段1
setBrightnessAdj(adj); --》
mPower.setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(adj);-》
mDirty |= DIRTY_SETTINGS;updatePowerStateLocked(); // 这个时候并没有改变亮度,用于设置的是当前进度条的值阶段2设置mTemporaryScreenAutoBrightnessAdjustmentSettingOverride 为adj,同时设置 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ这个时候会监听数据库值 Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJfinal float oldScreenAutoBrightnessAdjustmentSetting = mScreenAutoBrightnessAdjustmentSetting;mScreenAutoBrightnessAdjustmentSetting = Settings.System.getFloatForUser(resolver, Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ, 0.0f, UserHandle.USER_CURRENT);if (oldScreenAutoBrightnessAdjustmentSetting != mScreenAutoBrightnessAdjustmentSetting) { mTemporaryScreenAutoBrightnessAdjustmentSettingOverride = Float.NaN;}
//监听
private final class SettingsObserver extends ContentObserver { public SettingsObserver(Handler handler) { super(handler); } @Override public void onChange(boolean selfChange, Uri uri) { synchronized (mLock) { handleSettingsChangedLocked(); } }}
private void handleSettingsChangedLocked() { updateSettingsLocked(); updatePowerStateLocked();}
阶段1
setBrightnessAdj(adj); --》
mPower.setTemporaryScreenAutoBrightnessAdjustmentSettingOverride(adj);-》
mDirty |= DIRTY_SETTINGS;updatePowerStateLocked();
--》
// Phase 2: Update display power state.boolean displayBecameReady = updateDisplayPowerStateLocked(dirtyPhase2);这个时候 有 DIRTY_SETTINGS 并且 mTemporaryScreenAutoBrightnessAdjustmentSettingOverride 是有效值,否则取
mScreenAutoBrightnessAdjustmentSetting
这里赋值mDisplayPowerRequest
// Update display power request.mDisplayPowerRequest.screenBrightness = screenBrightness; ---屏膜亮度mDisplayPowerRequest.screenAutoBrightnessAdjustment = ---自动进度条值,现在是mTemporaryScreenAutoBrightnessAdjustmentSettingOverride screenAutoBrightnessAdjustment;mDisplayPowerRequest.brightnessSetByUser = brightnessSetByUser;mDisplayPowerRequest.useAutoBrightness = autoBrightness; ---自动调节值mDisplayPowerRequest.useProximitySensor = shouldUseProximitySensorLocked();mDisplayPowerRequest.lowPowerMode = mLowPowerModeEnabled;mDisplayPowerRequest.boostScreenBrightness = mScreenBrightnessBoostInProgress;mDisplayPowerRequest.useTwilight = mBrightnessUseTwilight;
mDisplayReady = mDisplayManagerInternal.requestPowerState(mDisplayPowerRequest, mRequestWaitForNegativeProximity);
实现在
frameworks\base\services\core\java\com\android\server\display\DisplayManagerService.java
public boolean requestPowerState(DisplayPowerRequest request, boolean waitForNegativeProximity) { return mDisplayPowerController.requestPowerState(request, waitForNegativeProximity);}
这个时候判断 mPendingRequestLocked 与 request可以知道是否changed,从而是否调用sendUpdatePowerStateLocked,并进入请求标识mPendingRequestChangedLocked
if (changed && !mPendingRequestChangedLocked) { mPendingRequestChangedLocked = true; sendUpdatePowerStateLocked();}
if (changed) { mDisplayReadyLocked = false; ---如果changed没准备好}
==》
private void sendUpdatePowerStateLocked() { if (!mPendingUpdatePowerStateLocked) { mPendingUpdatePowerStateLocked = true; Message msg = mHandler.obtainMessage(MSG_UPDATE_POWER_STATE); msg.setAsynchronous(true); mHandler.sendMessage(msg); }}
进入请求mPendingUpdatePowerStateLocked
@Overridepublic void handleMessage(Message msg) { switch (msg.what) { case MSG_UPDATE_POWER_STATE: updatePowerState(); break; case MSG_PROXIMITY_SENSOR_DEBOUNCED: debounceProximitySensor(); break; case MSG_SCREEN_ON_UNBLOCKED: if (mPendingScreenOnUnblocker == msg.obj) { unblockScreenOn(); updatePowerState(); } break; case MSG_PROTECT_LOW_DIMMING: handleProtectLowDimming(); break; }}
==》
updatePowerState();
synchronized (mLock) { mPendingUpdatePowerStateLocked = false; if (mPendingRequestLocked == null) { return; // wait until first actual power request } if (mPowerRequest == null) { mPowerRequest = new DisplayPowerRequest(mPendingRequestLocked); mWaitingForNegativeProximity = mPendingWaitForNegativeProximityLocked; mPendingWaitForNegativeProximityLocked = false; mPendingRequestChangedLocked = false; mustInitialize = true; } else if (mPendingRequestChangedLocked) { autoBrightnessAdjustmentChanged = (mPowerRequest.screenAutoBrightnessAdjustment != mPendingRequestLocked.screenAutoBrightnessAdjustment); mPowerRequest.copyFrom(mPendingRequestLocked); mWaitingForNegativeProximity |= mPendingWaitForNegativeProximityLocked; mPendingWaitForNegativeProximityLocked = false; mPendingRequestChangedLocked = false; mDisplayReadyLocked = false; }
这个时候构造 mPowerRequest
updateAutoBrightness()
根据光感应出一个值(算法),由这个值算出一个屏膜亮度newScreenAutoBrightness,
并与mScreenAutoBrightness比较,如果不一样就会updateBrightness
自动背光亮度mScreenAutoBrightness
mAppliedAutoBrightness
mScreenBrightness
手动模式
这个时候进度条对应的值是亮度值 SCREEN_BRIGHTNESS 0~255
自动模式下的亮度
这个时候进度条对应的值是[-1,1],即缩放比例mScreenAutoBrightnessAdjustment,根据这个比例来得到一个亮度值
自动模式下的自动动背光调节
自动背光传感器会自动感应光强度,并通过算法获得一个亮度值mScreenAutoBrightness,与当前屏膜亮度mScreenBrightness比较,
变化则会自动调节屏膜亮度。或者这个时候调节进度条会导致mScreenAutoBrightnessAdjustment变化,从而调节亮度。
问题:
1、手动与自动切换时,会出现进度条不一样,并且也会出些亮度不一样
---这是由于手动模式对应的是上一次SCREEN_BRIGHTNESS ,而自动模式对应的是上一次mScreenAutoBrightnessAdjustment,这两个
值没有必然联系,仅仅记录了上一次对应的亮度的位置及亮度,从而出现这种现象。
2、自动模式,会出现亮度变化但是进度条不变
---这是由于自动背光传感器及对应的算法会根据环境算出一个亮度mScreenAutoBrightness,从而跟目前亮度比较发生变化就会调节到
mScreenAutoBrightness亮度,但是不会影响mScreenAutoBrightnessAdjustment值,所以进度条不变化,亮度变化。如果这个时候
调节进度条会导致mScreenAutoBrightnessAdjustment变化,从而根据mScreenAutoBrightnessAdjustment重新调节亮度。
问题1、 修改
可以在手动与自动切换时将mScreenAutoBrightnessAdjustment与mScreenBrightness关联起来,做到切换时只是进度条改变,屏膜的亮度不变。
见http://www.ithao123.cn/content-11140655.html
http://blog.csdn.net/kitty_landon/article/details/64128140
- 下拉菜单中自动亮度调节
- 亮度调节及自动亮度开关
- Android7.1 亮度自动调节
- Android中调节屏幕亮度
- android自动调节屏幕亮度自动调节流程解析
- android自动调节屏幕亮度自动调节流程解析
- android自动调节屏幕亮度自动调节流程解析
- 屏幕亮度自动调节的实现
- Android4.4系统亮度的自动调节
- android屏幕亮度自动调节解析
- ubuntu14.04开机自动调节亮度
- Android5.0自动调节亮度黑屏问题
- 修改背光自动调节最低亮度值
- android5.1 自动亮度调节简析
- 设置屏幕亮度默认值为自动调节
- Android 屏幕亮度调节(2.0以后出现亮度自动调节)如何开启、关闭亮度自动调节
- 下拉菜单中自动信息播放
- android 如何设置屏幕亮度默认值为自动调节
- Fragment懒加载数据
- linux app
- 去除<input type='file'>右边路径方法
- Vuex 模块化实现待办事项的状态管理
- Echarts的研究(二)
- 下拉菜单中自动亮度调节
- 文章标题
- 湖南中医药大学2017年集训队第四场选拔赛-Problem F: Virtual Friends
- 关于js打包
- Android Okio
- 音频开发基础知识
- 安卓NDK开发之开发环境搭建以及使用的注意事项
- Java项目在jsp页面中引入jquery框架的步骤
- spring data RedisCacheManager 源码查看与配置解析