2015年8月17日 星期一

[轉] [Android]getevent,sendevent,input命令的使用

http://myeyeofjava.iteye.com/blog/1999615

adb shell 進入avd或者真機後台: 

getevent 
getevent -r -q 監控設備的sendevent事件 

Java代碼  收藏代碼
  1. root@android:/ # getevent -h  
  2. Usage: getevent [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-d] [-p] [-i] [-l] [-q] [-c count] [-r] [device]  
  3.     -t: show time stamps  
  4.     -n: don't print newlines  
  5.     -s: print switch states for given bits  
  6.     -S: print all switch states  
  7.     -v: verbosity mask (errs=1, dev=2, name=4, info=8, vers=16, pos. events=32, props=64)  
  8.     -d: show HID descriptor, if available  
  9.     -p: show possible events (errs, dev, name, pos. events)  
  10.     -i: show all device info and possible events  
  11.     -l: label event types and names in plain text  
  12.     -q: quiet (clear verbosity mask)  
  13.     -c: print given number of events then exit  
  14.     -r: print rate events are received  


顯示格式說明 

Java代碼  收藏代碼
  1. root@android:/ # getevent  
  2. /dev/input/event5: 0005 0002 00000001  
  3. device的名字:事件類型    鍵碼類別  具體的數值  
  4.   
  5. /dev/input/event5: 0000 0000 00000000  
  6.   
  7. 表示一次輸入結束  


/* 
* Event types 
*/ 

Java代碼  收藏代碼
  1. #define EV_SYN            0x00  
  2. #define EV_KEY            0x01  
  3. #define EV_REL            0x02  
  4. #define EV_ABS            0x03  
  5. #define EV_MSC            0x04  
  6. #define EV_SW            0x05  
  7. #define EV_LED            0x11  
  8. #define EV_SND            0x12  
  9. #define EV_REP            0x14  
  10. #define EV_FF            0x15  
  11. #define EV_PWR            0x16  
  12. #define EV_FF_STATUS        0x17  
  13. #define EV_MAX            0x1f  
  14. #define EV_CNT            (EV_MAX+1)  


二. 具體應用, 比如需要查看audio jack的事件,也就是耳機的插入 

1. 首先確認耳機插入的事件是啥 
r
Java代碼  收藏代碼
  1. oot@android:/ # getevent -i                                                   
  2. add device 1: /dev/input/event2  
  3.   bus:      0000  
  4.   vendor    0000  
  5.   product   0000  
  6.   version   0000  
  7.   name:     "pmic8xxx_pwrkey"  
  8.   location: "pmic8xxx_pwrkey/input0"  
  9.   id:       ""  
  10.   version:  1.0.1  
  11.   events:  
  12.     KEY (0001): 0074   
  13.   input props:  
  14.     <none>  
  15. .....  
  16.   
  17. add device 5: /dev/input/event10  
  18.   bus:      0000  
  19.   vendor    0000  
  20.   product   0000  
  21.   version   0000  
  22.   name:     "msm8960-snd-card Headset Jack"  
  23.   location: "ALSA"  
  24.   id:       ""  
  25.   version:  1.0.1  
  26.   events:  
  27.     SW  (0005): 000200040006  000e  000f  0010   
  28.   input props:  
  29.     <none>  
  30. add device 6: /dev/input/event9  
  31.   bus:      0000  
  32.   vendor    0000  
  33.   product   0000  
  34.   version   0000  
  35.   name:     "msm8960-snd-card Button Jack"  
  36.   location: "ALSA"  
  37.   id:       ""  
  38.   version:  1.0.1  
  39.   events:  
  40.     KEY (0001): 0100  0101  0102  0103  0104  0105  0106  0107   
  41.   input props:  
  42.     <none>  

2. 輸出 audio jack事件 

用的event type是#define EV_SW            0x05 

Java代碼  收藏代碼
  1. /* 
  2.  * Switch events 
  3.  */  
  4.   
  5. #define SW_LID            0x00  /* set = lid shut */  
  6. #define SW_TABLET_MODE        0x01  /* set = tablet mode */  
  7. #define SW_HEADPHONE_INSERT    0x02  /* set = inserted */  
  8. #define SW_RFKILL_ALL        0x03  /* rfkill master switch, type "any" 
  9.                      set = radio enabled */  
  10. #define SW_RADIO        SW_RFKILL_ALL    /* deprecated */  
  11. #define SW_MICROPHONE_INSERT    0x04  /* set = inserted */  
  12. #define SW_DOCK            0x05  /* set = plugged into dock */  
  13. #define SW_LINEOUT_INSERT    0x06  /* set = inserted */  
  14. #define SW_JACK_PHYSICAL_INSERT 0x07  /* set = mechanical switch set */  
  15. #define SW_VIDEOOUT_INSERT    0x08  /* set = inserted */  
  16. #define SW_CAMERA_LENS_COVER    0x09  /* set = lens covered */  
  17. #define SW_KEYPAD_SLIDE        0x0a  /* set = keypad slide out */  
  18. #define SW_FRONT_PROXIMITY    0x0b  /* set = front proximity sensor active */  
  19. #define SW_ROTATE_LOCK        0x0c  /* set = rotate locked/disabled */  
  20. #define SW_LINEIN_INSERT    0x0d  /* set = inserted */  
  21. #define SW_HPHL_OVERCURRENT    0x0e  /* set = over current on left hph */  
  22. #define SW_HPHR_OVERCURRENT    0x0f  /* set = over current on right hph */  
  23. #define SW_UNSUPPORT_INSERT    0x10  /* set = unsupported device inserted */  
  24. #define SW_MAX            0x20  
  25. #define SW_CNT            (SW_MAX+1)  
  26. root@android:/ # getevent  /dev/input/event10   
  27.   
  28. 0005 0002 00000001 (0002  表示earphone)  
  29. 0005 0004 00000001 (0004  表示microphone)  
  30. 0000 0000 00000000  
  31.   
  32.     插入  拔出  
  33. Headset 0005 0002 00000001  
  34. 0005 0004 00000001  
  35. 0000 0000 00000000  0005 0002 00000000  
  36. 0005 0004 00000000  
  37. 0000 0000 00000000  
  38. Headphone   0005 0002 00000001  
  39. 0000 0000 00000000  0005 0002 00000000  
  40. 0000 0000 00000000  
  41. invalid 0005 0010 00000001  
  42. 0000 0000 00000000  0005 0010 00000000  
  43. 0000 0000 00000000  

