觸摸屏和軌跡球上報的是坐標、按下、抬起等信息,信息量比較少。按鍵處理的過程稍微復(fù)雜,從驅(qū)動程序到Android的Java層受到的信息,鍵表示方式經(jīng)過了兩次轉(zhuǎn)化,如圖8-4所示。
鍵掃描碼Scancode是由Linux的Input驅(qū)動框架定義的整數(shù)類型。鍵掃描碼Scancode經(jīng)過一次轉(zhuǎn)化后,形成按鍵的標簽KeycodeLabel,是一個字符串的表示形式。按鍵的標簽KeycodeLabel經(jīng)過轉(zhuǎn)換后,再次形成整數(shù)型的按鍵碼keycode。在Android應(yīng)用程序?qū)?,主要使用按鍵碼keycode來區(qū)分。
在本地框架層libui的頭文件中KeycodeLabels.h,按鍵碼為整數(shù)值的格式,其定義KeyCode(枚舉值)如下所示:
進而在定義了KeycodeLabels.h中定義了從字符串到整數(shù)的映射關(guān)系,數(shù)組KEYCODES,定義如下所示:
數(shù)組KEYCODES表示的映射關(guān)系,左列的內(nèi)容即表示按鍵標簽KeyCodeLabel,右列的內(nèi)容為按鍵碼KeyCode(與KeyCode的數(shù)值對應(yīng))。實際上,在按鍵信息第二次轉(zhuǎn)化的時候就是將字符串類型KeyCodeLabel轉(zhuǎn)化成整數(shù)的KeyCode。
KeycodeLabel的Flags的定義如下所示:
KeycodeLabel表示按鍵的附屬標識。
提示:frameworks/base/core/Java/android/view/KeyEvent.Java中定義了類android.view. KeyEvent類,其中定義整數(shù)類型的數(shù)值與KeycodeLabels.h中定義的KeyCode枚舉值是對應(yīng)的。
在本地框架層libui的頭文件中KeyCharacterMap.h,定義了按鍵的字符映射關(guān)系,KeyCharacterMap類的定義如下所示:
KeyCharacterMap用于將按鍵的碼映射為文本可識別的字符串(例如,顯示的標簽等)。KeyCharacterMap是一個輔助的功能:由于按鍵碼只是一個與UI無關(guān)整數(shù),通常用程序?qū)ζ溥M行捕獲處理,然而如果將按鍵事件轉(zhuǎn)換為用戶可見的內(nèi)容,就需要經(jīng)過這個層次的轉(zhuǎn)換了。
KeyCharacterMap需要從本地層傳送到Java層,JNI的代碼路徑如下所示:
frameworks/base/core/jni/android_text_KeyCharacterMap.cpp
KeyCharacterMap Java框架層次的代碼如下所示:
frameworks/base/core/Java/android/view/KeyCharacterMap.Java
android.view.KeyCharacterMap類是Android平臺的API可以在應(yīng)用程序中使用這個類。
android.text.method中有各種Linstener,可以之間監(jiān)聽KeyCharacterMap相關(guān)的信息。DigitsKeyListener NumberKeyListener TextKeyListener。
以上關(guān)于按鍵碼和按鍵字符映射的內(nèi)容是在代碼中實現(xiàn)的內(nèi)容,還需要配合動態(tài)的配置文件來使用。在實現(xiàn)Android系統(tǒng)的時候,有可能需要更改這兩種文件。
動態(tài)的配置文件包括:
KL(Keycode Layout):后綴名為kl的配置文件
KCM(KeyCharacterMap):后綴名為kcm的配置文件
Donut及其之前配置文件的路徑為:
development/emulator/keymaps/
Eclair及其之后配置文件的路徑為:
sdk/emulator/keymaps/
這些配置文件經(jīng)過系統(tǒng)生成后,將被放置在目標文件系統(tǒng)的/system/usr/keylayout/目錄或者/system/usr/keychars/目錄中。
提示:kl文件將被直接復(fù)職到目標文件系統(tǒng)中;由于尺寸較大,kcm文件放置在目標文件系統(tǒng)中之前,需要經(jīng)過壓縮處理。KeyLayoutMap.cpp負責解析處理kl文件,KeyCharacterMap.cpp負責解析kcm文件。