大致章節(jié)如下:
(1)為什么會耗電翰守?
(2)學(xué)會使用電量分析工具Battery Historian
(3)低耗電模式(Doze)和應(yīng)用待機模式(App Standby)
(4)監(jiān)控電池電量和充電狀態(tài)
(5)確定和監(jiān)控插接狀態(tài)和基座類型
一孵奶、為什么會耗電?
電量的消耗是一種必然現(xiàn)象蜡峰,主要是由于移動設(shè)備的硬件在工作導(dǎo)致耗電了袁;
硬件的過度工作朗恳,導(dǎo)致耗電增加,這種情況屬于不正吃芈蹋現(xiàn)象粥诫,所以需要電量優(yōu)化;
耗電比較嚴重的硬件主要有:CPU崭庸、wakelock怀浆、數(shù)據(jù)傳輸(流量和wifi)、wifi運行冀自、gps、other senior等秒啦。
二熬粗、學(xué)會使用電量分析工具Battery Historian
Battery Historian 是谷歌推出的系統(tǒng)電量分析工具,僅支持5.0(API21)及以上系統(tǒng)的電量分析余境。
Battery Historian 對應(yīng)的Github地址是:
https://github.com/google/battery-historian
在線電量分析工具地址是:https://bathist.ef.lc/驻呐,可以將bugreport
文件上傳到在線網(wǎng)站上,從而進行數(shù)據(jù)分析芳来。但是含末,它的響應(yīng)速度太慢,甚至無法傳遞數(shù)據(jù)即舌,估計是需要翻墻才可以正常訪問吧佣盒。
Battery Historian可以配置本地環(huán)境,在Battery Historian的github官網(wǎng)上可以找到本地環(huán)境配置方法顽聂,步驟如下:
【1】
安裝Docker(https://docs.docker.com/engine/install/)
需要注意的是:
現(xiàn)在官網(wǎng)提供的最新版本的Docker只支持win10以上的操作系統(tǒng)或者mac系統(tǒng)肥惭,作者本人特地將win7升級到win11系統(tǒng);
如果Docker啟動失敗紊搪,報`WSL 2 installation is incomplete.`錯誤蜜葱,那么需要安裝`wsl_update_x64.msi`才可以,下載地址是:
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
Docker安裝完之后耀石,啟動即可牵囤。
如果Docker中沒有正在執(zhí)行的鏡像,那么主頁面會提示沒有容器在運行滞伟,如圖:
docker run -d -p:運行鏡像的命令
80:端口號
docker/getting-started:鏡像名稱
可以在命令提示符或者git bash中執(zhí)行命令(需要保證Docker已啟動):
docker run -d -p 80:80 docker/getting-started
如果本地沒有docker/getting-started
鏡像揭鳞,那么直接重遠程下載:
最終成功啟動鏡像:
輸入命令:
docker ps -a
可以看到當(dāng)前正在執(zhí)行的鏡像:
打開瀏覽器,輸入:
http://localhost:80
即可打開docker/getting-started鏡像的主頁面梆奈。
【2】
安裝電池分析相關(guān)鏡像
github上提供了電量分析相關(guān)的鏡像:gcr.io/android-battery-historian/stable:3.0
輸入以下命令下載并啟動鏡像(為了防止端口沖突汹桦,就不要設(shè)置80或者8080端口了):
docker run -d -p 9999:9999 gcr.io/android-battery-historian/stable:3.0 --port 9999
結(jié)果超時了:
之所以超時,可能是防火墻的原因鉴裹,或者需要翻墻舞骆。
如果您真的超時了钥弯,也無需煩惱,只需要使用Docker自帶的搜索命令督禽,輸入命令:
docker search battery
即脆霎,搜索關(guān)鍵字"battery"找到所有與battery相關(guān)的鏡像,如圖:
NAME為鏡像名稱狈惫,經(jīng)過一波嘗試睛蛛,最終確認,最好用的鏡像是:runcare/battery-historian
胧谈,因為他可以做到秒開忆肾。
接下來就用runcare/battery-historian
鏡像來演示。
輸入命令下載并啟動鏡像:
docker run -d -p 9999:9999 runcare/battery-historian --port 9999
等待下載完成菱肖,runcare/battery-historian
鏡像下載完成之后客冈,會自動啟動,如果已經(jīng)啟動稳强,請先關(guān)閉场仲。
接下來,點擊下圖的RUN按鈕:
啟動之前退疫,需要配置下端口號:
Local Host對應(yīng)的是localhost后面的端口號渠缕;
Container Port是容器的端口號;
需要注意的是褒繁, Local Host和Container Port不能相同亦鳞,否則上傳電池信息的Submit
按鈕無法顯示。
在瀏覽器上輸入(localhost后面的8888就是啟動鏡像之前配置的端口號):
http://localhost:8888/
打開后的頁面如下:
【3】
導(dǎo)出電池信息日志
重置電量信息:adb shell dumpsys batterystats --reset
獲取完整的wakelock信息:adb shell dumpsys batterystats --enable full-wake-history
拔掉USB棒坏,讓設(shè)備不處于充電狀態(tài)蚜迅,等待一段時間....
獲得報告:
>7.0
adb bugreport bugreport.zip
<=6.0
adb bugreport > bugreport.txt
【4】
上傳bugreport文件并分析
在瀏覽器上輸入:
http://localhost:8888/
點擊“Browse”按鈕,選擇bugreport文件俊抵,之后頁面的右側(cè)會出現(xiàn)一個提交按鈕
點擊提交:
那么谁不,怎么分析這個數(shù)據(jù)呢?
主要從兩個維度上來分析:
(1)查看耗電應(yīng)用排行
點擊左側(cè)的“Tables - Device's Power Estimates”徽诲,
耗電排名第一的非系統(tǒng)應(yīng)用為高德地圖刹帕,這個數(shù)據(jù)理所當(dāng)然,因為這段時間谎替,我只打開了高德地圖應(yīng)用偷溺。
(2)查看具體應(yīng)用的耗電情況
找到左側(cè)的”App Selection“,選擇對應(yīng)耗電應(yīng)用的包名:
查看耗電信息:
三钱贯、低耗電模式(Doze)和應(yīng)用待機模式(App Standby)
為了延長電池壽命挫掏,谷歌在Android 6.0(API 23)引入了低耗電模式(Doze)和應(yīng)用待機模式(App Standby)。
低電耗模式:如果用戶未插接設(shè)備的電源秩命,在屏幕關(guān)閉的情況下尉共,讓設(shè)備在一段時間內(nèi)保持不活動狀態(tài)褒傅,那么設(shè)備就會進入低電耗模式。
在低電耗模式下袄友,系統(tǒng)會嘗試通過限制應(yīng)用訪問占用大量網(wǎng)絡(luò)和 CPU 資源的服務(wù)來節(jié)省電量殿托。
它還會阻止應(yīng)用訪問網(wǎng)絡(luò),并延遲其作業(yè)剧蚣、同步和標(biāo)準(zhǔn)鬧鐘支竹。
系統(tǒng)會定期退出低電耗模式一小段時間,讓應(yīng)用完成其延遲的活動鸠按。
在此維護期內(nèi)礼搁,系統(tǒng)會運行所有待處理的同步、作業(yè)和鬧鐘目尖,并允許應(yīng)用訪問網(wǎng)絡(luò)馒吴。
在每個維護期結(jié)束時,系統(tǒng)會再次進入低電耗模式卑雁,暫停網(wǎng)絡(luò)訪問并推遲作業(yè)募书、同步和鬧鐘绪囱。
隨著時間的推移测蹲,系統(tǒng)安排維護期的次數(shù)越來越少,這有助于在設(shè)備未連接至充電器的情況下長期處于不活動狀態(tài)時降低耗電量鬼吵。
一旦用戶通過移動設(shè)備扣甲、打開屏幕或連接至充電器喚醒設(shè)備,系統(tǒng)就會立即退出低電耗模式齿椅,并且所有應(yīng)用都會恢復(fù)正沉鹜冢活動。
在低耗電模式下涣脚,您的應(yīng)用會收到如下限制:
(1)暫停訪問網(wǎng)絡(luò)示辈;
(2)系統(tǒng)忽略喚醒鎖定(PowerManager.WakeLock);
(3)標(biāo)準(zhǔn) AlarmManager 的 setExact() 和 setWindow() 推遲到下個維護期遣蚀;
如果需要在低耗電模式下觸發(fā)鬧鐘使用 `setAndAllowWhileIdle()` 和 `setExactAndAllowWhileIdle()` 即可矾麻;
使用 `setAlarmClock()` 設(shè)置的鬧鐘將繼續(xù)正常觸發(fā),系統(tǒng)會在這些鬧鐘觸發(fā)之前不久退出低耗電模式芭梯;
(4)系統(tǒng)不執(zhí)行WLAN掃描险耀;
(5)系統(tǒng)不允許運行同步適配器;
(6)系統(tǒng)不允許運行JobScheduler玖喘;
低耗電模式下甩牺,您的應(yīng)用可能存在的影響?
低電耗模式可能會對應(yīng)用產(chǎn)生不同的影響累奈,具體取決于應(yīng)用提供的功能和使用的服務(wù)贬派。
許多應(yīng)用無需修改即可在低電耗模式周期內(nèi)正常運行急但。
在某些情況下,您必須優(yōu)化應(yīng)用管理網(wǎng)絡(luò)赠群、鬧鐘羊始、作業(yè)和同步的方式。
應(yīng)用應(yīng)該能夠在每個維護期內(nèi)高效地管理活動查描。
低電耗模式尤其可能會影響 `AlarmManager` 鬧鐘和定時器管理的活動突委,因為當(dāng)系統(tǒng)處于低電耗模式時,不會觸發(fā) Android 5.1(API 級別 22)或更低版本中的鬧鐘冬三。
為了幫助安排鬧鐘匀油,Android 6.0(API 級別 23)引入了兩種新的 `AlarmManager` 方法:`setAndAllowWhileIdle()` 和 `setExactAndAllowWhileIdle()`。
通過這些方法勾笆,您可以設(shè)置即使設(shè)備處于低電耗模式也會觸發(fā)的鬧鐘敌蚜。
低電耗模式對網(wǎng)絡(luò)訪問的限制也有可能影響應(yīng)用,特別是當(dāng)應(yīng)用依賴于操作消息或通知等實時消息時更是如此窝爪。
系統(tǒng)提供白名單弛车,可以部分免除低耗電模式和應(yīng)用待機模式給應(yīng)用帶來的影響?
通過妥善管理網(wǎng)絡(luò)連接、鬧鐘蒲每、作業(yè)和同步纷跛,幾乎所有應(yīng)用都應(yīng)該能夠支持低電耗模式。
系統(tǒng)提供了一個可配置的白名單邀杏,將部分免除低電耗模式和應(yīng)用待機模式優(yōu)化的應(yīng)用列入其中贫奠。
在低電耗模式和應(yīng)用待機模式期間,列入白名單的應(yīng)用可以使用網(wǎng)絡(luò)并保留部分喚醒鎖定望蜡。不過唤崭,列入白名單的應(yīng)用仍會受到其他限制,就像其他應(yīng)用一樣脖律。
例如谢肾,列入白名單的應(yīng)用的作業(yè)和同步會延遲(在搭載 API 級別 23 及更低級別的設(shè)備上),并且其常規(guī) `AlarmManager` 鬧鐘不會觸發(fā)小泉。
應(yīng)用可以調(diào)用 `isIgnoringBatteryOptimizations()` 來檢查它當(dāng)前是否在豁免白名單中芦疏。
用戶可以依次轉(zhuǎn)到`設(shè)置 > 電池 > 電池優(yōu)化`來手動配置該白名單。另外膏孟,系統(tǒng)也提供了一些方法眯分,讓應(yīng)用要求用戶將其列入白名單。
`設(shè)置 > 電池 > 電池優(yōu)化`只是部分手機的路徑柒桑,但是有些手機弊决,電池優(yōu)化的路徑并未暴露出來爷速,可以通過以下代碼直接跳轉(zhuǎn)到`電池優(yōu)化`界面咧栗。
Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
startActivity(intent);
類似這樣的界面:
Android 6.0 之后琅催,PowerManager 新增了isIgnoringBatteryOptimizations方法郊丛,來確定應(yīng)用是電池優(yōu)化的情況。
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 是否忽視電池優(yōu)化
boolean isIgnoringBatteryOptimizations = powerManager.isIgnoringBatteryOptimizations(getPackageName());
}
如果應(yīng)用的電池優(yōu)化選擇了`不優(yōu)化`昆稿,那么`isIgnoringBatteryOptimizations`的值為true纺座,
此時就相當(dāng)于已經(jīng)加入了白名單,電池電量肯能會更快耗盡溉潭,系統(tǒng)將不再限制應(yīng)用在后臺使用電量净响;
具有 `REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` 權(quán)限的應(yīng)用可以觸發(fā)一個系統(tǒng)對話框,讓用戶直接將該應(yīng)用添加到白名單喳瓣,而無需轉(zhuǎn)到“設(shè)置”馋贤。
此類應(yīng)用將通過觸發(fā) `ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS` Intent 來觸發(fā)該對話框。
代碼如下:
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// 是否忽視電池優(yōu)化
boolean isIgnoringBatteryOptimizations = powerManager.isIgnoringBatteryOptimizations(getPackageName());
if (!isIgnoringBatteryOptimizations) {
Intent intent = new Intent(ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
startActivity(intent);
}
}
`ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS`的目的是為了彈出系統(tǒng)對話框畏陕,但是配乓,部分手機并沒有這個對話框,可以使用try...catch來保護惠毁。
另外犹芹,用戶可以根據(jù)需要從白名單中手動移除應(yīng)用。
如何在低電耗模式下進行測試鞠绰?
為確保用戶獲得良好的體驗腰埂,您應(yīng)在低電耗模式和應(yīng)用待機模式下全面測試您的應(yīng)用。
您可以按以下步驟在低電耗模式下測試您的應(yīng)用:
(1)使用 Android 6.0(API 級別 23)或更高版本的系統(tǒng)映像配置硬件設(shè)備或虛擬設(shè)備洞豁。
(2)將設(shè)備連接到開發(fā)計算機并安裝您的應(yīng)用盐固。
(3)運行您的應(yīng)用并使其保持活動狀態(tài)荒给。
(4)運行以下命令丈挟,強制系統(tǒng)進入閑置模式:
adb shell dumpsys deviceidle force-idle
(5)準(zhǔn)備就緒后,運行以下命令志电,使系統(tǒng)退出閑置模式:
adb shell dumpsys deviceidle unforce
(6)執(zhí)行以下命令曙咽,重新激活設(shè)備:
adb shell dumpsys battery reset
(7)在重新激活設(shè)備后觀察應(yīng)用的行為。確保應(yīng)用在設(shè)備退出低電耗模式時正程袅荆恢復(fù)例朱。
如何在應(yīng)用待機模式下進行測試?
如需在應(yīng)用待機模式下測試您的應(yīng)用鱼蝉,請執(zhí)行以下操作:
(1)使用 Android 6.0(API 級別 23)或更高版本的系統(tǒng)映像配置硬件設(shè)備或虛擬設(shè)備洒嗤。
(2)將設(shè)備連接到開發(fā)計算機并安裝您的應(yīng)用。
(3)運行您的應(yīng)用并使其保持活動狀態(tài)魁亦。
(4)運行以下命令渔隶,強制應(yīng)用進入應(yīng)用待機模式:
adb shell dumpsys battery unplug
adb shell am set-inactive <packageName> true
(5)使用以下命令模擬喚醒您的應(yīng)用:
adb shell am set-inactive <packageName> false
adb shell am get-inactive <packageName>
(6)在喚醒應(yīng)用后觀察它的行為。確保應(yīng)用從待機模式正常恢復(fù)间唉。您應(yīng)特別檢查應(yīng)用的通知和后臺作業(yè)是否繼續(xù)按預(yù)期運行绞灼。
四、監(jiān)控電池電量和充電狀態(tài)
如果您要通過改變后臺更新的頻率降低這些更新對電池續(xù)航時間的影響呈野,最好先從檢查當(dāng)前電池電量和充電狀態(tài)入手低矮。
執(zhí)行應(yīng)用更新對電池續(xù)航時間的影響取決于設(shè)備的電池電量和充電狀態(tài)。設(shè)備通過交流電源充電時執(zhí)行更新的影響可以忽略不計被冒,因此在大多數(shù)情況下军掂,
只要設(shè)備連接到壁式充電器,您就可以最大限度地提高更新頻率昨悼。相反良姆,如果設(shè)備正在放電,降低更新頻率有助于延長電池續(xù)航時間幔戏。
同理玛追,您也可以檢查電池充電電量,并在電池電量近乎耗盡時降低更新頻率闲延,甚至停止更新痊剖。
如何確認當(dāng)前充電狀態(tài)?
首先垒玲,確定當(dāng)前充電狀態(tài)陆馁。`BatteryManager` 會在一個包含充電狀態(tài)的粘性 `Intent` 中廣播所有電池和充電詳情。
由于它是一個粘性 Intent合愈,因此您并不需要如下一代碼段中所示的那樣通過簡單地調(diào)用 `registerReceiver`
傳入 `null` 作為接收器來注冊 `BroadcastReceive`叮贩,便可返回當(dāng)前電池狀態(tài) Intent。
您可以在此處傳入實際 `BroadcastReceive` 對象佛析,但由于稍后我們將會處理更新益老,因此并不需要這樣做。
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent batteryStatus = context.registerReceiver(null, ifilter);
獲取電池的充電狀態(tài)寸莫?
int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
電池的充電狀態(tài)有:
BatteryManager.BATTERY_STATUS_UNKNOWN:沒有安裝電池
BatteryManager.BATTERY_STATUS_CHARGING:正在充電
BatteryManager.BATTERY_STATUS_DISCHARGING:放電中
BatteryManager.BATTERY_STATUS_NOT_CHARGING:未充電
BatteryManager.BATTERY_STATUS_FULL:已經(jīng)充滿(電量100%不代表一定是BATTERY_STATUS_FULL狀態(tài)捺萌,如果電量100%并且正在充電才是BATTERY_STATUS_FULL狀態(tài))
// 是否正在充電
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL;
您可以提取當(dāng)前充電狀態(tài),并且如果設(shè)備正在充電膘茎,則還可以提取設(shè)備是通過 USB 還是交流充電器進行充電桃纯。
int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
電池的電源類型有:
BatteryManager.BATTERY_PLUGGED_USB:電源為USB端口
BatteryManager.BATTERY_PLUGGED_AC:電源為交流充電器
BatteryManager.BATTERY_PLUGGED_WIRELESS:電源為無線
// 電源是否是USB端口
boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB;
// 電源是否是交流充電器
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC;
// 電源是否是無線的
boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_WIRELESS;
您可以獲取電池的健康狀態(tài)
// 電池的健康狀況
int chargeHealth = batteryStatus.getIntExtra(BatteryManager.EXTRA_HEALTH, -1);
電池的健康狀況有:
BatteryManager.BATTERY_HEALTH_UNKNOWN:未知
BatteryManager.BATTERY_HEALTH_GOOD:良好
BatteryManager.BATTERY_HEALTH_OVERHEAT:過熱
BatteryManager.BATTERY_HEALTH_DEAD:沒電
BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:過電壓
BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:未知故障
BatteryManager.BATTERY_HEALTH_COLD:冷卻
// 是否為Good狀態(tài)
boolean chargeGood = chargeHealth == BatteryManager.BATTERY_HEALTH_GOOD;
如何監(jiān)控充電狀態(tài)變化?
就像設(shè)備可以輕松地插入電源披坏,充電狀態(tài)也很容易發(fā)生變化态坦,因此必須監(jiān)控充電狀態(tài)的變化并相應(yīng)地改變刷新頻率。
每當(dāng)設(shè)備連接或斷開電源時棒拂,`BatteryManager` 都會廣播一項操作伞梯。請務(wù)必接收這些事件,即便您的應(yīng)用并未運行,
尤其要考慮到這些事件可能會影響您啟動應(yīng)用以便發(fā)起后臺更新的頻率壮锻,因此您應(yīng)在清單中注冊一個 `BroadcastReceiver`琐旁,
通過在一個 Intent 過濾器內(nèi)定義 `ACTION_POWER_CONNECTED` 和 `ACTION_POWER_DISCONNECTED` 來同時監(jiān)聽這兩種事件。
代碼如下:
<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>
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;
if (isCharging) {
Log.d("TAG", "正在充電...");
} else {
Log.d("TAG", "放電中...");
}
}
}
IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
this.registerReceiver(new PowerConnectionReceiver(), ifilter);
當(dāng)充電器插拔時猜绣,充電狀態(tài)改變灰殴,PowerConnectionReceiver
廣播總是被觸發(fā)。
如何確定當(dāng)前電池電量掰邢?
在某些情況下牺陶,確定當(dāng)前電池電量也很有用處。您可以選擇在電池電量低于某一水平時降低后臺更新的頻率辣之。
您可以通過從電池狀態(tài) intent 提取當(dāng)前電池電量和刻度來了解當(dāng)前電池電量掰伸,如下所示:
int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
float batteryPct = level * 100 / (float)scale;
如何監(jiān)控電池電量變化?
您無法輕松地持續(xù)監(jiān)控電池狀態(tài)怀估,您也不必如此狮鸭。
一般而言,持續(xù)監(jiān)控電池電量對電池的影響大于應(yīng)用正常行為造成的影響多搀,因此最好只監(jiān)控顯著的電池電量變化歧蕉,特別是在設(shè)備進入或退出電量不足狀態(tài)時。
Android給我們提供了兩個給力的Actiton康铭,分別是:BATTERY_LOW 和 BATTERY_OKAY
BATTERY_LOW:設(shè)備進入電量不足狀態(tài)
BATTERY_OKAY:設(shè)備退出電量不足狀態(tài)
<receiver android:name=".BatteryLevelReceiver">
<intent-filter>
<action android:name="android.intent.action.BATTERY_LOW"/>
<action android:name="android.intent.action.BATTERY_OKAY"/>
</intent-filter>
</receiver>
一般而言惯退,建議您在電量極低時停用所有后臺更新。如果手機自行關(guān)機从藤,您就無法利用相關(guān)數(shù)據(jù)催跪,數(shù)據(jù)的新鮮度也就無關(guān)緊要。
五夷野、確定和監(jiān)控插接狀態(tài)和基座類型
Android 設(shè)備可插接到幾個不同種類的基座懊蒸,其中包括車載或家用基座以及數(shù)字和模擬基座。
插接狀態(tài)通常與充電狀態(tài)聯(lián)系密切扫责,因為許多基座都為插接的設(shè)備供電榛鼎。
手機插接狀態(tài)對更新頻率的影響取決于您的應(yīng)用逃呼。
您可以選擇在手機插入桌面基座時提高體育中心應(yīng)用的更新頻率鳖孤,或者在設(shè)備插入車載基座時完全停用更新。
相反抡笼,如果您的后臺服務(wù)正在更新路況信息苏揣,則您可以選擇在已插接車載基座的情況下最大限度地提高更新頻率。
插接狀態(tài)也會以粘性 `Intent` 形式廣播推姻,以便您查詢設(shè)備是否已插接以及已插接情況下的基座類型平匈。
如何確定當(dāng)前插接狀態(tài)?
插接狀態(tài)詳情以 extra 形式包含在 `ACTION_DOCK_EVENT` 操作的粘性廣播中。由于它是粘性廣播增炭,因此您只需調(diào)用 `registerReceiver()`忍燥,將 `null` 作為廣播接收器傳入。
以下代碼段展示了如何完成此流程:
IntentFilter ifilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
Intent dockStatus = context.registerReceiver(null, ifilter);
您可以從 EXTRA_DOCK_STATE extra 中提取當(dāng)前插接狀態(tài):
int dockState = dockStatus.getIntExtra(EXTRA_DOCK_STATE, -1);
boolean isDocked = dockState != Intent.EXTRA_DOCK_STATE_UNDOCKED;
基座類型有:
Intent.EXTRA_DOCK_STATE_UNDOCKED:無基座
Intent.EXTRA_DOCK_STATE_DESK:桌面基座
Intent.EXTRA_DOCK_STATE_CAR:車載基座
Intent.EXTRA_DOCK_STATE_LE_DESK:低端(模擬)桌面基座
Intent.EXTRA_DOCK_STATE_HE_DESK:高端(數(shù)字)桌面基座
請注意隙姿,后兩種類型從 Android 的 API 級別 11 才開始引入梅垄,因此如果您只關(guān)注基座類型而不關(guān)心其具體為數(shù)字還是模擬形式,則最好檢查所有三種類型:
boolean isCar = dockState == EXTRA_DOCK_STATE_CAR;
boolean isDesk = dockState == EXTRA_DOCK_STATE_DESK ||
dockState == EXTRA_DOCK_STATE_LE_DESK ||
dockState == EXTRA_DOCK_STATE_HE_DESK;
[本章完...]