三、具體應用, 比如需要查看touch的事件 
1、確認touch事件路徑 

root@android:/ # getevent -i     
add device 13: /dev/input/event7 
  bus:      0000 
  vendor    0000 
  product   0000 
  version   0000 
  name:     "cyttsp4_mt" 
  location: "cyttsp4_mt.main_ttsp_core" 
  id:       "" 
  version:  1.0.1 
  events: 
    ABS (0003): 0000  : value 0, min 0, max 0, fuzz 0, flat 0, resolution 0 
2、touch 事件 

用的event type是#define EV_ABS            0x03 

只分析多touch事件 
#define ABS_MT_SLOT        0x2f    /* MT slot being modified */ 
#define ABS_MT_TOUCH_MAJOR    0x30    /* Major axis of touching ellipse */ 
#define ABS_MT_TOUCH_MINOR    0x31    /* Minor axis (omit if circular) */ 
#define ABS_MT_WIDTH_MAJOR    0x32    /* Major axis of approaching ellipse */ 
#define ABS_MT_WIDTH_MINOR    0x33    /* Minor axis (omit if circular) */ 
#define ABS_MT_ORIENTATION    0x34    /* Ellipse orientation */ 
#define ABS_MT_POSITION_X    0x35    /* Center X ellipse position */   
#define ABS_MT_POSITION_Y    0x36    /* Center Y ellipse position */ 
#define ABS_MT_TOOL_TYPE    0x37    /* Type of touching device */ 
#define ABS_MT_BLOB_ID        0x38    /* Group a set of packets as a blob */ 
#define ABS_MT_TRACKING_ID    0x39    /* Unique ID of initiated contact */ 
#define ABS_MT_PRESSURE        0x3a    /* Pressure on contact area */ 
#define ABS_MT_DISTANCE        0x3b    /* Contact hover distance */ 
root@android:/ # getevent  /dev/input/event7 
單點觸摸 
0003 0039 000000d5  //觸點區分的唯一ID 
0003 0035 00000165 //觸點的x坐標 
0003 0036 000002fa  //觸點的y坐標 
0003 003a 00000025 //觸點的壓力,實際上是接觸區域大小 
0000 0000 00000000 //結束 

多點觸摸 

0003 0039 000000de 
0003 0035 00000140 
0003 0036 0000047f 
0003 003a 00000021 
0000 0000 00000000 
0003 0035 0000013f 
0003 003a 00000027 
0003 002f 00000001 //切換上報其中一點 
0003 0039 000000df 
0003 0035 000001fd 
0003 0036 000001e3 
0003 003a 00000022 
0000 0000 00000000 
0003 002f 00000000 //切換上報其中一點 
0003 0036 0000047e 
0003 003a 0000002b 
0000 0000 00000000 
0003 0036 0000047d 
0003 003a 0000002f 
0000 0000 00000000 
0003 0036 0000047b 
0003 003a 00000034 
0003 002f 00000001 //切換上報其中一點 
0003 0035 000001fc 
0003 0036 000001e6 
0003 003a 00000023 
0000 0000 00000000 

三、getevent 源代碼分析 
@system/core/toolbox/getevent.c 
int getevent_main(int argc, char *argv[]) 



      const char *device_path = "/dev/input";    //讀取的路徑 

      .... 

     res = scan_dir(device_path, print_flags); //掃瞄路徑下的所有文件路徑 

    .... 

    while(1) { 

        ... 
        res = read(ufds[i].fd, &event, sizeof(event)); //讀取事件 
       ... 

       print_event(event.type, event.code, event.value, print_flags); //打印出事件信息 
   } 


四、sendevent源代碼分析 

@system/core/toolbox/sendevent.c 

sendevent 
1. 模擬插入耳機, 這時候可以啟動收音機了(不再有耳機沒有的提示框) 
sendevent /dev/input/event10 0005 0002 00000001 

sendevent /dev/input/event10 0000 0000 00000000 


input 根據avd和真機的不同,參數可能不同 

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

4.可能遇到的問題 
實際實現的時候,還可能遇到問題 
一是root,getevent和sendevent需要/dev/input/event*的權限。一般應用是沒有這個權限的,需要在程序裡面獲取su後,執行chmod 666 /dev/input/event*。 
二是設備名稱。因為你不知道觸摸屏或者按鍵到底對應的event*是多少。需要有一個初始化的過程,大致思路是往event0-event9分別寫入按鍵和觸摸信號,同時監聽activity裡的onkeydown和view的onclick,這樣來偵測設備。 
三是廠商的實現不一樣,這個沒辦法,只能一個一個適配了,一般來說都還是標準的,有些廠商會有單獨的實現。
參考 
http://lxr.free-electrons.com/source/include/uapi/linux/input.h#L803 
http://source.android.com/tech/input/touch-devices.html 
http://cjix.info/blog/misc/internal-input-event-handling-in-the-linux-kernel-and-the-android-userspace/ 


推薦參考網址:http://www.jtben.com/document/919575