dumpsys battery
唯讀電池服務目前的狀態:電量、充電狀態、健康度、電壓與溫度。
- 指令
- adb shell dumpsys battery
- 指令
- 系統服務(dumpsys)
- 風險
- 唯讀
語法
dumpsys battery範例
dumpsys battery服務所知的一份即時快照。
cat /sys/class/power_supply/battery/current_now把充電電流拿去和核心那邊對照,那邊的單位是由 power supply 類別而不是廠商決定的。
輸出怎麼讀
輸出範例
Current Battery Service state:
AC powered: false
USB powered: true
Charge counter: 3110000
status: 2
health: 2
level: 71
scale: 100
voltage: 4038
temperature: 302縮排的 `key: value` 清單。陷阱在單位,因為 Android 有三個溫度來源、用三種不同的刻度:這裡是攝氏的十分之一,所以 `302` 是 30.2 °C。請用名稱而不是位置來讀欄位——廠商會在清單的任何地方插進自己的行。
輸出欄位
| 欄位 | 意義 |
|---|---|
| level / scale | 以 `scale` 為分母的 `level`。出貨裝置的 `scale` 都是 100,但它還是被印出來,就是為了讓人不必假設。 |
| status | 1 未知、2 充電中、3 放電中、4 未在充電、5 已充滿。 |
| health | 2 良好、3 過熱、4 損壞、5 過電壓、6 未指明的故障、7 過冷。 |
| voltage | 毫伏,所以 `4038` 是 4.038 V。 |
| temperature | 攝氏的十分之一:`302` 是 30.2 °C。 |
| Charge counter | 微安時:`3110000` 是 3110 mAh。 |
| Max charging current / voltage | 分別是微安與微伏。 |
需要什麼權限
讀取只要 `android.permission.DUMP`,其他都不用。`BatteryService` 的 binder 是透過 `DumpUtils.checkDumpPermission` 檢查的,而 Shell 套件的資訊清單同時宣告了 `DUMP` 與 `BATTERY_STATS`,所以一條普通的授權 `adb` 連線就夠了——不用 root、不用 `adb root`、也不用在設定裡授權。值得看第二眼的是寫入那一側,因為它對你來說是完全同一條路。`dumpsys battery set …` 與 `dumpsys battery unplug` 根本不是讀取:它們是電池服務的 shell 子指令,各自被 `enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER)` 守著,而 Shell 的資訊清單連 `DEVICE_POWER` 也有。這就是為什麼從纜線這端這麼容易誤植數值,也是 `(UPDATES STOPPED …)` 那行存在的理由。你會落在哪一半是由參數解析決定的,不是由什麼你認得出來的關鍵字:`dumpInternal` 只有在完全沒有參數、或只有 `-a` 這一個參數時才印出給人看的狀態區塊,**其他任何參數**都會被交給電池的 shell 指令處理器。所以 `dumpsys battery` 與 `dumpsys battery -a` 是讀取;`dumpsys battery level` 是一個被誤解的子指令;而 `dumpsys battery set level 5` 是一個活得比你這次 shell 連線更久、直到有東西重設它為止的裝置變更。Android Battery Health 這個工具只會送出讀取的那個形式。
失敗訊息對照
| 訊息 | 意義 |
|---|---|
| Permission Denial: can't dump BatteryService from from pid=4821, uid=10231 due to missing android.permission.DUMP permission | 來自 `DumpUtils.checkDumpPermission`。重複的 `from from` 是 AOSP 字串本身,不是抄錯,所以要照原樣比對、不要幫它改。更討厭的是串流:這行寫進的是 dump 自己的 writer,也就是說它出現在**標準輸出**,正好就是電池欄位平常在的地方。一個找 `level:` 找不到的解析器,會回報一顆空的電池,而不是一次被拒絕的呼叫。 |
| Unknown command: level | 你要了一個欄位,拿到的是 shell 指令處理器。`dumpsys battery` 只把「沒有參數」和 `-a` 當成「印出狀態區塊」,其他任何東西——包括這份輸出裡印出來的每一個欄位名稱——都會被當成子指令。請用 `dumpsys battery get level`,或直接從一般的 dump 裡讀 `level:`。它印在標準輸出,所以可能混進你收下來的那份「讀數」裡。 |
| *** SERVICE 'battery' DUMP TIMEOUT (10000ms) EXPIRED *** | `dumpsys` 這支程式等滿預設的十秒就放棄,並把這行印進輸出串流。它上面的一切都是真的;服務還沒來得及寫出來的就是不存在,而因為欄位是照固定順序印的,缺的永遠是尾巴——先是 `technology`,然後是 `temperature`。請用 `-t SECONDS` 或 `-T MILLIS` 拉長等待,不要拿一份被截斷的區塊反覆重讀。 |
| Can't find service: battery | 由 `dumpsys` 這支程式印到標準錯誤,代表 service manager 裡沒有 `battery` 這一項,而這在裝置還在開機時會發生。它不是廠商把誰改名了,也不是權限問題——根本沒有向服務要求過任何東西。 |
版本與廠商注意事項
- 原生 Android 在這裡既不印充電電流也不印循環次數。會顯示 `current now` 或 `cycle count` 的手機是廠商改過的,而那個電流欄位的正負號、在某些版本上連刻度都會變,所以它的大小要存疑,方向請改看 `status`。
- `(UPDATES STOPPED -- use 'reset' to restart)` 代表有人用 `dumpsys battery set` 或 `unplug` 注入了數值。在 `dumpsys battery reset` 之前,那行以下都是假的。
- 這裡的溫度是十分之一度,`/sys/class/thermal/*/temp` 是千分之一度,而 `dumpsys thermalservice` 印的是浮點數的攝氏。搞混就是往任一方向差十倍。
- `Dock powered:` 比這個區塊其他行都新——`BatteryService` 在 tag android-14.0.0_r1 會印它,android-11、12、13 都不會——所以舊手機上沒有它是年紀問題,不是少了一個座充。
- 這裡的參數不是篩選器:只有完全沒有參數、或只有 `-a` 這一個參數時才會印出狀態區塊,其他任何參數都會被交給電池服務自己的 shell 指令處理器,而 `set` 與 `unplug` 正在那裡等著。
這個我們有 UI
Android Battery Health 會透過 USB 執行這個指令並解析回應——只要 Chromium 系瀏覽器,不必安裝 SDK,也不會上傳任何東西。
相關指令
和 dumpsys battery 會在同一次作業裡出現的指令。
| 指令 | 做什麼 |
|---|---|
| dumpsys thermalservice | 手機是不是正在因為溫度而降速,以及硬體層回報的每一個溫區,單位是攝氏。 |
| top | 一次性的行程表:CPU 占用、記憶體、狀態與指令列。 |
| dumpsys meminfo | 哪些行程最吃記憶體,量的是 PSS(按比例分攤的用量)。 |
其他系統服務(dumpsys)指令
| 指令 | 做什麼 |
|---|---|
| dumpsys diskstats | 每個分割區的剩餘空間、一次磁碟寫入延遲的實測,以及一份快取起來的各 app 空間用量。 |
| dumpsys sensorservice | 手機上的每一個感測器,含廠商、type、取樣率與批次能力,以及一段近期讀數的緩衝。 |
| dumpsys package | 套件管理員知道的一切:版本、路徑、flags、安裝來源,以及每個使用者的狀態。 |
| dumpsys activity activities | 現在哪個 app 在前景,以及它背後的 task 與 stack 結構。 |
| dumpsys dropbox | 平台用來存放當機、ANR 與 tombstone 的環形緩衝——這是不用 root 讀 ANR 追蹤的方法。 |
這些行為是在撰寫 Web ADB 工具背後的解析程式時,對照 AOSP、toybox 與核心原始碼查證的。真的會因 Android 版本或廠牌而異的地方,這一頁會直接說明,而不是給你一個在半數手機上都是錯的數字。