Android51 电池充电剩余时间计算.docx
- 文档编号:25414174
- 上传时间:2023-06-08
- 格式:DOCX
- 页数:23
- 大小:21.98KB
Android51 电池充电剩余时间计算.docx
《Android51 电池充电剩余时间计算.docx》由会员分享,可在线阅读,更多相关《Android51 电池充电剩余时间计算.docx(23页珍藏版)》请在冰豆网上搜索。
Android51电池充电剩余时间计算
Android5.1电池充电剩余时间计算
android5.1手机在充电的时候,并且在锁屏界面的时候会显示还剩多少时间电池充满电。
我们就这个机制进行下深入分析:
首先对电池的变化都会监听BatteryService发出的Intent.ACTION_BATTERY_CHANGED广播,因此在framework目录下全局搜索,结果发现在./base/packages/Keyguard/src/com/Android/keyguard/KeyguardUpdateMonitor.Java这个目录下,也就是keyguard中有对这个广播的监控
在KeyguardUpdateMonitor.java这个文件中
[java]viewplaincopy
privatefinalBroadcastReceivermBroadcastReceiver=newBroadcastReceiver(){
publicvoidonReceive(Contextcontext,Intentintent){
finalStringaction=intent.getAction();
if(DEBUG)Log.d(TAG,"receivedbroadcast"+action);
if(Intent.ACTION_TIME_TICK.equals(action)
||Intent.ACTION_TIME_CHANGED.equals(action)
||Intent.ACTION_TIMEZONE_CHANGED.equals(action)){
mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
}elseif(Intent.ACTION_BATTERY_CHANGED.equals(action)){//监听电池变化的广播
finalintstatus=intent.getIntExtra(EXTRA_STATUS,BATTERY_STATUS_UNKNOWN);
finalintplugged=intent.getIntExtra(EXTRA_PLUGGED,0);
finalintlevel=intent.getIntExtra(EXTRA_LEVEL,0);
finalinthealth=intent.getIntExtra(EXTRA_HEALTH,BATTERY_HEALTH_UNKNOWN);
finalMessagemsg=mHandler.obtainMessage(
MSG_BATTERY_UPDATE,newBatteryStatus(status,level,plugged,health));
mHandler.sendMessage(msg);//发消息
}
接下来我们搜索下MSG_BATTERY_UPDATE这个消息,
[java]viewplaincopy
privatevoidhandleBatteryUpdate(BatteryStatusstatus){
if(DEBUG)Log.d(TAG,"handleBatteryUpdate");
finalbooleanbatteryUpdateInteresting=isBatteryUpdateInteresting(mBatteryStatus,status);
mBatteryStatus=status;
if(batteryUpdateInteresting){
for(inti=0;i KeyguardUpdateMonitorCallbackcb=mCallbacks.get(i).get(); if(cb! =null){ cb.onRefreshBatteryInfo(status);//接下来我们就搜一下谁定义了onRefreshBatteryInfo这个接口 } } } } 结果在KeyguardIndicationController.java这个文件中 [java]viewplaincopy KeyguardUpdateMonitorCallbackmUpdateMonitor=newKeyguardUpdateMonitorCallback(){ @Override publicvoidonRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatusstatus){ booleanisChargingOrFull=status.status==BatteryManager.BATTERY_STATUS_CHARGING ||status.status==BatteryManager.BATTERY_STATUS_FULL; mPowerPluggedIn=status.isPluggedIn()&&isChargingOrFull; mPowerCharged=status.isCharged(); updateIndication(); } }; 接下来看下updateIndication [java]viewplaincopy privatevoidupdateIndication(){ if(mVisible){ mTextView.switchIndication(computeIndication()); } } 接下来就是看下如何计算电池剩余时间的 [java]viewplaincopy privateStringcomputeIndication(){ if(! TextUtils.isEmpty(mTransientIndication)){ returnmTransientIndication; } if(mPowerPluggedIn){//当在充电时 returncomputePowerIndication(); } returnmRestingIndication; } privateStringcomputePowerIndication(){ if(mPowerCharged){ returnmContext.getResources().getString(R.string.keyguard_charged); } //Tryfetchingchargingtimefrombatterystats. try{//剩余时间通过BatteryStatsService获取 longchargingTimeRemaining=mBatteryIputeChargeTimeRemaining(); if(chargingTimeRemaining>0){ StringchargingTimeFormatted=Formatter.formatShortElapsedTimeRoundingUpToMinutes( mContext,chargingTimeRemaining); returnmContext.getResources().getString( R.string.keyguard_indication_charging_time,chargingTimeFormatted); } }catch(RemoteExceptione){ Log.e(TAG,"ErrorcallingIBatteryStats: ",e); } //Fallbacktosimplecharginglabel. returnmContext.getResources().getString(R.string.keyguard_plugged_in); } 下面是mBatteryInfo的赋值 [java]viewplaincopy mBatteryInfo=IBatteryStats.Stub.asInterface( ServiceManager.getService(BatteryStats.SERVICE_NAME)); 然后看BatteryStatsService中的computeChargeTimeRemaining代码 [java]viewplaincopy publiclongcomputeChargeTimeRemaining(){ synchronized(mStats){ longtime=mSputeChargeTimeRemaining(SystemClock.elapsedRealtime()); returntime>=0? (time/1000): time; } } 其中mStats是在BatteryStatsService构造的时候新建的: [java]viewplaincopy BatteryStatsService(FilesystemDir,Handlerhandler){ mStats=newBatteryStatsImpl(systemDir,handler); } 最后我们就来分析下BatteryStatsImpl中的computeChargeTimeRemaining函数: [java]viewplaincopy @Override publiclongcomputeChargeTimeRemaining(longcurTime){ if(mOnBattery){//当处于用电池的状态直接退出 //Notyetworking. Slog.e(TAG,"mOnBattery"); return-1; } /*Broken intcurLevel=mCurrentBatteryLevel; intplugLevel=mDischargePlugLevel; if(plugLevel<0||curLevel<(plugLevel+1)){ return-1; } longduration=computeBatteryRealtime(curTime,STATS_SINCE_UNPLUGGED); if(duration<1000*1000){ return-1; } longusPerLevel=duration/(curLevel-plugLevel); returnusPerLevel*(100-curLevel); */ if(mNumChargeStepDurations<1){ Slog.e(TAG,"mNumChargeStepDurations"); return-1; }//mChargeStepDurations是一个数组,保存着每一个level对应的时间,而mNumChargeStepDurations是现在总的一个level longmsPerLevel=computeTimePerLevel(mChargeStepDurations,mNumChargeStepDurations); if(msPerLevel<=0){ Slog.e(TAG,"msPerLevel"); return-1; } Slog.e(TAG,"returntimeremianing"+(msPerLevel*(100-mCurrentBatteryLevel))*1000); return(msPerLevel*(100-mCurrentBatteryLevel))*1000;//因此msperlevel代表每一个level需要多少时间,100-mCurrentBatteryLevel代表需要充电的电量 } 再来看看 [java]viewplaincopy privatelongcomputeTimePerLevel(long[]steps,intnumSteps){ //Fornowwe'lldoasimpleaverageacrossallsteps. if(numSteps<=0){ return-1; } longtotal=0; for(inti=0;i total+=steps[i]&STEP_LEVEL_TIME_MASK;//高位保存的别的信息,需要将它去除 } returntotal/numSteps;//所有的level的时间和除以总的level,就是每个level的平均时间 但是现在的关键mChargeStepDurations,和mNumChargeStepDurations这两个成员变量如何获得。 当在BatteryService更新电池信息的时候,如下: 会调用BatteryStatsService的setBatteryState函数 [java]viewplaincopy try{ mBatteryStats.setBatteryState(mBatteryProps.batteryStatus,mBatteryProps.batteryHealth, mPlugType,mBatteryProps.batteryLevel,mBatteryProps.batteryTemperature, mBatteryProps.batteryVoltage); }catch(RemoteExceptione){ //Shouldneverhappen. } 而在BatteryStatsService的setBatteryState函数中: 检查下权限然后调用了BatteryStatsImpl的setBatteryState函数 [java]viewplaincopy publicvoidsetBatteryState(intstatus,inthealth,intplugType,intlevel, inttemp,intvolt){ enforceCallingPermission(); mStats.setBatteryState(status,health,plugType,level,temp,volt); } 接下来我们来看下核心函数: [java]viewplaincopy publicvoidsetBatteryState(intstatus,inthealth,intplugType,intlevel, inttemp,intvolt){ synchronized(this){ finalbooleanonBattery=plugType==BATTERY_PLUGGED_NONE; finallonguptime=SystemClock.uptimeMillis(); finallongelapsedRealtime=SystemClock.elapsedRealtime(); intoldStatus=mHistoryCur.batteryStatus; if(! mHaveBatteryLevel){ mHaveBatteryLevel=true; //Westartoutassumingthatthedeviceispluggedin(not //onbattery).Ifourfirstreportisnowthatweareindeed //pluggedin,thentwiddleourstatetocorrectlyreflectthat //sincewewon'tbegoingthroughthefullsetOnBattery(). if(onBattery==mOnBattery){ if(onBattery){ mHistoryCur.states&=~HistoryItem.STATE_BATTERY_PLUGGED_FLAG; }else{ mHistoryCur.states|=HistoryItem.STATE_BATTERY_PLUGGED_FLAG; } } oldStatus=status; } if(onBattery){ mDischargeCurrentLevel=level; if(! mRecordingHistory){ mRecordingHistory=true; startRecordingHistory(elapsedRealtime,uptime,true); } }elseif(level<96){ if(! mRecordingHistory){ mRecordingHistory=true; startRecordingHistory(elapsedRealtime,uptime,true); } } mCurrentBatteryLevel=level; if(mDischargePlugLevel<0){ mDischargePlugLevel=level; } if(onBattery! =mOnBattery){ mHistoryCur.batteryLevel=(byte)level; mHistoryCur.batteryStatus=(byte)status; mHistoryCur.batteryHealth=(byte)health; mHistoryCur.batteryPlugType=(byte)plugType; mHistoryCur.batteryTemperature=(short)temp; mHistoryCur.batteryVoltage=(char)volt; setOnBatteryLocked(elapsedRealtime,uptime,onBattery,oldStatus,level); }else{ booleanchanged=false; if(mHistoryCur.batteryLevel! =level){ mHistoryCur.batteryLevel=(byte)level; changed=true; } if(mHistoryCur.batteryStatus! =status){ mHistoryCur.batteryStatus=(byte)status; changed=true; } if(mHistoryCur.batteryHealth! =health){ mHistoryCur.batteryHealth=(byte)health; changed=true; } if(mHistoryCur.batteryPlugType! =plugType){ mHistoryCur.batteryPlugType=(byte)plugType; changed=true; } if(temp>=(mHistoryCur.batteryTemperature+10) ||temp<=(mHistoryCur.batteryTemperature-10)){ mHistoryCur.batteryTemperature=(short)temp; changed=true; } if(volt>(mHistoryCur.batteryVoltage+20) ||volt<(mHistoryCur.batteryVoltage-20)){ mHistoryCur.batteryVoltage=(char)volt; changed=true; } if(changed){ addHistoryRecordLocked(elapsedRealtime,uptime); } longmodeBits=(((long)mInitStepMode)< |(((long)mModStepMode)< |(((long)(level&0xff))< if(onBattery){ if(mLastDischargeStepLevel! =level&&mMinDischargeStepLevel>level){ mNumDischargeStepDurations=addLevelSteps(mDischargeStepDurations, mNumDischargeStepDurations,mLastDischargeStepTime, mLastDischargeStepLevel-level,modeBits,elapsedRealtime); mLastDischargeStepLevel=level; mMinDischargeStepLevel=level; mLastDischargeStepTime=elapsedRealtime; mInitStepMode=mCurStepMode; mModStepMode=0; } }else{ if(mLastChargeStepLevel!
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Android51 电池充电剩余时间计算 电池 充电 剩余时间 计算