这里只是简单的介绍下电池图标的显示,所以不是全面的电池分析。想做frameworks电池图标定制的可以参考下。
frameworks/base/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java,这个类就是用来显示电池图标的,它继承ImageView,构造函数中就会去设置图片,也就是电池图标。setImageDrawable(mDrawable) 就是设置的电池图标。
public BatteryMeterView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray atts = context.obtainStyledAttributes(attrs, R.styleable.BatteryMeterView,
defStyle, 0);
final int frameColor = atts.getColor(R.styleable.BatteryMeterView_frameColor,
context.getColor(R.color.batterymeter_frame_color));
mDrawable = new BatteryMeterDrawable(context, new Handler(), frameColor);
atts.recycle();
mSlotBattery = context.getString(
com.android.internal.R.string.status_bar_battery);
setImageDrawable(mDrawable);
}
frameworks/base/packages/SystemUI/src/com/android/systemui/BatteryMeterDrawable.java是一个Drawable,用来画电池图标,它实现了BatteryController.BatteryStateChangeCallback这个接口,用来跟新电池图标,当电池发生变化的时候,就去刷新下Drawable。
@Override
public void onBatteryLevelChanged(int level, boolean pluggedIn, boolean charging) {
mLevel = level;
mPluggedIn = pluggedIn;
postInvalidate();
}
private void postInvalidate() {
mHandler.post(new Runnable() {
@Override
public void run() {
invalidateSelf();
}
});
}
下面看下frameworks/base/packages/SystemUI/src/com/android/systemui/policy/BatteryControllerImpl.java这个类,它实现了接口BatteryController,BatteryControllerImpl它会添加所有BatteryController.BatteryStateChangeCallback
@Override
public void addStateChangedCallback(BatteryController.BatteryStateChangeCallback cb) {
synchronized (mChangeCallbacks) {
mChangeCallbacks.add(cb);
}
if (!mHasReceivedBattery) return;
cb.onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
cb.onPowerSaveChanged(mPowerSave);
}
然后去监听电池变化,当电池发生变化时,就去循环调用所以的BatteryController.BatteryStateChangeCallback。
@Override
public void onReceive(final Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
if (mTestmode && !intent.getBooleanExtra("testmode", false)) return;
mHasReceivedBattery = true;
mLevel = (int)(100f
* intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
/ intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100));
mPluggedIn = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0) != 0;
final int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS,
BatteryManager.BATTERY_STATUS_UNKNOWN);
mCharged = status == BatteryManager.BATTERY_STATUS_FULL;
mCharging = mCharged || status == BatteryManager.BATTERY_STATUS_CHARGING;
fireBatteryLevelChanged();
} else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED)) {
updatePowerSave();
} else if (action.equals(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING)) {
setPowerSave(intent.getBooleanExtra(PowerManager.EXTRA_POWER_SAVE_MODE, false));
} else if (action.equals(ACTION_LEVEL_TEST)) {
mTestmode = true;
mHandler.post(new Runnable() {
int curLevel = 0;
int incr = 1;
int saveLevel = mLevel;
boolean savePlugged = mPluggedIn;
Intent dummy = new Intent(Intent.ACTION_BATTERY_CHANGED);
@Override
public void run() {
if (curLevel < 0) {
mTestmode = false;
dummy.putExtra("level", saveLevel);
dummy.putExtra("plugged", savePlugged);
dummy.putExtra("testmode", false);
} else {
dummy.putExtra("level", curLevel);
dummy.putExtra("plugged", incr > 0 ? BatteryManager.BATTERY_PLUGGED_AC
: 0);
dummy.putExtra("testmode", true);
}
context.sendBroadcast(dummy);
if (!mTestmode) return;
curLevel += incr;
if (curLevel == 100) {
incr *= -1;
}
mHandler.postDelayed(this, 200);
}
});
}
}
protected void fireBatteryLevelChanged() {
synchronized (mChangeCallbacks) {
final int N = mChangeCallbacks.size();
for (int i = 0; i < N; i++) {
mChangeCallbacks.get(i).onBatteryLevelChanged(mLevel, mPluggedIn, mCharging);
}
}
}
所以当电池发生变化的时候,所有实现了BatteryController.BatteryStateChangeCallback回调的地方都会被调用,执行onBatteryLevelChanged和onPowerSaveChanged。