[Android Framework] 8.1 Battery系列(六) 上次充满电计算

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/FightFightFight/article/details/82629645

Settings中获取”上次充满电”时间的代码如下:

packages/apps/Settings/src/com/android/settings/fuelgauge/BatteryUtils.java

public long calculateLastFullChargeTime(BatteryStatsHelper batteryStatsHelper,
        long currentTimeMs) {
    //当前时间 - BatteryStats.getStartClockTime()
    return currentTimeMs - batteryStatsHelper.getStats().getStartClockTime();

}

从这里可以看出,其计算公式可以用如下公式来表示:

上次充满电时间 = 当前系统时间 - BatteryStats.getStartClockTime()
因此,我们在BatteryStatsImpl中就来看看这个方法返回的是什么,如下:

@Override public long getStartClockTime() {
    final long currentTime = System.currentTimeMillis();
    //mStartClockTime距离当前时间超过一年,则重新进行设置
    if (ensureStartClockTime(currentTime)) {
        recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(),
                mClocks.uptimeMillis());
    }
    return mStartClockTime;
}

ensureStartClockTime()方法用来确保mStartClockTime可用,如果距离当前时间超过一年,则重新进行设置,该方法如下:

boolean ensureStartClockTime(final long currentTime) {
    //一年毫秒数
    final long ABOUT_ONE_YEAR = 365*24*60*60*1000L;
    //如果mStartClockTime < (currentTime-ABOUT_ONE_YEAR),说明上次采集电池信息时间超过1年
    if (currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) {

        //重新计算时间,当前时间-开始计时时间
        mStartClockTime = currentTime - (mClocks.elapsedRealtime()-(mRealtimeStart/1000));
        return true;
    }
    return false;
}

从这个方法中可以看出,实际上返回的是mStartClockTime,它是表示BatteryStats开始计时的一个时间值,当系统开机后初始化BatteryStatsService时,该值会被初始化。

综上可知,Android中并没有专门对上次充满电时间进行标记和处理,而是直接使用了BatteryStatsService采集数据开始时间,通过取该值和当前时间的差得到上次充满电时间。

再来看看mStartClockTime在哪里被初始化了:

  • 1.在BatteryStatsImpl构造方法中,调用initTimes()初始化:
void initTimes(long uptime, long realtime) {
    //初始化为当前时间
    mStartClockTime = System.currentTimeMillis();
}
  • 2.从Parcel中初始化:
mStartClockTime = in.readLong();
  • 3.在resetAllStatsLocked()中调用initTimes()
initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000);

当手机充满电后,如果拔掉充电器,则会以setBatteryStateLocked()->setOnBatteryLocked()->resetAllStatsLocked()->initTimes()的调用顺序,将mStartClockTime设置为当前系统时间。从而在Settings中提示上次充满电为0分钟前。

综合上面的分析,可以得出如下几个结论:

  • 1.上次充满电时间实际是当前系统时间和BatteryStatsImpl中开始计时时间点的差值。
  • 2.当由未满到充满后,如果不拔充电线,不会更新这个时间(没有更新mStartClockTime);
  • 3.当拔掉电池后开机,实际读取的是开机到现在的时间(无法读取Parcel中的数据);

如此看来,Google对于Battery这块的统计还不是特别精确。

猜你喜欢

转载自blog.csdn.net/FightFightFight/article/details/82629645