Android系统添加全局快捷键的方法

来源:互联网 发布:三国霸业4单机版源码 编辑:程序博客网 时间:2024/05/16 19:35

<!--@page { margin: 2cm }P { margin-bottom: 0.21cm }-->

一、Android中键盘驱动

1android使用标准的linux输入事件设备(/dev/input/)和驱动按键定义在linux内核include/linux/input.h中,其中input.h文件中定义了linux标准的按键扫描码,定义形式如下:

/*

*Keys and buttons

*

*Most of the keys/buttons are modeled after USB HUT 1.12

*(see http://www.usb.org/developers/hidpage).

*Abbreviations in the comments:

*AC - Application Control

*AL - Application Launch Button

*SC - System Control

*/

#defineKEY_RESERVED0

#defineKEY_ESC1

#defineKEY_12

#defineKEY_23

#defineKEY_34

#defineKEY_45

#defineKEY_56

#defineKEY_67

#defineKEY_78

#defineKEY_89

#defineKEY_910

#defineKEY_011

#defineKEY_MINUS12

#defineKEY_EQUAL13

#defineKEY_BACKSPACE14

#defineKEY_TAB15

#defineKEY_Q16

#defineKEY_W17

#defineKEY_E18

 

2、在具体的kernel/drivers/input/keyboard下的.c文件中定义了各种设备键盘按键到linux内核标准按键的映射,其定义形式为:

即定义了具体设备硬件GPIOGeneralPurpose Input Output)口到内核标准按键的映射。

如:qt2160.c中:

staticunsigned 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、以上驱动程序就实现了从硬件GPIO口到内核标准按键的映射,但是android系统没有直接使用映射后的值,而是对其再进行了一次映射。从内核标准键值到android所用的键值映射表定义在 android文件系统的 /system/usr/keylayout目录下。Android标准的键值映射表文件为qwerty.kl。(源代码中的话为:build/target/board/generic_x86/keymaps/qwerty.kl

定义如下:

key41 GRAVE

key2 1

key3 2

key4 3

key5 4

key6 5

key7 6

key8 7

key9 8

key10 9

key11 0

key1 BACK WAKE_DROPPED

key230 SOFT_RIGHT WAKE

key60 SOFT_RIGHT WAKE

key107 ENDCALL WAKE_DROPPED

key62 ENDCALL WAKE_DROPPED

key64 ENDCALL WAKE_DROPPED

key127 MENU WAKE_DROPPED

key139 MENU WAKE_DROPPED

key228 POUND

key227 STAR

key231 CALL WAKE_DROPPED

key61 CALL WAKE_DROPPED

key221 DPAD_CENTER WAKE_DROPPED

key108 DPAD_DOWN WAKE_DROPPED

key103 DPAD_UP WAKE_DROPPED

key125 HOME WAKE

key105 DPAD_LEFT WAKE_DROPPED

key106 DPAD_RIGHT WAKE_DROPPED

4android系统对底层按键的处理(这部分在《Android系统级深入开发——移植与调试》这本书的第8章用户输入系统中有详细介绍)

 

举例为扫描码103linux标准的)映射为按键标签为DPAD_UP,在映射为整形的按键码keycode 19android自定义的)。

注:

(1)frameworks/base/core/Java/android/view/KeyEvent.Java中定义了类android.view.KeyEvent类,其中定义整数类型的数值与KeycodeLabels.h中定义的KeyCode枚举值是对应的。

(2)android中一般使用按键标签来标识某个特定的键,通过qwerty.kl的映射我们可以知道其对应的扫描码,从而知道对应于键盘上哪个键。

 

PS:以下将以添加F10键全局调用系统设置菜单为案例进行讲解。

二、HowTo Add A New KeyCode In Android

Linux内核部分并不需要修改,我们只需要参考input.h文件了解键盘上按键对应的扫描码即可。在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.hattrs.xmlkeyevent.java文件

当然,最重要的是我们得在qwerty.kl文件中添加扫描码到按键标签的定义。

1qwerty.kl

考虑系统设置按键拟定义为全局的,则不宜采用字母数字键等,故采用F10键,对照input.h文件可知,F10键的扫描码为68,故可在qwerty.kl中定义它为:

key68 EDIT

注意:文件中要注意格式及对齐,按键标签是自定义的,这里扫描码最好使用android系统还没有使用的。

2KeycodeLabels.h

1)在数组keycodes中添加 新定义的信息,

要在{NULL,0}之前添加:

staticconst 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中添加

typedefenum KeyCode {

...

...

kKeyCodeEDIT= 68,

}KeyCode;

3attrs.xml

添加如下

<enumname="KEYCODE_EDIT" value="68" />

4keyevent.java

1)、

publicstatic final int KEYCODE_EDIT = 68;

2)、privatestatic final int LAST_KEYCODE = KEYCODE_MUTE;

应改为:privatestatic final int LAST_KEYCODE = KEYCODE_EDIT;

3)、应为我们是要添加系统按键,故还要更改在函数publicfinal boolean isSystem() 中,同样需要添加:

caseKEYCODE_EDIT:

至此,已在android底层添加了对F10键的支持,如要对F10进行处理,可通过keyevent.keycode_edit来调用它即可。

下面将讲解如何在phonewidow.java文件添加F10键对系统设置的全局定义。

三、添加F10键对系统设置的全局定义

1PhoneWindow.javaframeworks/policies/base/phone/com/android/internal/policy/impl下)

(1)、在方法onkeydown()中添加如下代码:

caseKeyEvent.KEYCODE_EDIT: {

Log.i(TAG,"editSystemMenu!");

Intentintent=new Intent(Intent.ACTION_EDIT_BUTTON);

getContext().sendBroadcast(intent);

returntrue;

}

在方法onkeyup()中添加如下代码:

caseKeyEvent.KEYCODE_EDIT:

关于Intent.ACTION_EDIT_BUTTONIntent.java中有定义。

2Intent.javaframeworks/base/core/java/android/content/Intent.java

添加如下代码,自定义intentaction

 

在应用程序系统设置的AndroidManifest.xml文件中定义了相应的boardcastreceiver来处理从PhoneWindow.java传来的boardcast,注意在系统设置EditMainMenu.java文件的同一目录下还需要添加一个EditButtonIntentReceiver类。

3EditButtonIntentReceiver.Java(位于与EditMainMenu.java同一目录

packages/apps/Visux_portal/src/com/yarin/android/Visux_portal/EditMainMenu.java)

具体可参考CameraButtonIntentReceiver.Java文件

其代码如下,主要定义黑体字部分:

………………

packagecom.yarin.android.Visux_portal;

 

importandroid.content.BroadcastReceiver;

importandroid.content.Context;

importandroid.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.

*

*/

publicclass EditButtonIntentReceiver extends BroadcastReceiver {

 

@Override

publicvoid onReceive(Context context, Intent intent) {

 

Intenti = 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);

}

}

4AndroidManifest.xml的修改

(位于packages/apps/Visux_portal/AndroidManifest.xml

<receiverandroid:name="com.yarin.android.Visux_portal.EditButtonIntentReceiver">

<intent-filter>

<actionandroid:name="android.intent.action.EDIT_BUTTON" />

</intent-filter>

</receiver>

这样就实现了F10键全局调用系统设置的功能。