Android51 電池充電剩余時(shí)間計(jì)算_第1頁
Android51 電池充電剩余時(shí)間計(jì)算_第2頁
Android51 電池充電剩余時(shí)間計(jì)算_第3頁
Android51 電池充電剩余時(shí)間計(jì)算_第4頁
Android51 電池充電剩余時(shí)間計(jì)算_第5頁
已閱讀5頁,還剩7頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

本文格式為Word版,下載可任意編輯——Android51電池充電剩余時(shí)間計(jì)算Android5.1電池充電剩余時(shí)間計(jì)算

android5.1手機(jī)在充電的時(shí)候,并且在鎖屏界面的時(shí)候會(huì)顯示還剩多少時(shí)間電池充滿電。我們就這個(gè)機(jī)制進(jìn)行下深入分析:

首先對(duì)電池的變化都會(huì)監(jiān)聽BatteryService發(fā)出的Intent.ACTION_BATTERY_CHANGED廣播,因此在framework目錄下全局探尋,結(jié)果發(fā)現(xiàn)在./base/packages/Keyguard/src/com/Android/keyguard/KeyguardUpdateMonitor.Java這個(gè)目錄下,也就是keyguard中有對(duì)這個(gè)廣播的監(jiān)控在KeyguardUpdateMonitor.java這個(gè)文件中[java]viewplaincopy

