ByteScope

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,但它還是被印出來,就是為了讓人不必假設。
status1 未知、2 充電中、3 放電中、4 未在充電、5 已充滿。
health2 良好、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,也不會上傳任何東西。

開啟 Android Battery Health

相關指令

和 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 版本或廠牌而異的地方,這一頁會直接說明,而不是給你一個在半數手機上都是錯的數字。

常見問題

adb shell 指令要怎麼執行?

在手機上打開開發者選項與 USB 除錯、接上線,然後從裝了 platform-tools 的機器執行 adb shell <指令>——或者只執行 adb shell 取得互動提示字元,再直接打指令、不用前綴。如果指令會輸出二進位資料(例如截圖),請改用 adb exec-out 而不是 adb shell:單純的 shell 服務會配一個終端機,而它會改寫換行位元組並毀掉資料。

adb shell 指令需要 root 嗎?

這份參考裡的都不用。它們以 shell 使用者身分執行,可以針對自己的 Android 使用者管理套件、讀取大多數 dumpsys 服務、寫入設定提供者、注入輸入,以及讀取共用儲存空間。需要 root 的是這份參考刻意避開的事:讀取其他 app 的私有資料(除了對可除錯版本使用 run-as)、寫入系統分割區,或直接讀 /data/anr。

為什麼在我的手機上輸出看起來不一樣?

不是 Android 版本就是廠商。有些旗標與欄位是從特定版本才有的,那些都在各指令頁註明了。其餘是廠商改動,而受影響最深的是 dumpsys:一份 dump 是除錯輸出,它的文字就是那個服務的作者最後印了什麼,而廠商既會改它也會把改動往回移植。請用名稱而不是位置來讀欄位,並把沒見過的格式當成差異而不是失敗。

可以用瀏覽器而不是終端機來跑嗎?

很多指令可以——本站的 Web ADB 工具從 Chromium 系桌面瀏覽器透過 WebUSB 和手機對話,不必安裝 SDK,也不會上傳任何東西。每一頁在有對應工具時都會連過去。有兩個限制值得知道:同一時間只有一個程式能持有 ADB 介面,所以桌面的 adb server 要先停掉;而 adb forward 與 adb reverse 在瀏覽器裡完全無法運作。

比較想按而不是打字?Web ADB Toolkit 會從瀏覽器透過 USB 執行這類指令。或者瀏覽全部指令。