1. 程式人生 > >和菜鳥一起學android4.0.3原始碼之按鍵驅動短長按功能

和菜鳥一起學android4.0.3原始碼之按鍵驅動短長按功能

第一:按鍵ADB除錯

   通過使用adb shell getevent,可以得到如下裝置操作後的指令,具體表示的含義,可以參考網上很多的文章,這裡就不再敘述



這裡的0035和0036分別表示螢幕上的X座標和Y座標,後面的值表示具體的座標點,通過16進位制轉換可以得到值1142和1527,而我手機的螢幕解析度為800*480的,很明顯兩個點是完全不匹配,那如何轉換呢?

在cmd中輸入adb shell getevent -p


找到您的螢幕裝置中0035和0036的含義,我的手機中可以看到x的值min為0,max為1172,y的值min為0,max為1900。
這樣就找到您的裝置的座標具體大小值,這裡計算公式如下:


x=(x-xmin)*480/(xmax-xmin) ;
y=(y-ymin)*800/(ymax-ymin);

這樣算出的座標值就跟您手機的螢幕解析度相匹配了。
該公式是通過檢視androidvncserver原始碼,然後反向推出的公式,目前碰到的手機min都為0,未測試過不過為0的情況,如果不為0的情況這個公式是錯誤的,請各位同學補充。

getevent/sendevent原始碼

這兩個命令的原始碼在system/core/toolbox/下,sendevent.c getevent.c

getevent

使用getevent獲得/dev/input/eventX裝置彙報的事件,這個命令還會輸出所有event裝置的基本資訊,如下:

add device 1: /dev/input/event1
  name:     "mxc_ts"
add device 2: /dev/input/event0
  name:     "mxckpd"

表明系統有兩個event裝置,分別對應著input裝置touchscreen,keyboard

Android可以使用sendevent來模擬觸屏,鍵盤以及其他型別的event事件,

sendevent /dev/input/eventX type code value

/dev/input/eventX 對應一個event裝置,可以通過getevent獲得可用的event裝置

type, code, value的定義可參看kernel/include/linux/input.h

type如下定義

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

一般來說,常用的是EV_KEY, EV_REL, EV_ABS, EV_SYN

分別對應keyboard, 相對座標, 絕對座標, 同步事件

EV_SYN則表示一組完整事件已經完成,需要處理,EV_SYN的code定義事件分發的型別

EV_SYN對應的code如下

  1. /*  
  2.  * Synchronization events.  
  3.  */  
  4. #define SYN_REPORT      0  
  5. #define SYN_CONFIG      1  
  6. #define SYN_MT_REPORT       2  

EV_KEY的code比較多,這裡就不列出來了,可參照input.h

EV_REL對應的code

  1. /*  
  2.  * Relative axes  
  3.  */  
  4. #define REL_X           0x00  
  5. #define REL_Y           0x01  
  6. #define REL_Z           0x02  
  7. #define REL_RX          0x03  
  8. #define REL_RY          0x04  
  9. #define REL_RZ          0x05  
  10. #define REL_HWHEEL      0x06  
  11. #define REL_DIAL        0x07  
  12. #define REL_WHEEL       0x08  
  13. #define REL_MISC        0x09  
  14. #define REL_MAX         0x0f  
  15. #define REL_CNT         (REL_MAX+1)  

