android測試之getevent/sendevent

http://source.android.com/devices/tech/input/index.html


關於在android平臺上捕獲事件的資料互聯網上已經鋪天蓋地,但個人覺得可用性都不太大,大部僅 

針對特定設備,而對於其他設備引導性不強,故整理處本文,望對初學者有個有力的幫助: 

getevent 旨在獲取android設備的事件信息,具體參考詳細用法(本人亦初學者一枚,無法深入解釋) 
sendevent 則可以向設備發送模擬事件,其中包括touch和keypress 

詳細用法如下: 

  1. Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] [-c count] [-r] [device]  

  2.    -t: show time stamps  

  3.    -n: don't print newlines  

  4.    -s: print switch states for given bits  

  5.    -S: print all switch states  

  6.    -v: verbosity mask (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32, props=64)  

  7.    -d: show HID descriptor, if available  

  8.    -p: show possible events (errs, dev, name, pos. events)  

  9.    -i: show all device info and possible events  

  10.    -l: label event types and names in plain text  

  11.    -q: quiet (clear verbosity mask)  

  12.    -c: print given number of events then exit  

  13.    -r: print rate events are received  

  14. Usage: sendevent <device> <type> <code> <value>  



首先,adb shell進入android設備,運行getevent命令得到如下信息,爲各類事件的驅動設備,每部 

硬件可能都不一樣,可以說無規律可循,個人覺得掠過吧 
  1. add device 1: /dev/input/event1  

  2.  name:     "pmic8xxx_pwrkey"

  3. add device 2: /dev/input/event3  

  4.  name:     "apq8064-tabla-snd-card Headset Jack"

  5. add device 3: /dev/input/event2  

  6.  name:     "apq8064-tabla-snd-card Button Jack"

  7. add device 4: /dev/input/event5  

  8.  name:     "gpio-keys"

  9. could not get driver version for /dev/input/mice, Not a typewriter  

  10. add device 5: /dev/input/event0  

  11.  name:     "atmel_mxt_ts"

  12. add device 6: /dev/input/event4  

  13.  name:     "mhl_rcp"



在點擊設備屏幕之後得到: 
  1. /dev/input/event0: 00030039 000002a5  

  2. /dev/input/event0: 0003003000000004

  3. /dev/input/event0: 00030035 0000017b  

  4. /dev/input/event0: 00030036 000001cf  

  5. /dev/input/event0: 0003 003a 0000001c  

  6. /dev/input/event0: 0000000000000000

  7. /dev/input/event0: 00030039 ffffffff  

  8. /dev/input/event0: 0000000000000000


很難辨認,加-l參數後得到 ( getevent -l ) 
  1. /dev/input/event0: EV_ABS       ABS_MT_TRACKING_ID     000002a6  

  2. /dev/input/event0: EV_ABS       ABS_MT_TOUCH_MAJOR   00000004

  3. /dev/input/event0: EV_ABS       ABS_MT_POSITION_X      0000017b  

  4. /dev/input/event0: EV_ABS       ABS_MT_POSITION_Y      000001cf  

  5. /dev/input/event0: EV_ABS       ABS_MT_PRESSURE         0000001c  

  6. /dev/input/event0: EV_SYN       SYN_REPORT                  00000000

  7. /dev/input/event0: EV_ABS       ABS_MT_TRACKING_ID     ffffffff  

  8. /dev/input/event0: EV_SYN       SYN_REPORT                  00000000


格式爲 device: type code value,即 設備、輸入設備類型、按鍵掃描碼、附加碼,具體定義可從kernel/include/linux/input.h中獲得,至於這個頭文件,途徑之一是從google官網源碼中獲取: 

type: 輸入設備類型,在手機系統中經常使用的鍵盤(keyboard)和小鍵盤(kaypad)屬於按鍵設 
備EV_KEY,軌跡球屬於相對設備EV_REL,觸摸屏屬於絕對設備EV_ABS 
code: 按鍵掃描碼,區別於ASCII碼和SDK中KeyEvent的鍵碼 
value: 附加碼,1/0 down/up 

第一行:可理解爲一次touch的開始 
第2行:可理解爲點擊開始 
第3行:觸摸點x座標 
第4行:觸摸點y座標 
第5行:可理解爲觸摸點大小 
第6行:事件同步(點擊結束) 
第7行:一次touch結束 
第8行:事件同步(事件結束) 

