wm density
會改變裝置回報顯示密度,或覆寫它——真正會讓版面斷點移動的是這一個。
- 指令
- adb shell wm density
- 指令
- 畫面與擷取
- 風險
- 會改變裝置
語法
wm density [<dpi> | reset]旗標與參數
| token | 意義 |
|---|---|
| <dpi> | 要回報的密度。Android 自己的級距是 120 到 640,廠商也會出貨中間的值。 |
| reset | 拿掉覆寫,回到實體密度。 |
範例
wm density只回報。
wm density 420搭配 `wm size 1080x2340` 就是一台寬 411 dp 的手機,這是真實存在的斷點。
wm density reset還原。
輸出怎麼讀
輸出範例
Physical density: 560
Override density: 420形狀和 `wm size` 一樣:Physical 永遠有,Override 只在設了覆寫時才有。決定你拿到哪個版面的是 dp,所以真正有意義的量是「寬度像素乘 160 再除以這個 dpi」——420 dpi 的 1080 px 是 411 dp,同樣的 1080 px 換成 320 dpi 就變成 540 dp 的平板型版面。
輸出欄位
| 欄位 | 意義 |
|---|---|
| Physical density | 面板真正的 dpi。 |
| Override density | 改成回報的值。只在覆寫存在時出現。 |
需要什麼權限
不用 root,也不用 `adb root`。`wm` 是一行的 shell 腳本,跑的是 `cmd window "$@"`(AOSP 的 `cmds/wm/wm.sh`),而覆寫會經過的 `setForcedDisplayDensityForUser` 與 `clearForcedDisplayDensityForUser` 都標註了 `@EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)`——這個權限 `com.android.shell` 在自己的資訊清單裡就有,所以一條已授權的線就夠了,除了 USB 偵錯以外也沒有其他開發者選項的開關牽涉在內。有一個不對稱值得帶著走:密度那組呼叫吃一個使用者 id,而 shell 指令傳的是 `USER_CURRENT`,尺寸那組則完全不吃使用者。所以密度覆寫是記在當下在前景的那個人身上的,一台有第二個使用者或工作設定檔的手機,可能在其中一邊看得到覆寫、另一邊看不到;尺寸覆寫沒有這個維度。另外一半是界限而不是權限。shell 指令在呼叫 window manager 之前就會拒絕任何小於 72 的值,而且它完全沒有上限——本站強制的範圍是它自己的理智檢查而不是平台的,因為平台會很開心地接受一個讓螢幕上只剩一個半按鈕的密度。
失敗訊息對照
| 訊息 | 意義 |
|---|---|
| Error: density must be >= 72 | 下限是在 `runDisplayDensity` 自己裡面檢查的,在呼叫 window manager 之前,所以什麼都沒改。要注意這個檢查「沒有」出現在哪:沒有對應的上限,所以手滑打出來的 `4200` 會被接受並套用。實驗之前先把 `wm density reset` 放在畫面上。 |
| Error: bad number | 後面會接上例外自己的 `toString()`,指出失敗的那個 token。和 `wm size` 不同,這個參數是當成純整數解析的——這裡沒有 `dp` 或 `px` 後綴的處理——所以 `420dpi` 是語法錯誤,不是一種聰明的 420 寫法。 |
| Error: the uniqueId is invalid | `-u <uniqueId>` 的形式拿到一個 display manager 不認識的 id,指令沒讀也沒設就回來了。行尾那個多出來的空白是上游自己的,所以請比對文字而不是整行。 |
| Remote exception: | 回報那條路徑聯絡不到 window manager,於是印了這行加例外而不是一個密度。把它當成「未知」,絕對不要當成 0——把 0 dpi 帶進 dp 的計算會除以零,而這就是一次失敗的讀取如何讓整頁顯示探測結果變成胡言亂語。 |
| cmd: Can't find service: window | `cmd` 找不到 `window` 服務可以把子指令交出去,因為 `wm.sh` 只是 `cmd window` 的包裝。裝置還在開機、`system_server` 還沒登記它的時候,這是預期中的——等開機完成,不要斷定這台顯示器沒有密度。 |
會改變什麼,以及怎麼回頭
和尺寸覆寫一樣,它會跨過重新開機留下來,並改變手機上每個介面元素的縮放,設定 app 也包含在內。在手機面板上把密度設成 800,畫面上大概只看得到一個半按鈕,而你沒辦法靠點擊脫身。`wm density reset` 是回頭的路,在實驗之前先放在手邊。
版本與廠商注意事項
- 只改密度、或只改尺寸,會做出一個不存在的裝置形狀。兩個都要設。
- 0 與大得離譜的值不是測螢幕的方法,是讓螢幕變得看不懂的方法。
這個我們有 UI
Android ADB Toolbox 會透過 USB 執行這個指令並解析回應——只要 Chromium 系瀏覽器,不必安裝 SDK,也不會上傳任何東西。
相關指令
和 wm density 會在同一次作業裡出現的指令。
| 指令 | 做什麼 |
|---|---|
| wm size | 回報顯示器的解析度,或覆寫它,讓手機假裝自己是另一塊螢幕。 |
| screencap | 擷取螢幕畫面,可以寫進手機裡的檔案,也可以把 PNG 送到標準輸出。 |
| settings put | 把值寫進設定提供者——多數開發者選項小技巧背後的機制。 |
其他畫面與擷取指令
| 指令 | 做什麼 |
|---|---|
| screenrecord | 把螢幕錄成裝置上的一個 MP4 檔。 |
這些行為是在撰寫 Web ADB 工具背後的解析程式時,對照 AOSP、toybox 與核心原始碼查證的。真的會因 Android 版本或廠牌而異的地方,這一頁會直接說明,而不是給你一個在半數手機上都是錯的數字。