Android 4.4 电池电量显示相关。

这篇博客主要探讨了在Android 4.4中,当电池温度过高或OVP状态时如何在用户界面显示信息。分析了BatteryService.java的相关源码,包括低电量提示对话框的实现、电池图标更新、低电量关机的处理。同时,讲解了如何在App中获取电池信息,并简要提及了pm.reboot和pm.shutdown的后续流程、LED灯显示的LightService以及电池电量广播的传递过程。
摘要由CSDN通过智能技术生成

最近遇到个新的需求,当电池温度过高以及OVP状态的时候,在用户界面提示信息。

电池电源信息相关在Framework层/

与电池电量信息等相关类:

1.BatteryManager.java

2.BatteryProperties.java

3.BatteryStates.java

4.PowerUI.java

5.LightService.java

6.PowerManager.java

7.BatteryService.java


这里先分析BatteryService.java。

源码路径: 

***/framework/base/services/java/com/android/server/BatteryService.java

BatteryService.java代码,必要的地方做了处理。

/*
 * Copyright (C) 2006 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server;

import android.os.BatteryStats;
import com.android.internal.app.IBatteryStats;
import com.android.server.am.BatteryStatsService;

import android.app.ActivityManagerNative;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.BatteryManager;
import android.os.BatteryProperties;
import android.os.Binder;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBatteryPropertiesListener;
import android.os.IBatteryPropertiesRegistrar;
import android.os.IBinder;
import android.os.DropBoxManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UEventObserver;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.EventLog;
import android.util.Slog;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;


/**
 * <p>BatteryService monitors the charging status, and charge level of the device
 * battery.  When these values change this service broadcasts the new values
 * to all {@link android.content.BroadcastReceiver IntentReceivers} that are
 * watching the {@link android.content.Intent#ACTION_BATTERY_CHANGED
 * BATTERY_CHANGED} action.</p>
 * <p>The new values are stored in the Intent data and can be retrieved by
 * calling {@link android.content.Intent#getExtra Intent.getExtra} with the
 * following keys:</p>
 * <p>"scale" - int, the maximum value for the charge level</p>
 * <p>"level" - int, charge level, from 0 through "scale" inclusive</p>
 * <p>"status" - String, the current charging status.<br />
 * <p>"health" - String, the current battery health.<br />
 * <p>"present" - boolean, true if the battery is present<br />
 * <p>"icon-small" - int, suggested small icon to use for this state</p>
 * <p>"plugged" - int, 0 if the device is not plugged in; 1 if plugged
 * into an AC power adapter; 2 if plugged in via USB.</p>
 * <p>"voltage" - int, current battery voltage in millivolts</p>
 * <p>"temperature" - int, current battery temperature in tenths of
 * a degree Centigrade</p>
 * <p>"technology" - String, the type of battery installed, e.g. "Li-ion"</p>
 *
 * <p>
 * The battery service may be called by the power manager while holding its locks so
 * we take care to post all outcalls into the activity manager to a handler.
 *
 * FIXME: Ideally the power manager would perform all of its calls into the battery
 * service asynchronously itself.
 * </p>
 */
public final class BatteryService extends Binder {
    private static final String TAG = BatteryService.class.getSimpleName();

    private static final boolean DEBUG = false;

    //电量百分比显示
    private static final int BATTERY_SCALE = 100;    // battery capacity is a percentage

    // Used locally for determining when to make a last ditch effort to log
    // discharge stats before the device dies.
    private int mCriticalBatteryLevel;

    private static final int DUMP_MAX_LENGTH = 24 * 1024;
    private static final String[] DUMPSYS_ARGS = new String[] { "--checkin", "--unplugged" };

    private static final String DUMPSYS_DATA_PATH = "/data/system/";

    // This should probably be exposed in the API, though it's not critical
    //没有充电状态则显示0
    private static final int BATTERY_PLUGGED_NONE = 0;

    private final Context mContext;
    private final IBatteryStats mBatteryStats;
    private final Handler mHandler;

    private final Object mLock = new Object();

    private BatteryProperties mBatteryProps;
    private boolean mBatteryLevelCritical;
    private int mLastBatteryStatus;
    private int mLastBatteryHealth;
    private boolean mLastBatteryPresent;
    private int mLastBatteryLevel;
    private int mLastBatteryVoltage;
    private int mLastBatteryTemperature;
    private boolean mLastBatteryLevelCritical;