EV_ABS對應的code
  1. /*  
  2.  * Absolute axes  
  3.  */  
  4. #define ABS_X           0x00  
  5. #define ABS_Y           0x01  
  6. #define ABS_Z           0x02  
  7. #define ABS_RX          0x03  
  8. #define ABS_RY          0x04  
  9. #define ABS_RZ          0x05  
  10. #define ABS_THROTTLE        0x06  
  11. #define ABS_RUDDER      0x07  
  12. #define ABS_WHEEL       0x08  
  13. #define ABS_GAS         0x09  
  14. #define ABS_BRAKE       0x0a  
  15. #define ABS_HAT0X       0x10  
  16. #define ABS_HAT0Y       0x11  
  17. #define ABS_HAT1X       0x12  
  18. #define ABS_HAT1Y       0x13  
  19. #define ABS_HAT2X       0x14  
  20. #define ABS_HAT2Y       0x15  
  21. #define ABS_HAT3X       0x16  
  22. #define ABS_HAT3Y       0x17  
  23. #define ABS_PRESSURE        0x18  
  24. #define ABS_DISTANCE        0x19  
  25. #define ABS_TILT_X      0x1a  
  26. #define ABS_TILT_Y      0x1b  
  27. #define ABS_TOOL_WIDTH      0x1c  
  28. #define ABS_VOLUME      0x20  
  29. #define ABS_MISC        0x28  
  30. #define ABS_MT_TOUCH_MAJOR  0x30    /* Major axis of touching ellipse */  
  31. #define ABS_MT_TOUCH_MINOR  0x31    /* Minor axis (omit if circular) */  
  32. #define ABS_MT_WIDTH_MAJOR  0x32    /* Major axis of approaching ellipse */  
  33. #define ABS_MT_WIDTH_MINOR  0x33    /* Minor axis (omit if circular) */  
  34. #define ABS_MT_ORIENTATION  0x34    /* Ellipse orientation */  
  35. #define ABS_MT_POSITION_X   0x35    /* Center X ellipse position */  
  36. #define ABS_MT_POSITION_Y   0x36    /* Center Y ellipse position */  
  37. #define ABS_MT_TOOL_TYPE    0x37    /* Type of touching device */  
  38. #define ABS_MT_BLOB_ID      0x38    /* Group a set of packets as a blob */  
  39. #define ABS_MT_TRACKING_ID  0x39    /* Unique ID of initiated contact */  
  40. #define ABS_MT_PRESSURE     0x3a    /* Pressure on contact area */  
  41. #define ABS_MAX         0x3f  
  42. #define ABS_CNT         (ABS_MAX+1)  


input keyevent

如果想模擬按鍵,send event用起來比較繁瑣,可以用input keyevent代替

下面是input keyevent幾個比較常用的用法:

input keyevent 3    // Home

input keyevent 4    // Back

input keyevent 19  //Up

input keyevent 20  //Down

input keyevent 21  //Left

input keyevent 22  //Right

input keyevent 23  //Select/Ok

input keyevent 24  //Volume+

input keyevent 25  // Volume-

input keyevent 82  // Menu 選單

用senevent 模擬觸屏事件

sendevent /dev/input/event1 0003 0000 0000015e    // ABS x 座標

sendevent /dev/input/event1: 0003 0001 000000df    // ABS y 座標

sendevent /dev/input/event1: 0001 014a 00000001   // BTN touch事件 值為1

sendevent /dev/input/event1: 0003 0018 00000000   // ABS pressure事件

sendevent /dev/input/event1: 0001 014a 00000000   // BTN touch事件 值為0

sendevent /dev/input/event1: 0000 0000 00000000   // sync事件


adb命令可以模擬簡單的按鍵事件,當觸控式螢幕不好使的時候就可以用咯。上篇有提到adb devices命令,就是用usb連線到手機或平板,這個時候就可以用adb shell 命令開啟手機或平板終端了。輸入input 回車有:

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

你可以輸入:input text "字串"

或一些按鍵事件:input keyevent Num

解鎖:input keyevent 83

向上:input keyevent 19

向下:input keyevent 20

向左:input keyevent 21

向右:input keyevent 22

等等。。。。

以下就是約定的按鍵鍵碼:

