###分析电池状态
RG170:/ $ dumpsys battery
dumpsys battery
Current Battery Service state:
AC powered: false //充电器充电
USB powered: true
Wireless powered: false //无线充电
Max charging current: 5000000 //最大充电电流
Max charging voltage: 500000 //最大充电电压
Charge counter: 88
status: 2
health: 2
present: true
level: 92 //电量
scale: 100
voltage: 4057
temperature: 340 //温度
technology: Li-ion
如上主要关注2个字段:
USB powered : true
那么闪电图标应该会出现
status: 2
那么充电动画应该启动了
同时我们还可以通过shell指令的方式启动充电图标和充电动画
dumpsys battery set usb 1
闪电图标应该会出现
dumpsys battery set status 2
充电动画应该启动了
dumpsys battery set usb 0
闪电图标消失
dumpsys battery set status 4
充电动画消失
界面分析
Settings中的Battery主界面是
vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/fuelgauge/PowerUsageSummary.java
布局界面是
vendor/mediatek/proprietary/packages/apps/MtkSettings/res/xml/power_usage_summary.xml
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:title="@string/power_usage_summary_title"
settings:keywords="@string/keywords_battery">
<com.android.settings.applications.LayoutPreference
android:key="battery_header"
android:selectable="true"
android:layout="@layout/battery_header"/>
<Preference
android:key="high_usage"
android:icon="@drawable/ic_battery_alert_24dp"
android:title="@string/power_high_usage_title"/>
<PreferenceCategory
android:key="device_usage_list">
<com.android.settings.fuelgauge.PowerGaugePreference
android:key="last_full_charge"
android:title="@string/battery_last_full_charge" //Last full charge
android:selectable="false"/>
<com.android.settings.fuelgauge.PowerGaugePreference
android:key="screen_usage"
android:title="@string/device_screen_usage" //Screen usage since full charge
android:selectable="false"/>
</PreferenceCategory>
<PreferenceCategory
android:key="power_management" //Power management
android:title="@string/battery_power_management">
<!-- MTK background power saving -->
<SwitchPreference
android:key="background_power_saving"
android:title="@string/bg_power_saving_title"/>
<com.android.settings.widget.MasterSwitchPreference
android:fragment="com.android.settings.fuelgauge.BatterySaverSettings"
android:key="battery_saver_summary"
android:title="@string/battery_saver"/>
<SwitchPreference
android:key="battery_percentage"
android:title="@string/battery_percentage"
android:summary="@string/battery_percentage_description"/>
<!-- Cross-listed item, if you change this, also change it in display_settings.xml -->
<SwitchPreference
android:key="auto_brightness_battery"
android:title="@string/auto_brightness_title"
android:summary="@string/auto_brightness_summary"
settings:keywords="@string/keywords_display_auto_brightness"/>
<!-- Cross-listed item, if you change this, also change it in display_settings.xml -->
<com.android.settings.TimeoutListPreference
android:key="screen_timeout_battery"
android:title="@string/screen_timeout"
android:summary="@string/screen_timeout_summary"
android:entries="@array/screen_timeout_entries"
android:entryValues="@array/screen_timeout_values"/>
<!-- Cross-listed item, if you change this, also change it in display_settings.xml -->
<Preference
android:key="ambient_display_battery"
android:title="@string/ambient_display_screen_title"
android:fragment="com.android.settings.display.AmbientDisplaySettings" />
</PreferenceCategory>
<PreferenceCategory
android:key="app_list"
android:title="@string/power_usage_list_summary"/>
</PreferenceScreen>
从中可以看出电池的布局是在battery_header.xml中
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/battery_entity_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="horizontal"
android:paddingTop="24dp"
android:paddingBottom="24dp"
android:background="@drawable/selectable_card_grey"
style="@style/EntityHeader">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="56dp"
android:orientation="vertical">
<TextView
android:id="@+id/battery_percent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:fontFamily="@*android:string/config_headlineFontFamily"
android:textAppearance="@android:style/TextAppearance.Material.Display1"/>
<TextView
android:id="@+id/summary1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:minLines="2"
android:textAppearance="@android:style/TextAppearance.Material.Small"/>
<TextView
android:id="@+id/summary2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.Material.Small"/>
</LinearLayout>
<com.android.settings.fuelgauge.BatteryMeterView
android:id="@+id/battery_header_icon"
android:layout_width="@dimen/battery_meter_width"
android:layout_height="@dimen/battery_meter_height"
android:layout_marginEnd="16dp"/>
</LinearLayout>
可以看出电池图标是由BatteryMeterView绘制而成。
vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/fuelgauge/BatteryMeterView.java
public class BatteryMeterView extends ImageView {
@VisibleForTesting
BatteryMeterDrawable mDrawable;
@VisibleForTesting
ColorFilter mErrorColorFilter;
@VisibleForTesting
ColorFilter mAccentColorFilter;
public BatteryMeterView(Context context) {
this(context, null, 0);
}
public BatteryMeterView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public BatteryMeterView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final int frameColor = context.getColor(R.color.meter_background_color);
mAccentColorFilter = new PorterDuffColorFilter(
Utils.getColorAttr(context, android.R.attr.colorAccent), PorterDuff.Mode.SRC_IN);
mErrorColorFilter = new PorterDuffColorFilter(
context.getColor(R.color.battery_icon_color_error), PorterDuff.Mode.SRC_IN);
mDrawable = new BatteryMeterDrawable(context, frameColor);
mDrawable.setShowPercent(false);
mDrawable.setBatteryColorFilter(mAccentColorFilter);
mDrawable.setWarningColorFilter(
new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN));
setImageDrawable(mDrawable); //电池图标
}
//显示电量等级
public void setBatteryLevel(int level) {
mDrawable.setBatteryLevel(level);
if (level < mDrawable.getCriticalLevel()) {
mDrawable.setBatteryColorFilter(mErrorColorFilter);
} else {
mDrawable.setBatteryColorFilter(mAccentColorFilter);
}
}
public int getBatteryLevel() {
return mDrawable.getBatteryLevel();
}
//是否充电状态,充电状态图标会有闪电的标记
public void setCharging(boolean charging) {
//changed by wangjin in 2019/09/11
if(getBatteryLevel() == 100) {
mDrawable.setCharging(false);
} else{
mDrawable.setCharging(charging);
}
postInvalidate(); //刷新视图
}
public boolean getCharging() {
return mDrawable.getCharging();
}
public static class BatteryMeterDrawable extends BatteryMeterDrawableBase {
private final int mIntrinsicWidth;
private final int mIntrinsicHeight;
public BatteryMeterDrawable(Context context, int frameColor) {
super(context, frameColor);
mIntrinsicWidth = context.getResources()
.getDimensionPixelSize(R.dimen.battery_meter_width);
mIntrinsicHeight = context.getResources()
.getDimensionPixelSize(R.dimen.battery_meter_height);
}
@Override
public int getIntrinsicWidth() {
return mIntrinsicWidth;
}
@Override
public int getIntrinsicHeight() {
return mIntrinsicHeight;
}
public void setWarningColorFilter(@Nullable ColorFilter colorFilter) {
mWarningTextPaint.setColorFilter(colorFilter);
}
public void setBatteryColorFilter(@Nullable ColorFilter colorFilter) {
mFramePaint.setColorFilter(colorFilter);
mBatteryPaint.setColorFilter(colorFilter);
mBoltPaint.setColorFilter(colorFilter);
}
}
}
从代码中可以看到是否显示充电状态是setCharging设置的,这个值是从PowerUsageSummary.java 的LoaderManager.LoaderCallbacks<List> mBatteryInfoDebugLoaderCallbacks中传进去的
BatteryInfo oldInfo = batteryInfos.get(0);
BatteryInfo newInfo = batteryInfos.get(1);
percentRemaining.setText(Utils.formatPercentage(oldInfo.batteryLevel));
// set the text to the old estimate (copied from battery info). Note that this
// can sometimes say 0 time remaining because battery stats requires the phone
// be unplugged for a period of time before being willing ot make an estimate.
summary1.setText(mPowerFeatureProvider.getOldEstimateDebugString(
Formatter.formatShortElapsedTime(getContext(),
BatteryUtils.convertUsToMs(oldInfo.remainingTimeUs))));
// for this one we can just set the string directly
summary2.setText(mPowerFeatureProvider.getEnhancedEstimateDebugString(
Formatter.formatShortElapsedTime(getContext(),
BatteryUtils.convertUsToMs(newInfo.remainingTimeUs))));
batteryView.setBatteryLevel(oldInfo.batteryLevel);
batteryView.setCharging(!oldInfo.discharging); //是否在充电
是否在充电是由BatteryInfo.discharging值来决定的。
Intent batteryBroadcast = context.registerReceiver(null,
new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); //通过ACTION_BATTERY_CHANGED广播接收到电池变化
// 0 means we are discharging, anything else means charging
boolean discharging =
batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) == 0; //EXTRA_PLUGGED 整数,表示设备是否插入电源; 0表示它是电池供电,其他常数是不同类型的电源。