<!-- @page { margin: 2cm } P { margin-bottom: 0.21cm } --> 一、Android中鍵盤驅(qū)動 1、android使用標(biāo)準(zhǔn)的linux輸入事件設(shè)備(/dev/input/)和驅(qū)動按鍵定義在linux內(nèi)核include/linux/input.h中,其中input.h文件中定義了linux標(biāo)準(zhǔn)的按鍵掃描碼,定義形式如下: /* * Keys and buttons * * Most of the keys/buttons are modeled after USB HUT 1.12 * (see http://www./developers/hidpage). * Abbreviations in the comments: * AC - Application Control * AL - Application Launch Button * SC - System Control */ #define KEY_RESERVED 0 #define KEY_ESC 1 #define KEY_1 2 #define KEY_2 3 #define KEY_3 4 #define KEY_4 5 #define KEY_5 6 #define KEY_6 7 #define KEY_7 8 #define KEY_8 9 #define KEY_9 10 #define KEY_0 11 #define KEY_MINUS 12 #define KEY_EQUAL 13 #define KEY_BACKSPACE 14 #define KEY_TAB 15 #define KEY_Q 16 #define KEY_W 17 #define KEY_E 18
2、在具體的kernel/drivers/input/keyboard下的.c文件中定義了各種設(shè)備鍵盤按鍵到linux內(nèi)核標(biāo)準(zhǔn)按鍵的映射,其定義形式為: 即定義了具體設(shè)備硬件GPIO(General Purpose Input Output)口到內(nèi)核標(biāo)準(zhǔn)按鍵的映射。 如:qt2160.c中: static unsigned char qt2160_key2code[] = { KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, KEY_F, };
3、以上驅(qū)動程序就實現(xiàn)了從硬件 GPIO口到內(nèi)核標(biāo)準(zhǔn)按鍵的映射,但是 android 系統(tǒng)沒有直接使用映射后的值,而是對其再進(jìn)行了一次映射。從內(nèi)核標(biāo)準(zhǔn)鍵值到 android 所用的鍵值映射表定義在 android 文件系統(tǒng)的 /system/usr/keylayout 目錄下。Android標(biāo)準(zhǔn)的鍵值映射表文件為 qwerty.kl。(源代碼中的話為:build/target/board/generic_x86/keymaps/qwerty.kl) 定義如下: key 41 GRAVE key 2 1 key 3 2 key 4 3 key 5 4 key 6 5 key 7 6 key 8 7 key 9 8 key 10 9 key 11 0 key 1 BACK WAKE_DROPPED key 230 SOFT_RIGHT WAKE key 60 SOFT_RIGHT WAKE key 107 ENDCALL WAKE_DROPPED key 62 ENDCALL WAKE_DROPPED key 64 ENDCALL WAKE_DROPPED key 127 MENU WAKE_DROPPED key 139 MENU WAKE_DROPPED key 228 POUND key 227 STAR key 231 CALL WAKE_DROPPED key 61 CALL WAKE_DROPPED key 221 DPAD_CENTER WAKE_DROPPED key 108 DPAD_DOWN WAKE_DROPPED key 103 DPAD_UP WAKE_DROPPED key 125 HOME WAKE key 105 DPAD_LEFT WAKE_DROPPED key 106 DPAD_RIGHT WAKE_DROPPED 4、android系統(tǒng)對底層按鍵的處理(這部分在《Android系統(tǒng)級深入開發(fā)——移植與調(diào)試》這本書的第8章用戶輸入系統(tǒng)中有詳細(xì)介紹)
舉例為掃描碼103(linux標(biāo)準(zhǔn)的)映射為按鍵標(biāo)簽為DPAD_UP,在映射為整形的按鍵碼keycode 為19(android自定義的)。 注: (1)、frameworks/base/core/Java/android/view/KeyEvent.Java中定義了類android.view. KeyEvent類,其中定義整數(shù)類型的數(shù)值與KeycodeLabels.h中定義的KeyCode枚舉值是對應(yīng)的。 (2)、android中一般使用按鍵標(biāo)簽來標(biāo)識某個特定的鍵,通過qwerty.kl的映射我們可以知道其對應(yīng)的掃描碼,從而知道對應(yīng)于鍵盤上哪個鍵。
PS:以下將以添加F10鍵全局調(diào)用系統(tǒng)設(shè)置菜單為案例進(jìn)行講解。 二、How To Add A New KeyCode In Android Linux內(nèi)核部分并不需要修改,我們只需要參考input.h文件了解鍵盤上按鍵對應(yīng)的掃描碼即可。在keyevent.java文件中有這樣一段注釋說明,可供參考: // NOTE: If you add a new keycode here you must also add it to: // isSystem() // frameworks/base/include/ui/KeycodeLabels.h // tools/puppet_master/PuppetMaster/nav_keys.py // frameworks/base/core/res/res/values/attrs.xml // commands/monkey/Monkey.java // emulator? // // Also Android currently does not reserve code ranges for vendor- // specific key codes. If you have new key codes to have, you // MUST contribute a patch to the open source project to define // those new codes. This is intended to maintain a consistent // set of key code definitions across all Android devices. 上文中提到我們需要修改如下文件: KeycodeLabels.h、attrs.xml、keyevent.java文件 當(dāng)然,最重要的是我們得在qwerty.kl文件中添加掃描碼到按鍵標(biāo)簽的定義。 1、qwerty.kl 考慮系統(tǒng)設(shè)置按鍵擬定義為全局的,則不宜采用字母數(shù)字鍵等,故采用F10鍵,對照input.h文件可知,F10鍵的掃描碼為68,故可在qwerty.kl中定義它為: key 68 EDIT 注意:文件中要注意格式及對齊,按鍵標(biāo)簽是自定義的,這里掃描碼最好使用android系統(tǒng)還沒有使用的。 2、KeycodeLabels.h 1)在數(shù)組keycodes 中添加 新定義的信息, 要在{NULL, 0}之前添加: static const KeycodeLabel KEYCODES[] = { ... ... { "EDIT",68 },
// NOTE: If you add a new keycode here you must also add it to: // (enum KeyCode, in this file) // frameworks/base/core/java/android/view/KeyEvent.java // tools/puppet_master/PuppetMaster.nav_keys.py // frameworks/base/core/res/res/values/attrs.xml
{ NULL, 0 } } 2)枚舉類型 KeyCode 中添加 typedef enum KeyCode { ... ... kKeyCodeEDIT = 68, }KeyCode; 3、attrs.xml 添加如下 <enum name="KEYCODE_EDIT" value="68" /> 4、keyevent.java (1)、 public static final int KEYCODE_EDIT = 68; (2)、private static final int LAST_KEYCODE = KEYCODE_MUTE; 應(yīng)改為:private static final int LAST_KEYCODE = KEYCODE_EDIT; (3)、應(yīng)為我們是要添加系統(tǒng)按鍵,故還要更改在函數(shù) public final boolean isSystem() 中,同樣需要添加: case KEYCODE_EDIT: 至此,已在android底層添加了對F10鍵的支持,如要對F10進(jìn)行處理,可通過keyevent.keycode_edit來調(diào)用它即可。 下面將講解如何在phonewidow.java文件添加F10鍵對系統(tǒng)設(shè)置的全局定義。 三、添加F10鍵對系統(tǒng)設(shè)置的全局定義 1、PhoneWindow.java(frameworks/policies/base/phone/com/android/internal/policy/impl下) (1)、在方法onkeydown()中添加如下代碼: case KeyEvent.KEYCODE_EDIT: { Log.i(TAG,"edit SystemMenu!"); Intent intent=new Intent(Intent.ACTION_EDIT_BUTTON); getContext().sendBroadcast(intent); return true; } 在方法onkeyup()中添加如下代碼: case KeyEvent.KEYCODE_EDIT: 關(guān)于Intent.ACTION_EDIT_BUTTON在Intent.java中有定義。 2、Intent.java(frameworks/base/core/java/android/content/Intent.java) 添加如下代碼,自定義intent的action:
在應(yīng)用程序系統(tǒng)設(shè)置的AndroidManifest.xml文件中定義了相應(yīng)的boardcast receiver來處理從PhoneWindow.java傳來的boardcast,注意在系統(tǒng)設(shè)置EditMainMenu.java文件的同一目錄下還需要添加一個EditButtonIntentReceiver類。 3、EditButtonIntentReceiver.Java (位于與EditMainMenu.java同一目錄 packages/apps/Visux_portal/src/com/yarin/android/Visux_portal/EditMainMenu.java) 具體可參考CameraButtonIntentReceiver.Java文件 其代碼如下,主要定義黑體字部分: ……………… package com.yarin.android.Visux_portal;
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent;
/** * {@code EditButtonIntentReceiver} is invoked when the F10 is * pressed. * * It is declared in {@code AndroidManifest.xml} to receive the * {@code android.intent.action.EDIT_BUTTON} intent. * */ public class EditButtonIntentReceiver extends BroadcastReceiver {
@Override public void onReceive(Context context, Intent intent) {
Intent i = new Intent(Intent.ACTION_MAIN); i.setClass(context, EditMainMenu.class); i.addCategory(Intent.CATEGORY_LAUNCHER); i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); context.startActivity(i); } } 4、AndroidManifest.xml的修改 (位于packages/apps/Visux_portal/AndroidManifest.xml) <receiver android:name="com.yarin.android.Visux_portal.EditButtonIntentReceiver"> <intent-filter> <action android:name="android.intent.action.EDIT_BUTTON" /> </intent-filter> </receiver> 這樣就實現(xiàn)了F10鍵全局調(diào)用系統(tǒng)設(shè)置的功能。 |
|