0 -->  "KEYCODE_UNKNOWN"
1 -->  "KEYCODE_MENU"
2 -->  "KEYCODE_SOFT_RIGHT"
3 -->  "KEYCODE_HOME"
4 -->  "KEYCODE_BACK"
5 -->  "KEYCODE_CALL"
6 -->  "KEYCODE_ENDCALL"
7 -->  "KEYCODE_0"
8 -->  "KEYCODE_1"
9 -->  "KEYCODE_2"
10 -->  "KEYCODE_3"
11 -->  "KEYCODE_4"
12 -->  "KEYCODE_5"
13 -->  "KEYCODE_6"
14 -->  "KEYCODE_7"
15 -->  "KEYCODE_8"
16 -->  "KEYCODE_9"
17 -->  "KEYCODE_STAR"
18 -->  "KEYCODE_POUND"
19 -->  "KEYCODE_DPAD_UP"
20 -->  "KEYCODE_DPAD_DOWN"
21 -->  "KEYCODE_DPAD_LEFT"
22 -->  "KEYCODE_DPAD_RIGHT"
23 -->  "KEYCODE_DPAD_CENTER"
24 -->  "KEYCODE_VOLUME_UP"
25 -->  "KEYCODE_VOLUME_DOWN"
26 -->  "KEYCODE_POWER"
27 -->  "KEYCODE_CAMERA"
28 -->  "KEYCODE_CLEAR"
29 -->  "KEYCODE_A"
30 -->  "KEYCODE_B"
31 -->  "KEYCODE_C"
32 -->  "KEYCODE_D"
33 -->  "KEYCODE_E"
34 -->  "KEYCODE_F"
35 -->  "KEYCODE_G"
36 -->  "KEYCODE_H"
37 -->  "KEYCODE_I"
38 -->  "KEYCODE_J"
39 -->  "KEYCODE_K"
40 -->  "KEYCODE_L"
41 -->  "KEYCODE_M"
42 -->  "KEYCODE_N"
43 -->  "KEYCODE_O"
44 -->  "KEYCODE_P"
45 -->  "KEYCODE_Q"
46 -->  "KEYCODE_R"
47 -->  "KEYCODE_S"
48 -->  "KEYCODE_T"
49 -->  "KEYCODE_U"
50 -->  "KEYCODE_V"
51 -->  "KEYCODE_W"
52 -->  "KEYCODE_X"
53 -->  "KEYCODE_Y"
54 -->  "KEYCODE_Z"
55 -->  "KEYCODE_COMMA"
56 -->  "KEYCODE_PERIOD"
57 -->  "KEYCODE_ALT_LEFT"
58 -->  "KEYCODE_ALT_RIGHT"
59 -->  "KEYCODE_SHIFT_LEFT"
60 -->  "KEYCODE_SHIFT_RIGHT"
61 -->  "KEYCODE_TAB"
62 -->  "KEYCODE_SPACE"
63 -->  "KEYCODE_SYM"
64 -->  "KEYCODE_EXPLORER"
65 -->  "KEYCODE_ENVELOPE"
66 -->  "KEYCODE_ENTER"
67 -->  "KEYCODE_DEL"
68 -->  "KEYCODE_GRAVE"
69 -->  "KEYCODE_MINUS"
70 -->  "KEYCODE_EQUALS"
71 -->  "KEYCODE_LEFT_BRACKET"
72 -->  "KEYCODE_RIGHT_BRACKET"
73 -->  "KEYCODE_BACKSLASH"
74 -->  "KEYCODE_SEMICOLON"
75 -->  "KEYCODE_APOSTROPHE"
76 -->  "KEYCODE_SLASH"
77 -->  "KEYCODE_AT"
78 -->  "KEYCODE_NUM"
79 -->  "KEYCODE_HEADSETHOOK"
80 -->  "KEYCODE_FOCUS"
81 -->  "KEYCODE_PLUS"
82 -->  "KEYCODE_MENU"
83 -->  "KEYCODE_NOTIFICATION"
84 -->  "KEYCODE_SEARCH"
85 -->  "TAG_LAST_KEYCODE"


3>底層驅動

一切再次回到原點,一切都又開始了正常的路線,上班,下班。每每一個人回到那小小的屋子,覺得什麼也不是。想離開,又不知道要去哪。日子還是一天天過去,地球不因任何人改變它的轉速,月亮也不會為了誰而改變她的形狀。平靜,也許就是一種幸福。

上週由於其他部門需要用我們的晶片,得模擬個input裝置,用以mcu按鍵傳遞過來後的處理。所以只能屁顛屁顛地去實現了,還好以前做過類似的驅動,於是很快就實現了這個功能。但是一直對於android長按鍵功能和短按鍵功能表示不解。網上也很少講到驅動時怎麼取實現的。一直以為那個

  1. input_report_key(btn_dev, KEY_POWER, 0);  
  2. input_report_key(btn_dev, KEY_POWER, 1);  


這句話是表示按鍵的按下和擡起,其實錯了,是value值為1的時候表示是按鍵按下,而value值是0的時候才是表示按鍵的擡起,而每次都需要傳送一個

  1. input_sync(btn_dev);  