一次touch此8行是必須的,如果是longTouch呢,在touch的基礎上,重複若干次第2~6行,即看起 
來可能是這樣子: 
  1. /dev/input/event0: EV_ABS       ABS_MT_TRACKING_ID     000002a6  

  2. /dev/input/event0: EV_ABS       ABS_MT_TOUCH_MAJOR   00000004

  3. /dev/input/event0: EV_ABS       ABS_MT_POSITION_X      0000017b  

  4. /dev/input/event0: EV_ABS       ABS_MT_POSITION_Y      000001cf  

  5. /dev/input/event0: EV_ABS       ABS_MT_PRESSURE         0000001c  

  6. /dev/input/event0: EV_SYN       SYN_REPORT                  00000000

  7. /dev/input/event0: EV_ABS       ABS_MT_TOUCH_MAJOR   00000004

  8. /dev/input/event0: EV_ABS       ABS_MT_POSITION_X      0000017b  

  9. /dev/input/event0: EV_ABS       ABS_MT_POSITION_Y      000001cf  

  10. /dev/input/event0: EV_ABS       ABS_MT_PRESSURE         0000001c  

  11. /dev/input/event0: EV_SYN       SYN_REPORT                  00000000

  12. /dev/input/event0: EV_ABS       ABS_MT_TOUCH_MAJOR   00000004

  13. /dev/input/event0: EV_ABS       ABS_MT_POSITION_X      0000017b  

  14. /dev/input/event0: EV_ABS       ABS_MT_POSITION_Y      000001cf  

  15. /dev/input/event0: EV_ABS       ABS_MT_PRESSURE         0000001c  

  16. /dev/input/event0: EV_SYN       SYN_REPORT                  00000000

  17. ......  

  18. /dev/input/event0: EV_ABS       ABS_MT_TRACKING_ID     ffffffff  

  19. /dev/input/event0: EV_SYN       SYN_REPORT                  00000000



如果是drag呢,在longTouch的基礎上,xy座標從起點到終點是漸變的,其他可認爲一樣。 



對於按鍵,HOME爲例,一目瞭然: 
  1. /dev/input/event0: 0001006600000001

  2. /dev/input/event0: 0000000000000000

  3. /dev/input/event0: 0001006600000000

  4. /dev/input/event0: 0000000000000000

  5. /dev/input/event0: EV_KEY       KEY_HOME             DOWN  

  6. /dev/input/event0: EV_SYN       SYN_REPORT          00000000

  7. /dev/input/event0: EV_KEY       KEY_HOME             UP  

  8. /dev/input/event0: EV_SYN       SYN_REPORT          00000000



所以清楚了之後,使用sendevent進行事件模擬就很輕鬆了,關鍵是從input.h中獲取按鍵對應的掃 

描碼,也許每個版本的系統中input.h的內容都稍有不同,這個很頭疼。 

值得注意的是使用getevent獲取的數值都是16進制的,而sendevent使用的是10進制的,需要進行 

轉換。 

如點擊座標: 120,254 
  1. sendevent /dev/input/event1 0003005700000000      <---事件開始  

  2. sendevent /dev/input/event1 0003004800000010      <---點擊開始  

  3. sendevent /dev/input/event1 0003005800000070      <---  觸摸範圍  

  4. sendevent /dev/input/event1 0003005300000120      <---  x座標  

  5. sendevent /dev/input/event1 0003005400000254      <---  y座標  

  6. sendevent /dev/input/event1 0000000000000000      <---點擊結束(同步)  

  7. sendevent /dev/input/event1 000300574294967295        <---事件結束  

  8. sendevent /dev/input/event1 0000000000000000      <---事件同步  


翻譯爲: 
type code value 
EV_ABS ABS_MT_TRACKING_ID 00000000 <---事件開始 
EV_ABS ABS_MT_TOUCH_MAJOR00000010 <---點擊開始 
EV_ABS ABS_MT_PRESSURE 00000070 <--- 觸摸範圍 
EV_ABS ABS_MT_POSITION_X 00000120 <--- x座標 
EV_ABS ABS_MT_POSITION_Y 00000254 <--- y座標 
EV_SYN SYN_REPORT 00000000 <---點擊結束(同步) 
EV_ABS ABS_MT_TRACKING_ID 4294967295<---事件結束 
EV_SYN SYN_REPORT 00000000 <---事件同步 



