ADB 按鍵輸入

ADB shell command 裡有個 input,可以用來輸入文字或觸發鍵盤的事件。

$ input
usage: input [text|keyevent]
       input text <string>
       input keyevent <event_code>

首先來看 input keyevent <event_code>,例如:

$ input keyevent 3

Home 鍵的 key code 是 3,所以 input keyevent 3 可以模擬使用者按下 Home 鍵的效果。其他常用的 key code 有:

  • KEYCODE_HOME (3)
  • KEYCODE_BACK (4)
  • KEYCODE_SPACE (62)
  • KEYCODE_ENTER (66)
  • KEYCODE_MENU (82)

完整的清單可以參考這裡

接著來看 input text <string>,通常只要先讓文字輸入框取得焦點,然後把要輸入的文字接在 input text 後面即可:

$ input text hello
$
$ input text android&java 1
java: not found
[1]   Done                    input text android
$ input text 'android&java'
$
$ input text hello world 2
$ input text 'hello world'
$
$ input text hello
$ input keyevent 62
$ input text world
$
$ input text 你好 3
/mnt/.lfs: Function not implemented
/mnt/secure/asec: Permission denied
rename(/data/log/dumpstate_sys_error.txt.gz.tmp, /data/log/dumpstate_sys_error.txt.gz): Operation not permitted
Unable to chmod /data/log/dumpstate_sys_error.txt.gz: Operation not permitted
[1]   Killed                  input text 你好
1 & 在 shell 有特殊的意義,所以畫面上只出現 hello& 後面的 java 被視為另外一個指令;包在單引號裡就不會有問題了。
2 只會輸出 hello,空白字元後面的 " world" 全不見了,用單引號框起來或是把 software keyboard 整個收起來都沒用(跟輸入法無關?)。一個可行的解決方法,就是混用 input textinput keyevent,其中 62 是空白字元的 key code。
3 顯然 input text 目前還不支援非英數字元。
Tip 由於 input text 背後是送出 raw keyevent,所以想要透過它來輸入 unicode 是行不通的,不過倒可以試試透過 clipboard 來交換文字

撇開文字內容包含空白、特殊符號或非英數字的限制,就算是第一個 input text hello 這麼簡單的動作,都可能會失敗,原因就出在使用者開始要輸入文字之前,對螢幕點選的動作會叫輸入法的 software keyboard。input text 背後其實是送出一連串的 keyevent(也就是說,改用 input keyevent 也會有相同的問題),感覺 keyevent 會先被吃進 software keyboard 再轉換成對應的文字,因此最後的結果往往不如預期(字首變成大寫、只出現部份文字…)。

AndADBInput/ime_hello.png

Figure 1. 在 Samsung Galaxy S2 上採用 Chinese Keypad 時,input text hello 累積成一串無效的拼音

遇到這種情形,通常只要事先用 Back 鍵將輸入法收回去即可,keyevent 就不會先由輸入法過一手。不過某些 App 在按下 Back 鍵之後,輸入的焦點就會跟著移開,導致輸入的文字無法進到該文字輸入框,這時候只好透過 ime 切換輸入法來避開這個問題(每一種輸入法影響的程度不一)。下面示範在 Samsung Galaxy S2 上的做法:

$ ime list -a -s
com.swype.android.inputmethod/.SwypeInputMethod
com.samsung.inputmethod/.SamsungIME
com.sec.android.inputmethod.axt9/.AxT9IME
$
$ ime set com.samsung.inputmethod/.SamsungIME 1
Input method com.samsung.inputmethod/.SamsungIME selected
$ input text http://www.google.com.tw         2
$ input ABCabc123
$
$ ime set com.sec.android.inputmethod.axt9/.AxT9IME
Input method com.sec.android.inputmethod.axt9/.AxT9IME selected
$ input text http://www.google.com.tw         3
$ input text ABCabc123
1 別懷疑,com.sec.android.inputmethod.axt9/.AxT9IME 是 Samsung Keypad,com.samsung.inputmethod/.SamsungIME 才是會出狀況的 Chinese Keypad。
2 搭配 Chinese Keypad 時,輸入的網址會變成 http://www:google:com(句點全變成冒號了),下一行文字則變成 ABCAbc123(中間那個 a 被轉成大寫 A 了)。
3 切換回 Samsung Keypad 之後,兩串文字都能正常地輸入了。

一路測試下來,似乎沒有一個方法是萬無一失的。這裡總結一下不同的做法:

  • 要輸入 unicode,只能 透過 clipboard 來交換文字,而且會涉及 UI 的操作(長按後選 Paste,而且貼上的動作不一定有支援)。
  • 如果輸入法的 software keyboard 可以用 Back 鍵關閉,而且輸入的焦點不會跑掉,直接用 input event 輸入英數字即可。
  • 如果輸入的焦點會因為關閉輸入法的 software keyboard 跑掉,只好事先切換到不會出狀況的輸入法,不過每台裝置安裝的輸入法不同,是這個方法最大的缺點。

延伸閱讀


參考資料

其他文件