這樣才表示是整個過程,才可以實現按鍵的長按和短按的功能。也就是下面的方式:

  1. input_report_key(btn_dev, KEY_POWER, 1);  
  2. input_sync(btn_dev);  


這個表示的是按鍵被按下了。

  1. input_report_key(btn_dev, KEY_POWER, 0);  
  2. input_sync(btn_dev);  


這個表示按鍵被擡起了。

這兩個之間是表示按鍵按下的時間長度,android上層就是通過這個來實現按鍵的短按和長按的功能的。

下面用簡單的驅動和簡單的應用才實現android的按鍵的功能,無需真實的按鍵就可以測試了。

下面的驅動和我的那篇input子系統例項的驅動很類似

  1. #include <linux/slab.h>
  2. #include <linux/irq.h>
  3. #include <linux/interrupt.h

    相關推薦

    一起android4.0.3原始碼按鍵驅動功能

    第一:按鍵ADB除錯    通過使用adb shell getevent,可以得到如下裝置操作後的指令,具體表示的含義,可以參考網上很多的文章,這裡就不再敘述 這裡的0035和0036分別表示螢幕上的X座標和Y座標,後面的值表示具體的座標點

    一起android4.0.3原始碼touchscreen配置+除錯記錄

            記得應該是上上週了,終於畢業了,離開了學校,就得面對現實的社會,以前學校實驗室裡,老師給了鑰匙,那電腦隨便用,那元器件隨便玩,什麼51微控制器啊,PIC微控制器啊,FPGA啊,arm11啊什麼的。想著做什麼就直接萬用版+電烙鐵什麼的一起搞定。除錯,寫程式,焊

    一起android4.0.3原始碼wifi的簡單分析

    關於wlan的組成   關於wifi應用層的介面的呼叫         首先從上層android wifi的應用開始,首先會根據android的wifimanager的類,例項化一個mwifimanager的物件,這個物件處理了所有wifi需要處理的任務,接著比如說開啟wi

    一起cgcc編譯過程及其常用編譯選項

           上篇文章,知道了,C程式碼編譯後存放在記憶體中的位置,那麼C程式碼的整個編譯過程又是怎樣的呢?一條命令gcc hello.c就可以編譯成可執行程式a.out,然後./a.out之後就可以

    一起演算法三分法求極值問題

              午後的陽光,那麼燦爛,如果不是溫度過高,那麼去西湖看看風景還是不錯的。想著,現在西湖邊應該是平靜的湖面,加上無數知了在柳枝上演奏著交響曲吧。小看了下非誠勿擾,那男生為了女孩唐靜付出了7年,唉,可是他錯了,女孩根本不愛他,不過期間他的執著和付出,很讓我感動

    一起linuxwifi學習記錄

    也差不多一個月沒有更新部落格了,元旦也過去了,8天的班也上完了,小病也好了,時間又回到了每個周的週末了,不知道幹嘛,突然發現好像失去了什麼,好像做了很多很多沒有意義的事,一直都是在原點打轉,不知道接下去會是什麼,不知道為了什麼。也許總會有一段日子覺得很迷茫,不知所措。這麼一

    ubuntu編譯android4.0.3原始碼

    1.ubuntu安裝 a.下載64位桌面版映象檔案ubuntu-12.10-desktop-amd64 b.下載EasyBCD     新增新條目——>NeoGrub——>安裝——>配置     新增     root (hd0,0)     kernel

    Android4.0.3修改啟動動畫開機聲音[轉載]

    1. Linux 系統啟動,出現Linux小企鵝畫面(reboot)(Android 1.5及以上版本已經取消載入圖片);   2. Android平臺啟動初始化,出現"A N D R I O D"文字字樣畫面; 3. Android平臺圖形系統啟動,出現含閃動的ANDRO

    從狀態模式看“大神””的差別

    err pri after dsm ets 大話設計模式 post else clas 《大話設計模式》中講狀態模式這一節名字叫做“無盡加班何時休-狀態模式”。菜鳥因為編程經驗不足,解決這個問題的能力不夠而不得不犧牲時間去不斷的寫代碼結果還是重復出錯。而大神

    新書 《跟一起學習Linux系統》發布

    linux 項目 實戰 本文出自 “民工哥博客” 博客,請務必保留此出處http://mingongge.blog.51cto.com/2429897/1977487新書 《跟菜鳥一起學習Linux系統》發布

    怎麼做爬蟲-1

    本文打算寫成一個系列,剛開始覺得我寫得比較淺,而園子裡比較高階,似乎有點不搭配,於是只放在了自己的部落格上,後來一想萬一有新入門的朋友想參考一下呢,於是就厚著臉皮也發在這吧。高手們請輕噴。   首先,說明一下我已經用python和C#完整實現了批量爬取微信公眾號歷史文章的功能,而且已經做成GUI

    馬雲的利他思想1300億的商業佈局

    神祕的北緯30° 金字塔、中東北海、百慕大三角、雅魯藏布大峽谷、喜馬拉雅山、神農架……,諸多百思不得其解的祕密都存在於這條線上。 浙江桐廬,就位於北緯30°,這裡的農民將創造一個偉大的奇蹟。 如果從歷史的天空打量,1993年是一個里程碑。 那年春天,上海市浦東新區正式成立,進出口貿易紅紅火火。也是這一

    可能是最簡單最容易的webservice案例(給初學者提供入門思路)

    伺服器端: 一共建立了三個類,一個介面,一個介面實現類,一個釋出類(main方法)。 具體如下: 介面: package service; import javax.jws.WebMethod; @javax.jws.WebService public interface Web

    如何在WINFORM中彈出一個又控制元件的對話方塊 能給個簡單的示範C#程式碼嗎 以及一些小問題

    如何在WINFORM中彈出一個又控制元件的對話方塊  能給個簡單的示範C#程式碼嗎順便問問 這段程式碼是啥意思啊        private void btn_catchMe_Click(object sender, System.EventArgs e)        {

    jQuery 2.0.3 原始碼分析 回溯魔法 end()pushStack()

    瞭解了jQuery對DOM進行遍歷背後的工作機制,可以在編寫程式碼時有意識地避免一些不必要的重複操作,從而提升程式碼的效能 從這章開始慢慢插入jQuery內部一系列工具方法的實現 關於jQuery物件的包裝 var $aaron = $("aaron"); 通過對sizzle的分析呢,jQue

    調錯——Hibernate 4.3.x 註解常見錯誤及解決方案

    程式設計的過程免不了遇到各種錯誤,各種問題,而遇到問題,解決問題的這個過程我認為是最讓人興奮的事情。越棘手的問題,解決以後帶來的快感也越大。當一個問題你搞了一下午或者一天,甚至幾天,當你解決的那一刻你會覺得你又獲得了重生。甚至會感覺此時此刻整個世界都是你的。 啊哦,扯的有點

    iTop4412開發板Android4.0.3映象OTG方式燒寫

    iTop4412開發板Android4.0.3映象OTG方式燒寫 最近開始學習linux,入手一塊訊為的iTop4412開發板,遵循訊為的框架學習法(畢竟科技更新速度如此之快,不可能什麼都學,必須要懂得抽象化,模組化思想),前階段學習一直難以入門,前階段看到一篇文章講解了uboot(全面

    一起Netty(五) 初識ByteBufByteBuf的常用API

      網路傳輸的載體是byte,這是任何框架誰也逃脫不了的一種規定,JAVA的NIO提供了ByteBuffer,用來完成這項任務,當然ByteBuffer也很好的完成了這個任務,Netty也提供了一個名字很相似的載體叫做ByteBuf,相比於ByteBuf而言,它有著更加更多

    C#編寫的區域網聊天工具(本Socket,拿來分享下~~~)

    class Server //服務端方法 { #region 繫結IP、埠 IniOperate io = new IniOperate("C:\\lwj.ini"); public Socket Bind()

    必練入侵命令 (3)

    <03>的話,那他前面的就是使用者。   這裡的使用者是PENTIUMII。   8:Shutdown   關了對方的NT伺服器的命令   Shutdown IP地址 t:20   20秒後將NT自動關閉,三思後才能執行這個命令,這樣對對方造很大的損失,要做個有良