privatefinalBroadcastReceivermBroadcastReceiver=newBroadcastReceiver(){

publicvoidonReceive(Contextcontext,Intentintent){finalStringaction=intent.getAction();

if(DEBUG)Log.d(TAG,\

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)){//監(jiān)聽電池變化的廣播

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);//發(fā)消息}

接下來我們探尋下MSG_BATTERY_UPDATE這個(gè)消息,[java]viewplaincopy

privatevoidhandleBatteryUpdate(BatteryStatusstatus){if(DEBUG)Log.d(TAG,\

finalbooleanbatteryUpdateInteresting=isBatteryUpdateInteresting(mBatteryStatus,status);mBatteryStatus=status;

if(batteryUpdateInteresting){

for(inti=0;i0){StringchargingTimeFormatted=Formatter.formatShortElapsedTimeRoundingUpToMinutes(mContext,chargingTimeRemaining);returnmContext.getResources().getString(R.string.keyguard_indication_charging_time,chargingTimeFormatted);}

}catch(RemoteExceptione){

Log.e(TAG,\}

//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構(gòu)造的時(shí)候新建的:[java]viewplaincopy

BatteryStatsService(FilesystemDir,Handlerhandler){mStats=newBatteryStatsImpl(systemDir,handler);}

最終我們就來分析下BatteryStatsImpl中的computeChargeTimeRemaining函數(shù):[java]viewplaincopy@Override

publiclongcomputeChargeTimeRemaining(longcurTime){if(mOnBattery){//當(dāng)處于用電池的狀態(tài)直接退出//Notyetworking.

Slog.e(TAG,\return-1;}

/*Broken

intcurLevel=mCurrentBatteryLevel;intplugLevel=mDischargePlugLevel;

if(plugLevel

}

if(onBattery){

mDischargeCurrentLevel=level;if(!mRecordingHistory){mRecordingHistory=true;startRecordingHistory(elapsedRealtime,uptime,true);}

}elseif(level=(mHistoryCur.batteryTemperature+10)||temp(mHistoryCur.batteryVoltage+20)||volt=0//這次充電用了多少時(shí)間for(inti=0;iSTEP_LEVEL_TIME_MASK){thisDuration=STEP_LEVEL_TIME_MASK;}

steps[0]=thisDuration|modeBits;//這個(gè)是將一些模式信息存在高位,與我們不是很相關(guān)}

stepCount+=numStepLevels;if(stepCount>steps.length){stepCount=steps.length;}}

returnstepCount;}

有可能比較難理解,我們直接舉個(gè)例子

譬如我們充了5格電,用了30s,當(dāng)i=0,thisDuration=30/5=6,step[0]=6;當(dāng)i=1,thisDuration=24/(5-1)=6;然后將整個(gè)數(shù)組往后延,這樣每次保存的值都會(huì)往后延。最前面是最新的電池充電時(shí)間,mNumChargeStepDurations是所有的level,哪怕再次調(diào)用這個(gè)函數(shù),數(shù)組還是往后延,該保存的值都保存了。

因此計(jì)算每格電池的平均充電時(shí)間,每格電池所花的時(shí)間之和除以就是所有的level即mNumChargeStepDurations。就是平均每格電池的充電時(shí)間。

至此BatteryStatsImpl中計(jì)算充電電池還剩多少時(shí)間我們已經(jīng)分析完了。

接下來我們?cè)賮砜聪耚這個(gè)文件

先來看它的讀?。簳?huì)在readSummaryFromParcel函數(shù)中,將成員變量都讀出來。

[java]viewplaincopy

publicvoidreadLocked(){if(mFile==null){

Slog.w(\return;}

mUidStats.clear();

try{

Filefile=mFile.chooseForRead();if(!file.exists()){return;}

FileInputStreamstream=newFileInputStream(file);

byte[]raw=BatteryStatsHelper.readFully(stream);Parcelin=Parcel.obtain();

in.unmarshall(raw,0,raw.length);in.setDataPosition(0);stream.close();

readSummaryFromParcel(in);}catch(Eeptione){

Slog.e(\}

readSummaryFromParcel函數(shù),從\這個(gè)文件讀取各個(gè)成員變量。[java]viewplaincopy

publicvoidreadSummaryFromParcel(Parcelin){finalintversion=in.readInt();if(version!=VERSION){

Slog.w(\+\return;}

readHistory(in,true);

mStartCount=in.readInt();mUptime=in.readLong();mRealtime=in.readLong();

mStartClockTime=in.readLong();

mStartPlatformVersion=in.readString();mEndPlatformVersion=in.readString();

mOnBatteryTimeBase.readSummaryFromParcel(in);

mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);mDischargeUnplugLevel=in.readInt();mDischargePlugLevel=in.readInt();mDischargeCurrentLevel=in.readInt();mCurrentBatteryLevel=in.readInt();

mLowDischargeAmountSinceCharge=in.readInt();mHighDischargeAmountSinceCharge=in.readInt();mDischargeAmountScreenOnSinceCharge=in.readInt();mDischargeAmountScreenOffSinceCharge=in.readInt();mNumDischargeStepDurations=in.readInt();in.readLongArray(mDischargeStepDurations);mNumChargeStepDurations=in.readInt();

然后還有兩個(gè)寫的函數(shù),一個(gè)同步一個(gè)異步[java]viewplaincopy

publicvoidwriteAsyncLocked(){writeLocked(false);}

publicvoidwriteSyncLocked(){writeLocked(true);}

voidwriteLocked(booleansync){if(mFile==null){

Slog.w(\return;}

if(mShuttingDown){return;}

Parcelout=Parcel.obtain();

writeSummaryToParcel(out,true);

mLastWriteTime=SystemClock.elapsedRealtime();

if(mPendingWrite!=null){mPendingWrite.recycle();}

mPendingWrite=out;

if(sync){

commitPendingDataToDisk();}else{

BackgroundThread.getHandler().post(newRunnable(){@Overridepublicvoidrun(){commitPendingDataToDisk();}});}}

在ActivityManagerService中新建BatteryStatsService的時(shí)候,會(huì)去調(diào)用BatteryStatsImpl的readLocked,讀取\的值,來初始化自己的成員變量。[java]viewplaincopy

mBatteryStatsService=newBatteryStatsService(systemDir,mHandler);mBatteryStatsService.getActiveStatistics().readLocked();

mBatteryStatsService.getActiveStatistics().writeAsyncLocked();譬如在關(guān)機(jī)的時(shí)候進(jìn)行寫,但這時(shí)候是同步的。

我們?cè)趺蠢斫庑陆˙atteryStatsService的時(shí)候,會(huì)去調(diào)用BatteryStatsImpl的readLocked,讀取\的值,來初始化自己的成員變量。

譬如說充電,一開機(jī),之前的充電的每格電池的充電時(shí)間都沒有,通過從\文件中讀取,就可以將上次開機(jī)的狀態(tài)知道了。

其實(shí)細(xì)心看代碼,知道插入usb充電時(shí),由于mOnBattery改變了會(huì)調(diào)用setOnBatteryLocked函數(shù),而這時(shí)候?qū)LastChargeStepTime=-1;mNumChargeStepDurations=0;[java]viewplaincopy

voidsetOnBatteryLocked(finallongmSecRealtime,finallongmSecUptime,finalbooleanonBattery,

finalintoldStatus,finalintlevel){booleandoWrite=lse;

Messagem=mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);m.arg1=onBattery?1:0;mHandler.sendMessage(m);

finallonguptime=mSecUptime*1000;finallongrealtime=mSecRealtime*1000;

finalbooleanscreenOn=mScreenState==Display.STATE_ON;if(onBattery){}else{

Slog.e(\mOnBattery=mOnBatteryInternal=onBattery;pullPendingStateUpdatesLocked();

mHistoryCur.batteryLevel=(byte)level;

mHistoryCur.states|=HistoryItem.STATE_BATTERY_PLUGGED_FLAG;

if(DEBUG_HI

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論