getevent
唯讀直接從核心串流原始輸入事件,或列出每個輸入裝置能回報什麼。
- 指令
- adb shell getevent
- 指令
- 輸入與觸控
- 風險
- 唯讀
語法
getevent [-l] [-t] [-p] [/dev/input/eventN]旗標與參數
| token | 意義 |
|---|---|
| -l | 印出核心的標籤名稱而不是純十六進位。 |
| -t | 在每個事件前面加上核心的單調時間戳。 |
| -p | 不串流,改成印出每個裝置的能力後結束。 |
| /dev/input/eventN | 只看一個裝置。這同時會讓每行的裝置前綴消失,因為那個前綴只在沒指定裝置時才印。 |
範例
getevent -lp每個輸入裝置及其軸與範圍。它會自己結束。
getevent -lt /dev/input/event3帶時間戳觀察一個觸控面板。
輸出怎麼讀
輸出範例
/dev/input/event3: EV_ABS ABS_MT_TRACKING_ID ffffffff
/dev/input/event3: EV_SYN SYN_REPORT 00000000一行三個欄位:事件 type、事件 code、數值。數值是以無號 32 位元十六進位印出來的,這是這裡最大的陷阱——tracking id 的 `ffffffff` 是 -1,也就是「手指離開」的訊號,而當成無號來讀就變成四十億,看起來像一個再平常不過的新接觸點。`SYN_REPORT` 是影格邊界:在它之前的都是半份封包,畫出來會看到座標只更新一半的手指。
輸出欄位
| 欄位 | 意義 |
|---|---|
| EV_ABS / EV_KEY / EV_SYN | 事件 type:絕對軸、按鍵,或同步標記。 |
| ABS_MT_SLOT | 選擇接下來的軸是在描述哪一個接觸點。 |
| ABS_MT_TRACKING_ID | 非負值代表一個接觸點開始;`ffffffff`(-1)代表結束。 |
| ABS_MT_POSITION_X / _Y | 以面板自己的單位表示的接觸點位置,不是螢幕像素。 |
| SYN_REPORT | 提交:到目前為止這個影格完成了。 |
| SYN_DROPPED | 核心的佇列滿了。請丟掉累積的狀態並重新同步。 |
| : value v, min a, max b, fuzz f, flat l, resolution r | 能力那一行,也是整份輸出裡唯一的十進位數字。`max` 是含上限的,所以 0 到 1439 的軸有 1440 個位置。 |
需要什麼權限
不用 root、不用 `adb root`——而且在這一家族裡很少見地,連 Android 權限都不需要。`/dev/input/*` 是 `ueventd.rc` 以 `0660 root input` 建出來的,所以打開一個 event 節點純粹是 Unix 群組的問題,而 `adbd` 是刻意去回答它的:它在放掉權限的時候,會給 shell 一組固定的附加群組,而那個陣列旁邊的註解點名的正是這個工具——`AID_INPUT to diagnose input issues (getevent)`。這就是為什麼在一台鎖著的量產手機上,很多東西讀不到,原始觸控資料卻可以從普通的 `adb shell` 讀出來,也是為什麼除了 USB 偵錯本身,開發者選項裡沒有東西在管它。有兩件事跟著而來。這個群組只給讀:每個節點都是用 `O_RDONLY` 開的,所以這一頁可以看數位板,但沒辦法合成一次觸控——那是 `input` 的工作,走的是另一套機制與另一個權限。而且錯誤回報本身也躲在旗標後面。裝置錯誤訊息只有在詳細度遮罩的 `errs` 位元被打開時才會印,在指令列上指名裝置會預設打開那個位元,但 `-q` 會把整個遮罩清掉——所以 `getevent -q /dev/input/event3` 在一個它打不開的節點上,會什麼都沒印就以非零結束。
失敗訊息對照
| 訊息 | 意義 |
|---|---|
| could not open /dev/input/event3, Permission denied | `open()` 失敗了,逗號後面那段是 C 函式庫的 `strerror`。`Permission denied` 代表這個行程不在 `input` 群組裡——常見原因是它不是 adbd 生出來的 shell,因為 adbd 自己會給那個群組。同一個位置出現 `No such file or directory` 則代表節點編號根本就錯了:用 `getevent -lp` 列出來,不要用猜的。 |
| could not get driver version for /dev/input/event3, Inappropriate ioctl for device | 節點打開了,但 `EVIOCGVERSION` 這個 ioctl 被拒絕,所以它不是一個 evdev 裝置。`getevent` 會放棄那個節點並以非零結束。手動指定路徑時看到它,通常代表你指到 `/dev/input` 底下某個不是 `eventN` 的東西。 |
| scan dir failed for /dev/input | 沒給裝置參數時 `getevent` 會去列舉整個目錄,而這是列舉本身失敗,不是某一個裝置失敗。它會立刻回傳 1,所以你連一點串流都拿不到——在怪面板之前,先確認 `/dev/input` 存在而且進得去。 |
| getevent: invalid option -z | 不認識的開關。後面會接著印出用法區塊,然後行程以 1 結束,什麼都沒打開。它值得知道,是因為這裡的旗標是可以綁在一起的單字母:`-lp` 就是 `-l -p`,而一串綁在一起的字母裡打錯一個,整次執行就一起倒。 |
版本與廠商注意事項
- 軸是黏著的:驅動程式只送有變化的部分,所以一根往橫向移動的手指會保留上一次的縱向位置。要累積而不是取代。
- 面板座標不是螢幕座標。對應方式是減掉軸的最小值,再乘上「螢幕尺寸 ÷(max − min + 1)」。那個 +1 不是硬湊的修正,而是因為最大值含上限。
- 某片面板相對於顯示器有沒有旋轉或鏡像安裝,是無法從軸的範圍推出來的,必須在真機上摸一個角落來確認。
- 加了 `-l` 之後數值可能是單字:按鍵的值會印成 UP、DOWN 或 REPEAT,tool type 會印成 MT_TOOL_FINGER、MT_TOOL_PEN 或 MT_TOOL_PALM。
這個我們有 UI
Android Sensor Tester 會透過 USB 執行這個指令並解析回應——只要 Chromium 系瀏覽器,不必安裝 SDK,也不會上傳任何東西。
相關指令
和 getevent 會在同一次作業裡出現的指令。
| 指令 | 做什麼 |
|---|---|
| dumpsys sensorservice | 手機上的每一個感測器,含廠商、type、取樣率與批次能力,以及一段近期讀數的緩衝。 |
| input text | 把一段字串打進目前取得焦點的輸入欄位。 |
| wm size | 回報顯示器的解析度,或覆寫它,讓手機假裝自己是另一塊螢幕。 |
其他輸入與觸控指令
| 指令 | 做什麼 |
|---|---|
| input keyevent | 按下實體或虛擬按鍵——Home、Back、電源、音量、Enter。 |
這些行為是在撰寫 Web ADB 工具背後的解析程式時,對照 AOSP、toybox 與核心原始碼查證的。真的會因 Android 版本或廠牌而異的地方,這一頁會直接說明,而不是給你一個在半數手機上都是錯的數字。