對於longTouch,重複幾次上面提到的步驟,而drag再弄個座標漸變。 

按鍵方面(MENU) DOWN:1 UP:0 
  1. sendevent /dev/input/event0 000101020000000001

  2. sendevent /dev/input/event0 000000000000000000

  3. sendevent /dev/input/event0 000101020000000000

  4. sendevent /dev/input/event0 000000000000000000

  5. EV_KEY       KEY_MENU             DOWN  

  6. EV_SYN       SYN_REPORT         00000000

  7. EV_KEY       KEY_MENU             UP  

  8. EV_SYN       SYN_REPORT         00000000


此外還可以模擬可見字符按鍵。 




到這裏是否覺得getevent好用好理解,但sendevent卻超級麻煩。沒關係,如果真不想用sendevent 

模擬事件的話,可以轉向input命令。 

個人覺得這個input命令是個重量級的東東,調用時間非常長,貌似低系統版本和高系統版本的input提 

供的功能還不一樣,但它畢竟好用啊,如下: 
  1. usage: input ...  

  2.       input text <string>  

  3.       input keyevent <key code number or name>  

  4.       input tap <x> <y>  

  5.       input swipe <x1> <y1> <x2> <y2>  


可見除了longTouch無法模擬之外,其他的都很簡便了 

輸入文本: input text abcdefg 
按鍵 : input keyevent KEYCODE_MENU 
點擊 : input tap 100 300 
拖拽 : input swipe 100 600 500 600 

①對於文本輸入,以下字符需要加 \ 進行轉義: 
` ' " ~ # & ( ) | \ ; < > 

②對於longTouch,使用input如何模擬? 

③最後,在android中不管使用sendevent或者input,如何能模擬輸入非ASCII字符呢,比如中文? 

這是個難題


命令格式2:adb shell sendevent [device] [type] [code] [value]

  如: adb shell sendevent /dev/input/event0 1 229 1 代表按下按下menu鍵

  adb shell sendevent /dev/input/event0 1 229 0 代表按下鬆開menu鍵

  說明:上述的命令需組合使用

  另外所知道的命令如下:

  Key Name                        CODE

  MENU                                 229

  HOME                                 102

  BACK (back button)            158

  CALL (call button)               231

  END (end call button)         107

  2. 發送鼠標事件(Touch):

  命令格式:adb shell sendevent [device] [type] [code] [value]

  情況1:在某座標點上touch

  如在屏幕的x座標爲40,y座標爲210的點上touch一下,命令如下

  adb shell sendevent /dev/input/event0 3 0 40
  adb shell sendevent /dev/input/event0 3 1 210
   
  adb shell sendevent /dev/input/event0 1 330 1 //touch
  adb shell sendevent /dev/input/event0 0 0 0       //it must have
   
  adb shell sendevent /dev/input/event0 1 330 0 //untouch
  adb shell sendevent /dev/input/event0 0 0 0 //it must have

  注:以上六組命令必須配合使用,缺一不可

  情況2:模擬滑動軌跡(可下載並採用aPaint軟件進行試驗)

  如下例是在aPaint軟件上畫出一條開始於(100,200),止於(108,200)的水平直線

  adb shell sendevent /dev/input/event0 3 0 100 //start from point (100,200)
  adb shell sendevent /dev/input/event0 3 1 200
   
  adb shell sendevent /dev/input/event0 1 330 1 //touch
  adb shell sendevent /dev/input/event0 0 0 0
   
  adb shell sendevent /dev/input/event0 3 0 101 //step to point (101,200)
  adb shell sendevent /dev/input/event0 0 0 0
  ……………………                                                  //must list each step, here just skip
  adb shell sendevent /dev/input/event0 3 0 108 //end point(108,200)
  adb shell sendevent /dev/input/event0 0 0 0
   
  adb shell sendevent /dev/input/event0 1 330 0 //untouch
  adb shell sendevent /dev/input/event0 0 0 0


發佈了17 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章