參考 Google 官方文檔 : 優化電池續航時間
一、獲取充電狀態
在應用中執行某些操作 , 如軟件雲端備份 , 從服務器端獲取最新版本號 , 從服務器端緩存最新軟件安裝包 , 固件版本 , 等操作 , 最好都在充電狀態 , 那麼如何獲取充電狀態呢 , 這裏給出兩個方式 , 分別是主動獲取充電狀態 , 被動獲取充電狀態 ;
二、被動獲取充電狀態
1 . 被動獲取充電狀態 :
① 監聽方法 : 註冊廣播接受者 , 監聽充電狀態變化 ;
② 場景描述 : 當用戶插拔數據線時 , 充電狀態發生變化時 , 系統發出對應的廣播 , 使用廣播接受者接收這些廣播 ;
③ 數據線插入廣播 : 當數據線插入時 , 系統會發出 Intent.ACTION_POWER_CONNECTED 廣播 ;
④ 數據線拔出廣播 : 當數據線拔出時 , 系統會發出 Intent.ACTION_POWER_DISCONNECTED 廣播 ;
2 . 廣播接受者代碼示例 :
package kim.hsl.bp;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
/**
* 被動獲取充電狀態
* 充電狀態發生變化時 , 系統發出的廣播 , 使用廣播接受者接收這些廣播
*/
public class BatteryReceiver extends BroadcastReceiver {
public static final String TAG = "BatteryReceiver";
@Override
public void onReceive(Context context, Intent intent) {
// 獲取廣播事件
String action = intent.getAction();
if(TextUtils.equals(Intent.ACTION_POWER_CONNECTED, action)){
// 數據線插入
Log.i(TAG, "數據線插入");
}else if(TextUtils.equals(Intent.ACTION_POWER_DISCONNECTED, action)){
// 數據先拔出
Log.i(TAG, "數據線拔出");
}
}
}
3 . AndroidManifest.xml 註冊廣播接受者代碼示例 :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kim.hsl.bp">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".BatteryReceiver" >
<intent-filter>
<!-- 充電線插上 -->
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<!-- 充電線拔出 -->
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
</application>
</manifest>
三、主動獲取充電狀態
1 . 主動獲取充電狀態流程 :
① 創建 IntentFilter : 創建 IntentFilter , 併爲其設置 Intent.ACTION_BATTERY_CHANGED 意圖 ;
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
② 註冊廣播接受者 : 調用 Context 對象的 registerReceiver 方法 , 設置 BroadcastReceiver receiver 廣播接收者參數爲空 , IntentFilter 就是上述創建的意圖過濾器 ;
Intent intent = context.registerReceiver(null, intentFilter);
③ 獲取充電狀態 : 從註冊廣播返回的 Intent 意圖中獲取對應的充電狀態 ;
int batteryChargeState = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
④ 對比充電狀態 : 將上述從 Intent.ACTION_BATTERY_CHANGED 匹配的意圖中獲取 BatteryManager.EXTRA_PLUGGED 對應的值 , 與以下 個值進行對比 , 如果一致 , 說明當前是此種充電狀態 ;
- BatteryManager.BATTERY_PLUGGED_AC : 交流電充電 ;
- BatteryManager.BATTERY_PLUGGED_USB : USB 接口充電 ;
- BatteryManager.BATTERY_PLUGGED_WIRELESS : 無線充電 ;
2 . 廣播接受者註冊用法 :
① 註冊廣播接收者 : registerReceiver 方法主要作用是在主線程註冊一個廣播接收者 BroadcastReceiver 運行 ;
② 廣播接收者調用 : 當註冊的 IntentFilter 中的 action 匹配到相應的廣播時 , BroadcastReceiver 會被在主線程調用 ;
③ 歷史廣播保存 : 系統發送完畢的廣播 , 會被保存下來 , 在後續註冊時發送 ;
④ 廣播複用機制 : 一旦有廣播接收者註冊廣播 , 如果之前發送完畢的廣播與本次註冊的 IntentFilter 意圖的 Action 匹配 , 次函數就會返回一個 Intent , 這個 Intent 就是之前已經發送的廣播 ;
⑤ 如 : 本次註冊的 IntentFilter 中包含 Intent.ACTION_BATTERY_CHANGED , 如果使用如下方法 context.registerReceiver(null, intentFilter) 註冊空廣播接收者 , 返回值就是之前發送過的 Intent.ACTION_BATTERY_CHANGED 廣播 , 可以從該廣播中獲取對應的充電狀態變化數據 ;
⑥ 註冊多個意圖 : 如果在 IntentFilter 中註冊多個意圖 , 廣播接收者如果不爲空 , 則會處理每一個意圖 , 但是返回值只能返回一個意圖 , 返回哪個由系統決定 ;
廣播接收者註冊方法有兩種功能 , 一個是註冊廣播接收者 , 另一個是獲取之前已經發送的相同 Action 的歷史廣播 ;
這裏使用的註冊廣播接收者的獲取歷史廣播的功能 ;
3 . 代碼示例 :
package kim.hsl.bp;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
public class BatteryUtils {
/**
* 主動獲取當前電池是否在充電 , 即數據線是否插在手機上
* @return
*/
public static boolean isBatteryCharging(Context context){
boolean isBatteryCharging = false;
// 主動發送包含是否正在充電狀態的廣播 , 該廣播會持續發送
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
// 註冊廣播接受者
Intent intent = context.registerReceiver(null, intentFilter);
// 獲取充電狀態
int batteryChargeState = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
// 判定是否是 AC 交流電充電
boolean isAc = batteryChargeState == BatteryManager.BATTERY_PLUGGED_AC;
// 判斷是否是 USB 充電
boolean isUsb = batteryChargeState == BatteryManager.BATTERY_PLUGGED_USB;
// 判斷是否是 無線充電
boolean isWireless = batteryChargeState == BatteryManager.BATTERY_PLUGGED_WIRELESS;
// 如何上述任意一種爲 true , 說明當前正在充電
isBatteryCharging = isAc || isUsb || isWireless;
return isBatteryCharging;
}
}