2025-05-23

當你想通過減少後臺更新服務的更新頻率來降低程序對電池的影響時,檢查電池當前的電量和充電狀態將是一個比較好的起點。

程序更新對電池造成的影響將取決於當前電池電量和充電狀態,比如說,當設備正在充電的時候,這時的更新對電池的影響是微不足道的,所以這時就是你的程序加大更新力度的最佳時刻。與之相對的是,如果當前設備不是處於充電狀態的話,降低程序更新力度對延長續航時間是很必要的。

與之相類似的,如果設備沒有處於充電狀態,並且是當電池快要用完的時候,這時最好就是將更新力度降到最低甚至是停止更新。

確定電池所處狀態

當前電池電量和狀態都是通過BatteryManager發送廣播,來通知相關的廣播接收者的。 個人感覺應該是通過sendStickyBroadcast這種方法發送的廣播,這種廣播的特點是在廣播發送之後,廣播的實體Intent會一直存在,意思就是說,在以後調用registerReceiver註冊相匹配的Receiver時會把這個Intent對象直接返回給新註冊的Receiver,明白這一點對下文是很重要的。

因為BatteryManager廣播的是一個sticky的intent實體,這就意味著你不用非得註冊一個廣播接收者來讓你的程序接受這個廣播,你可以僅僅就是通過調用registerReceiver這個方法,在需要添加廣播接收者位置的參數上傳入null,當然你也可以新建一個廣播接收者,並在註冊廣播接收者的時候傳入。下面是相關代碼:

[java]
//設置意圖過濾器 
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 
//註冊廣播接收者,因為BatteryManager發送的是sticky形式的intent,所以接收者可以為空 
Intent batteryStatus = registerReceiver(null, ifilter); 
//得到電池當前的狀態(共有5種,包括unkonwn、charging、discharging、not charging、full) 
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1); 
//是否處於充電狀態 
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ; 
//充電方式(共有兩種,分別是通過AC充電和通過USB端口進行充電) 
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); 
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; 
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; 
//打印相關信息 
Log.i("MyBroadcastReceiverActivity","isCharging:"+isCharging+"\nusbCharge:"+usbCharge + "\nacCharge:"+ acCharge); 
註意這裡是使用的模擬器,其結果如下: 

 

更新程序的最佳時機是:電池狀態是使用AC充電狀態時,當是使用USB端口進行的充電時,應降低更新頻率,當不處於通電狀態時,更要降低程序更新頻率。

監聽電池狀態變化 www.aiwalls.com

當設備插上電源開始充電時,電池狀態便發生瞭變化,所以對程序員來說,通過監聽電池狀態的變化來進行相應的更新操作是很重要的。

當設備連上電源或與電源斷開連接時,BatteryManager都會發送一個廣播。即使這時,你的程序不是出於運行狀態,接收這些電池狀態變化的信息也是很有必要的,因為你可以控制在後臺是否進行相應的更新操作,所以應該為你的程序註冊一個廣播接收者,來監聽接上電源和與電源斷開兩種狀態。這裡通過AndroidManifest.xml進行廣播接收者的註冊,具體如下:

在AndroidManifest.xml中註冊一個名為PowerConnectionReceiver的廣播接收者:

[java]
<receiver android:name=".PowerConnectionReceiver"> 
<intent-filter> 
 <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/> 
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/> 
 </intent-filter> 
</receiver> 

PowerConnectionReceiver這個類,方法中的內容可參看上文:

[java]
public class PowerConnectionReceiver extends BroadcastReceiver { 
@Override 
public void onReceive(Context context, Intent intent) { 
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); 
        boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || 
                            status == BatteryManager.BATTERY_STATUS_FULL; 
     
        int chargePlug = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); 
        boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; 
        boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; 
        Log.i("PowerConnectionReceiver","isCharing:"+isCharging+"\nusbCharge:"+usbCharge+"\nacCharge:"+acCharge); 

確定當前電池電量

有時候,確定當前電池的電量也是很有必要的,你可以控制當電池電量低於某值時就降低程序頻率或者不再進行程序更新,相關代碼如下:

[java]
//取得當前電池電量 
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); 
//取得電池容量 
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1); 
//計算電池電量使用率 
float batteryPct = level / (float)scale; 
Log.i("MyBroadcastReceiverActivity", "level:"+level+"\nscale:"+scale+"\nbatteryPct:"+batteryPct); 

註意,這裡仍然是使用的模擬器,結果如下: 

 

監聽電池狀態的重大變化

一般說來,如果你一直對電池的狀態進行監聽的話,可能這本身就會對電池造成很大的影響,甚至超過程序本身的影響,這就有點得不償失瞭,所以,我們很有必要隻監聽電池狀態的重大變化,比如設備進入瞭電池電量很低的狀態或者從這個狀態中出來的時候,下面的代碼片段將對這兩者情況進行監聽,具體如下:

[java] print?<receiver android:name=".BatteryLevelReceiver"> 
<intent-filter> 
 <action android:name="android.intent.action.ACTION_BATTERY_LOW"/> 
 <action android:name="android.intent.action.ACTION_BATTERY_OKAY"/> 
 </intent-filter> 
</receiver> 
<receiver android:name=".BatteryLevelReceiver">
<intent-filter>
 <action android:name="android.intent.action.ACTION_BATTERY_LOW"/>
 <action android:name="android.intent.action.ACTION_BATTERY_OKAY"/>
 </intent-filter>
</receiver>
在廣播接收者BatterLevelReceiver類的onReceive方發中,就可以做你想做的瞭。

 

 

下一節,講介紹怎樣確定和監聽設備的dock狀態和 類型。

 

摘自  yaozq的android開發 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *