Settings中Battery分析

###分析电池状态

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表示它是电池供电,其他常数是不同类型的电源。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值