关键字段:
/packages/apps/Settings/res/values/strings.xml
Turn on automatically
对应布局:
/packages/apps/Settings/res/xml/battery_saver_settings.xml
控件:
使用类:
/packages/apps/Settings/src/com/android/settings/fuelgauge/BatterySaverSettings.java
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (mCreated) {
mSwitchBar.show();
return;
}
mCreated = true;
addPreferencesFromResource(R.xml.battery_saver_settings);
mContext = getActivity();
mSwitchBar = ((SettingsActivity) mContext).getSwitchBar();
mSwitch = mSwitchBar.getSwitch();
mSwitchBar.show();
//SettingPref 帮助管理绑定到全局或系统设置的双状态或下拉式首选项, 这里使用下拉选项
mTriggerPref = new SettingPref(SettingPref.TYPE_GLOBAL, KEY_TURN_ON_AUTOMATICALLY,
Global.LOW_POWER_MODE_TRIGGER_LEVEL,
0, /*default*/
getResources().getIntArray(R.array.battery_saver_trigger_values)) { //设置下拉子选项 共3个 (0 5 15)
@Override
protected String getCaption(Resources res, int value) {
if (value > 0 && value < 100) {
return res.getString(R.string.battery_saver_turn_on_automatically_pct,
Utils.formatPercentage(value));
}
return res.getString(R.string.battery_saver_turn_on_automatically_never); //never选项 默认值
}
};
mTriggerPref.init(this); //初始化 mDropDown.setEntries(entries); mDropDown.setEntryValues(values) , 设置点击事件
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
}
/**
type 存放类型 两种: global 和 system
key 控件的key
setting Settings数据存放的键
def DropDownPreference 的默认值
values DropDownPreference 的下拉选项集合
*/
public SettingPref(int type, String key, String setting, int def, int... values) {
mType = type;
mKey = key;
mSetting = setting;
mDefault = def;
mValues = values;
mUri = getUriFor(mType, mSetting);
}
在 mTriggerPref.init(this) 方法中设置了DropDownPreference的点击事件
if (mDropDown != null && p != null) {
p.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
//当下拉选项改变时,将当前选项的值存入Settings数据库其实就是存如入setting_global.xml key值是Global.LOW_POWER_MODE_TRIGGER_LEVEL
return setSetting(context, Integer.parseInt((String) newValue));
}
});
return mDropDown;
}
当Settings数据库中Global.LOW_POWER_MODE_TRIGGER_LEVEL改变时,在PowerManagerService中做了监听:
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
public void systemReady(IAppOpsService appOps) {
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE),
false, mSettingsObserver, UserHandle.USER_ALL);
//注册Global.LOW_POWER_MODE_TRIGGER_LEVEL数据改变监听
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
false, mSettingsObserver, UserHandle.USER_ALL);
}
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();
}
updateSettingsLocked 和 updatePowerStateLocked 方法中做了一些状态的判断,最后都会调用:
再说第二种:
SwitchBar 开关的监听事件:
使用类:
/packages/apps/Settings/src/com/android/settings/fuelgauge/BatterySaverSettings.java
public void onResume(){
mSwitchBar.addOnSwitchChangeListener(this); //注册
}
public void onPause() {
mSwitchBar.removeOnSwitchChangeListener(this); //删除
}
监听事件的处理:
@Override
public void onSwitchChanged(Switch switchView, boolean isChecked) {
mHandler.removeCallbacks(mStartMode);
if (isChecked) {
mHandler.postDelayed(mStartMode, WAIT_FOR_SWITCH_ANIM); //开启省电模式 mStartMode是一个Runnable
} else {
if (DEBUG) Log.d(TAG, "Stopping low power mode from settings");
trySetPowerSaveMode(false);
}
}
最后调用:
private void trySetPowerSaveMode(boolean mode) {
if (!mPowerManager.setPowerSaveMode(mode)) { //PowerManager 实际调用的是PowerManagerService的方法
if (DEBUG) Log.d(TAG, "Setting mode failed, fallback to current value");
mHandler.post(mUpdateSwitch);
}
// TODO: Remove once broadcast is in place.
ConditionManager.get(getContext()).getCondition(BatterySaverCondition.class).refreshState();
}
实际调用: PowerManagerService --> setPowerSaveMode()
@Override // Binder call
public boolean setPowerSaveMode(boolean mode) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.DEVICE_POWER, null);
final long ident = Binder.clearCallingIdentity();
try {
return setLowPowerModeInternal(mode);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
private boolean setLowPowerModeInternal(boolean mode) {
synchronized (mLock) {
if (DEBUG) Slog.d(TAG, "setLowPowerModeInternal " + mode + " mIsPowered=" + mIsPowered);
if (mIsPowered) {
return false;
}
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE, mode ? 1 : 0); //将开关状态存入数据库
mLowPowerModeSetting = mode;
if (mAutoLowPowerModeConfigured && mBatteryLevelLow) {
if (mode && mAutoLowPowerModeSnoozing) {
if (DEBUG_SPEW) {
Slog.d(TAG, "setLowPowerModeInternal: clearing low power mode snooze");
}
mAutoLowPowerModeSnoozing = false;
} else if (!mode && !mAutoLowPowerModeSnoozing) {
if (DEBUG_SPEW) {
Slog.d(TAG, "setLowPowerModeInternal: snoozing low power mode");
}
mAutoLowPowerModeSnoozing = true;
}
}
updateLowPowerModeLocked(); //更新状态
return true;
}
}
最后说一下updateLowPowerModeLocked()方法:
//此方法返回true,表示省电模式设置成功
private void updateLowPowerModeLocked() {
if ((mIsPowered || !mBatteryLevelLow && !mBootCompleted) && mLowPowerModeSetting) {
if (DEBUG_SPEW) {
Slog.d(TAG, "updateLowPowerModeLocked: powered or booting with sufficient battery,"
+ " turning setting off");
}
// Turn setting off if powered
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.LOW_POWER_MODE, 0);
mLowPowerModeSetting = false;
}
/** mIsPowered 变量表示充电状态,true表示正在充电(已接入电源),否则为false
mLowPowerModeSetting 变量(表示设置低电模式的当前状态;从系统设置中获取的值,即数据库字段“low_power”的值)
mAutoLowPowerModeConfigured 自动开启省电模式的当前状态,即数据库字段“low_power_trigger_level”是否为0的值;不为0时表示打开了自动开
启功能,该变量为true
mAutoLowPowerModeSnoozing 当电量低并且允许自动设置省电模式时,如果此时省电模式是开启的,就要设置mAutoLowPowerModeSnoozing的值为
false;如果省电模式是关闭的,就要设置mAutoLowPowerModeSnoozing的值为true。就是要求
mAutoLowPowerModeSnoozing变量与省电模式的逻辑保持一致。
mBatteryLevelLow 如果电池电量低为true,否则为false
mBatteryLevelLowValue 当前自动开启省电模式的电量百分比,就是前面DropDownPreference中设置的values值,0(never) 5% 15%
*/
final boolean autoLowPowerModeEnabled = !mIsPowered && mAutoLowPowerModeConfigured
&& !mAutoLowPowerModeSnoozing && mBatteryLevelLow &&
(mBatteryManagerInternal.getBatteryLevel() <= mBatteryLevelLowValue);
final boolean lowPowerModeEnabled = mLowPowerModeSetting || autoLowPowerModeEnabled;
if (mLowPowerModeEnabled != lowPowerModeEnabled) {
mLowPowerModeEnabled = lowPowerModeEnabled;
powerHintInternal(POWER_HINT_LOW_POWER, lowPowerModeEnabled ? 1 : 0);
postAfterBootCompleted(new Runnable() {
@Override
public void run() {
//发送处理广播 ACTION_POWER_SAVE_MODE_CHANGING
Intent intent = new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)
.putExtra(PowerManager.EXTRA_POWER_SAVE_MODE, mLowPowerModeEnabled)
.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
mContext.sendBroadcast(intent);
ArrayList listeners;
synchronized (mLock) {
listeners = new ArrayList(
mLowPowerModeListeners);
}
for (int i=0; i
"ACTION_POWER_SAVE_MODE_CHANGING" 广播的接收类: