版权声明:本文为博主原创文章,未经博主允许不得转载。 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这块的统计还不是特别精确。