    private int mInvalidCharger;
    private int mLastInvalidCharger;

    private int mLowBatteryWarningLevel;
    private int mLowBatteryCloseWarningLevel;
    private int mShutdownBatteryTemperature;

    private int mPlugType;
    private int mLastPlugType = -1; // Extra state so we can detect first run

    private long mDischargeStartTime;
    private int mDischargeStartLevel;

    private boolean mUpdatesStopped;

    private Led mLed;

    private boolean mSentLowBatteryBroadcast = false;

    private BatteryListener mBatteryPropertiesListener;
    private IBatteryPropertiesRegistrar mBatteryPropertiesRegistrar;

    public BatteryService(Context context, LightsService lights) {
        mContext = context;
        mHandler = new Handler(true /*async*/);
        mLed = new Led(context, lights);
        mBatteryStats = BatteryStatsService.getService();

        mCriticalBatteryLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_criticalBatteryWarningLevel);
        //res/res/values/config.xml:547:    <integer name="config_lowBatteryWarningLevel">15</integer>
        mLowBatteryWarningLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lowBatteryWarningLevel);
        //res/res/values/config.xml:550:    <integer name="config_lowBatteryCloseWarningLevel">20</integer> 接近警戒值。
        mLowBatteryCloseWarningLevel = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_lowBatteryCloseWarningLevel);
        //res/res/values/config.xml:544:    <integer name="config_shutdownBatteryTemperature">680</integer>//68度?为什么?
        mShutdownBatteryTemperature = mContext.getResources().getInteger(
                com.android.internal.R.integer.config_shutdownBatteryTemperature);

        // watch for invalid charger messages if the invalid_charger switch exists
        if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {
            mInvalidChargerObserver.startObserving(
                    "DEVPATH=/devices/virtual/switch/invalid_charger");
        }

        //注册监听。实时更新电池电量信息,底层传递上来的电池信息有变化时,则上层会做响应的处理。
        //从这里可以看出回调接口中调用的update()方法应该是比较频繁的。
        mBatteryPropertiesListener = new BatteryListener();

        IBinder b = ServiceManager.getService("batterypropreg");
        mBatteryPropertiesRegistrar = IBatteryPropertiesRegistrar.Stub.asInterface(b);

        try {
            mBatteryPropertiesRegistrar.registerListener(mBatteryPropertiesListener);
        } catch (RemoteException e) {
            // Should never happen.
        }
    }

    //该方法在SystemServer.java中调用。开机过程。
    void systemReady() {
        // check our power situation now that it is safe to display the shutdown dialog.
        synchronized (mLock) {
            shutdownIfNoPowerLocked();
            shutdownIfOverTempLocked();
        }
    }

    /**
     * Returns true if the device is plugged into any of the specified plug types.
     */
    public boolean isPowered(int plugTypeSet) {
        synchronized (mLock) {
            return isPoweredLocked(plugTypeSet);
        }
    }

    //当前手机是否正在充电。这里面查查&的相关用法。
    private boolean isPoweredLocked(int plugTypeSet) {
        // assume we are powered if battery state is unknown so
        // the "stay on while plugged in" option will work.
        if (mBatteryProps.batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
            return true;
        }
        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_AC) != 0 && mBatteryProps.chargerAcOnline) {
            return true;
        }
        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_USB) != 0 && mBatteryProps.chargerUsbOnline) {
            return true;
        }
        if ((plugTypeSet & BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0 && mBatteryProps.chargerWirelessOnline) {
            return true;
        }
        return false;
    }

    /**
     * Returns the current plug type.
     */
    public int getPlugType() {
        synchronized (mLock) {
            return mPlugType;
        }
    }

    /**
     * Returns battery level as a percentage.
     */
    public int getBatteryLevel() {
        synchronized (mLock) {
            return mBatteryProps.batteryLevel;
        }
    }

    /**
     * Returns true if battery level is below the first warning threshold.
     */
    public boolean isBatteryLow() {
        synchronized (mLock) {
            return mBatteryProps.batteryPresent && mBatteryProps.batteryLevel <= mLowBatteryWarningLevel;
        }
    }

    /**
     * Returns a non-zero value if an  unsupported charger is attached.
     */
    public int getInvalidCharger() {
        synchronized (mLock) {
            return mInvalidCharger;
        }
    }

    private void shutdownIfNoPowerLocked() {
        // shut down gracefully if our battery is critically low and we are not powered.
        // wait until the system 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值