Android : 输入设备键值从底层到应用层的映射流程

时间:2023-01-26 07:52:16

一、Android输入子系统简介:

  Android输入事件的源头是位于/dev/input/下的设备节点,而输入系统的终点是由WMS管理的某个窗口。最初的输入事件为内核生成的原始事件,而最终交付给窗口的则是KeyEvent或MotionEvent对象。因此Android输入系统的主要工作是读取设备节点中的原始事件,将其加工封装,然后派发给一个特定的窗口以及窗口中的控件。这个过程由InputManagerService(以下简称IMS)系统服务为核心的多个参与者共同完成。

Android : 输入设备键值从底层到应用层的映射流程

                        图1:输入系统的总体流程与参与者

二、键值映射关系:

    ①IR硬件扫描码在驱动里面被映射为 include/uapi/linux/input.h 里面定义的某个键值,但这个键值只在linux系统(内核)中使用。
  ②Android通过源码目录下的 device/xxx/xxx.kl(keylayout) 文件完成linux键值到Android系统要使用的键值映射。
 
  以HID设备为例,首先内核中的键值转换在drivers/hid/hid-input.c 中进行映射,键值通道也有多种类型,例如:keyboard、consumer 等等;
  //keyboard通道键值则是在如下数组添加修改:
static const unsigned char hid_keyboard[] = {
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , , , , , , , , , ,
, , , , , , , ,,,,,,,,,
,,, , , , , , , , , , , , , ,
, , , , ,,,,,,,,,,,,
,,,,,,,,,,,,,,,,
,,unk,unk,unk,,unk, , ,, , , ,unk,unk,unk,
,, , , ,unk,unk,unk,unk,unk,unk,unk,,unk,unk,unk,
unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
unk,unk,unk,unk,unk,unk,,,unk,unk,unk,unk,unk,unk,unk,unk,
unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
unk,unk,unk,unk,unk,unk,unk,unk,,unk,unk,unk,unk,unk,unk,unk,
, , ,, , ,,,,,,,,,,,
,,,,,,,,,,,,unk,unk,unk,unk
}; ...... //然后在以下代码部分使用:
case HID_UP_KEYBOARD:
set_bit(EV_REP, input->evbit); if ((usage->hid & HID_USAGE) < ) {
if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore;
map_key_clear(hid_keyboard[usage->hid & HID_USAGE]);
} else
map_key(KEY_UNKNOWN); break;

 //consumer通道键值则是在如下添加修改:

case HID_UP_CONSUMER:    /* USB HUT v1.12, pages 75-84 */
switch (usage->hid & HID_USAGE) {
case 0x000: goto ignore;
case 0x030: map_key_clear(KEY_POWER); break;
case 0x031: map_key_clear(KEY_RESTART); break;
case 0x032: map_key_clear(KEY_SLEEP); break;
case 0x034: map_key_clear(KEY_SLEEP); break;
case 0x035: map_key_clear(KEY_KBDILLUMTOGGLE); break;
case 0x036: map_key_clear(BTN_MISC); break;
case 0x040: map_key_clear(KEY_MENU); break; /* Menu */
case 0x041: map_key_clear(KEY_SELECT); break; /* Menu Pick */
case 0x042: map_key_clear(KEY_UP); break; /* Menu Up */
case 0x043: map_key_clear(KEY_DOWN); break; /* Menu Down */
case 0x044: map_key_clear(KEY_LEFT); break; /* Menu Left */
case 0x045: map_key_clear(KEY_RIGHT); break; /* Menu Right */
case 0x046: map_key_clear(KEY_ESC); break; /* Menu Escape */
case 0x047: map_key_clear(KEY_KPPLUS); break; /* Menu Value Increase */
case 0x048: map_key_clear(KEY_KPMINUS); break; /* Menu Value Decrease */
case 0x060: map_key_clear(KEY_INFO); break; /* Data On Screen */
case 0x061: map_key_clear(KEY_SUBTITLE); break; /* Closed Caption */
case 0x063: map_key_clear(KEY_VCR); break; /* VCR/TV */
case 0x065: map_key_clear(KEY_CAMERA); break; /* Snapshot */
case 0x069: map_key_clear(KEY_RED); break;
case 0x06a: map_key_clear(KEY_GREEN); break;
case 0x06b: map_key_clear(KEY_BLUE); break;
case 0x06c: map_key_clear(KEY_YELLOW); break;
case 0x06d: map_key_clear(KEY_ZOOM); break;
case 0x082: map_key_clear(KEY_VIDEO_NEXT); break;
case 0x083: map_key_clear(KEY_LAST); break;
case 0x084: map_key_clear(KEY_ENTER); break;
case 0x088: map_key_clear(KEY_PC); break;
case 0x089: map_key_clear(KEY_TV); break;
case 0x08a: map_key_clear(KEY_WWW); break;
case 0x08b: map_key_clear(KEY_DVD); break;
case 0x08c: map_key_clear(KEY_PHONE); break;
case 0x08d: map_key_clear(KEY_PROGRAM); break;
case 0x08e: map_key_clear(KEY_VIDEOPHONE); break;
case 0x08f: map_key_clear(KEY_GAMES); break;
case 0x090: map_key_clear(KEY_MEMO); break;
case 0x091: map_key_clear(KEY_CD); break;
case 0x092: map_key_clear(KEY_VCR); break;
case 0x093: map_key_clear(KEY_TUNER); break;
case 0x094: map_key_clear(KEY_EXIT); break;
case 0x095: map_key_clear(KEY_HELP); break;
case 0x096: map_key_clear(KEY_TAPE); break;
case 0x097: map_key_clear(KEY_TV2); break;
case 0x098: map_key_clear(KEY_SAT); break;
case 0x09a: map_key_clear(KEY_PVR); break;
case 0x09c: map_key_clear(KEY_CHANNELUP); break;
case 0x09d: map_key_clear(KEY_CHANNELDOWN); break;
case 0x0a0: map_key_clear(KEY_VCR2); break;
case 0x0b0: map_key_clear(KEY_PLAY); break;
case 0x0b1: map_key_clear(KEY_PAUSE); break;
case 0x0b2: map_key_clear(KEY_RECORD); break;
case 0x0b3: map_key_clear(KEY_FASTFORWARD); break;
case 0x0b4: map_key_clear(KEY_REWIND); break;
case 0x0b5: map_key_clear(KEY_NEXTSONG); break;
case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break;
case 0x0b7: map_key_clear(KEY_STOPCD); break;
case 0x0b8: map_key_clear(KEY_EJECTCD); break;
case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT); break;
case 0x0b9: map_key_clear(KEY_SHUFFLE); break;
case 0x0bf: map_key_clear(KEY_SLOW); break;
case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break;
case 0x0e0: map_abs_clear(ABS_VOLUME); break;
case 0x0e2: map_key_clear(KEY_MUTE); break;
case 0x0e5: map_key_clear(KEY_BASSBOOST); break;
case 0x0e9: map_key_clear(KEY_VOLUMEUP); break;
case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break;
case 0x0f5: map_key_clear(KEY_SLOW); break;
case 0x182: map_key_clear(KEY_BOOKMARKS); break;
case 0x183: map_key_clear(KEY_CONFIG); break;
case 0x184: map_key_clear(KEY_WORDPROCESSOR); break;
case 0x185: map_key_clear(KEY_EDITOR); break;
case 0x186: map_key_clear(KEY_SPREADSHEET); break;
case 0x187: map_key_clear(KEY_GRAPHICSEDITOR); break;
case 0x188: map_key_clear(KEY_PRESENTATION); break;
case 0x189: map_key_clear(KEY_DATABASE); break;
case 0x18a: map_key_clear(KEY_MAIL); break;
case 0x18b: map_key_clear(KEY_NEWS); break;
case 0x18c: map_key_clear(KEY_VOICEMAIL); break;
case 0x18d: map_key_clear(KEY_ADDRESSBOOK); break;
case 0x18e: map_key_clear(KEY_CALENDAR); break;
case 0x191: map_key_clear(KEY_FINANCE); break;
case 0x192: map_key_clear(KEY_CALC); break;
case 0x193: map_key_clear(KEY_PLAYER); break;
case 0x194: map_key_clear(KEY_FILE); break;
case 0x196: map_key_clear(KEY_WWW); break;
case 0x199: map_key_clear(KEY_CHAT); break;
case 0x19c: map_key_clear(KEY_LOGOFF); break;
case 0x19e: map_key_clear(KEY_COFFEE); break;
case 0x1a6: map_key_clear(KEY_HELP); break;
case 0x1a7: map_key_clear(KEY_DOCUMENTS); break;
case 0x1ab: map_key_clear(KEY_SPELLCHECK); break;
case 0x1ae: map_key_clear(KEY_KEYBOARD); break;
case 0x1b6: map_key_clear(KEY_IMAGES); break;
case 0x1b7: map_key_clear(KEY_AUDIO); break;
case 0x1b8: map_key_clear(KEY_VIDEO); break;
case 0x1bc: map_key_clear(KEY_MESSENGER); break;
case 0x1bd: map_key_clear(KEY_INFO); break;
case 0x201: map_key_clear(KEY_NEW); break;
case 0x202: map_key_clear(KEY_OPEN); break;
case 0x203: map_key_clear(KEY_CLOSE); break;
case 0x204: map_key_clear(KEY_EXIT); break;
case 0x207: map_key_clear(KEY_SAVE); break;
case 0x208: map_key_clear(KEY_PRINT); break;
case 0x209: map_key_clear(KEY_PROPS); break;
case 0x21a: map_key_clear(KEY_UNDO); break;
case 0x21b: map_key_clear(KEY_COPY); break;
case 0x21c: map_key_clear(KEY_CUT); break;
case 0x21d: map_key_clear(KEY_PASTE); break;
case 0x21f: map_key_clear(KEY_FIND); break;
case 0x221: map_key_clear(KEY_SEARCH); break;
case 0x222: map_key_clear(KEY_GOTO); break;
case 0x223: map_key_clear(KEY_HOMEPAGE); break;
case 0x224: map_key_clear(KEY_BACK); break;
case 0x225: map_key_clear(KEY_FORWARD); break;
case 0x226: map_key_clear(KEY_STOP); break;
case 0x227: map_key_clear(KEY_REFRESH); break;
case 0x22a: map_key_clear(KEY_BOOKMARKS); break;
case 0x22d: map_key_clear(KEY_ZOOMIN); break;
case 0x22e: map_key_clear(KEY_ZOOMOUT); break;
case 0x22f: map_key_clear(KEY_ZOOMRESET); break;
case 0x233: map_key_clear(KEY_SCROLLUP); break;
case 0x234: map_key_clear(KEY_SCROLLDOWN); break;
case 0x238: map_rel(REL_HWHEEL); break;
case 0x23d: map_key_clear(KEY_EDIT); break;
case 0x25f: map_key_clear(KEY_CANCEL); break;
case 0x269: map_key_clear(KEY_INSERT); break;
case 0x26a: map_key_clear(KEY_DELETE); break;
case 0x279: map_key_clear(KEY_REDO); break;
case 0x289: map_key_clear(KEY_REPLY); break;
case 0x28b: map_key_clear(KEY_FORWARDMAIL); break;
case 0x28c: map_key_clear(KEY_SEND); break;
default: goto ignore;
}
break;

通过 map_key_clear 宏将原始键值(usage->hid & HID_USAGE)转换成内核的定义,映射函数的具体实现可看内核源码,

以上键值的定义在 include/uapi/linux/input-event-codes.h (内核代码,较新版本定义整合进了input.h),对应到Android系统层的头文件则是 bionic/libc/kernel/uapi/linux/input-event-codes.h:

#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
#define KEY_R 19
#define KEY_T 20
#define KEY_Y 21
#define KEY_U 22
#define KEY_I 23
#define KEY_O 24
#define KEY_P 25
#define KEY_LEFTBRACE 26
#define KEY_RIGHTBRACE 27
#define KEY_ENTER 28
#define KEY_LEFTCTRL 29
#define KEY_A 30
#define KEY_S 31
#define KEY_D 32
#define KEY_F 33
#define KEY_G 34
#define KEY_H 35
#define KEY_J 36
#define KEY_K 37
#define KEY_L 38
#define KEY_SEMICOLON 39
#define KEY_APOSTROPHE 40
#define KEY_GRAVE 41
#define KEY_LEFTSHIFT 42
#define KEY_BACKSLASH 43
#define KEY_Z 44
#define KEY_X 45
#define KEY_C 46
#define KEY_V 47
#define KEY_B 48
#define KEY_N 49
#define KEY_M 50
#define KEY_COMMA 51
#define KEY_DOT 52
#define KEY_SLASH 53
#define KEY_RIGHTSHIFT 54
#define KEY_KPASTERISK 55
#define KEY_LEFTALT 56
#define KEY_SPACE 57
#define KEY_CAPSLOCK 58
#define KEY_F1 59
#define KEY_F2 60
#define KEY_F3 61
#define KEY_F4 62
#define KEY_F5 63
#define KEY_F6 64
#define KEY_F7 65
#define KEY_F8 66
#define KEY_F9 67
#define KEY_F10 68
#define KEY_NUMLOCK 69
#define KEY_SCROLLLOCK 70
#define KEY_KP7 71
#define KEY_KP8 72
#define KEY_KP9 73
#define KEY_KPMINUS 74
#define KEY_KP4 75
#define KEY_KP5 76
#define KEY_KP6 77
#define KEY_KPPLUS 78
#define KEY_KP1 79
#define KEY_KP2 80
#define KEY_KP3 81
#define KEY_KP0 82
#define KEY_KPDOT 83 #define KEY_ZENKAKUHANKAKU 85
#define KEY_102ND 86
#define KEY_F11 87
#define KEY_F12 88
#define KEY_RO 89
#define KEY_KATAKANA 90
#define KEY_HIRAGANA 91
#define KEY_HENKAN 92
#define KEY_KATAKANAHIRAGANA 93
#define KEY_MUHENKAN 94
#define KEY_KPJPCOMMA 95
#define KEY_KPENTER 96
#define KEY_RIGHTCTRL 97
#define KEY_KPSLASH 98
#define KEY_SYSRQ 99
#define KEY_RIGHTALT 100
#define KEY_LINEFEED 101
#define KEY_HOME 102
#define KEY_UP 103
#define KEY_PAGEUP 104
#define KEY_LEFT 105
#define KEY_RIGHT 106
#define KEY_END 107
#define KEY_DOWN 108
#define KEY_PAGEDOWN 109
#define KEY_INSERT 110
#define KEY_DELETE 111
#define KEY_MACRO 112
#define KEY_MUTE 113
#define KEY_VOLUMEDOWN 114
#define KEY_VOLUMEUP 115
#define KEY_POWER 116 /* SC System Power Down */
#define KEY_KPEQUAL 117
#define KEY_KPPLUSMINUS 118
#define KEY_PAUSE 119
#define KEY_SCALE 120 /* AL Compiz Scale (Expose) */ #define KEY_KPCOMMA 121
#define KEY_HANGEUL 122
#define KEY_HANGUEL KEY_HANGEUL
#define KEY_HANJA 123
#define KEY_YEN 124
#define KEY_LEFTMETA 125
#define KEY_RIGHTMETA 126
#define KEY_COMPOSE 127 #define KEY_STOP 128 /* AC Stop */
#define KEY_AGAIN 129
#define KEY_PROPS 130 /* AC Properties */
#define KEY_UNDO 131 /* AC Undo */
#define KEY_FRONT 132
#define KEY_COPY 133 /* AC Copy */
#define KEY_OPEN 134 /* AC Open */
#define KEY_PASTE 135 /* AC Paste */
#define KEY_FIND 136 /* AC Search */
#define KEY_CUT 137 /* AC Cut */
#define KEY_HELP 138 /* AL Integrated Help Center */
#define KEY_MENU 139 /* Menu (show menu) */
#define KEY_CALC 140 /* AL Calculator */
#define KEY_SETUP 141
#define KEY_SLEEP 142 /* SC System Sleep */
#define KEY_WAKEUP 143 /* System Wake Up */
#define KEY_FILE 144 /* AL Local Machine Browser */
#define KEY_SENDFILE 145
#define KEY_DELETEFILE 146
#define KEY_XFER 147
#define KEY_PROG1 148
#define KEY_PROG2 149
#define KEY_WWW 150 /* AL Internet Browser */
#define KEY_MSDOS 151
#define KEY_COFFEE 152 /* AL Terminal Lock/Screensaver */
#define KEY_SCREENLOCK KEY_COFFEE
#define KEY_DIRECTION 153
#define KEY_CYCLEWINDOWS 154
#define KEY_MAIL 155
#define KEY_BOOKMARKS 156 /* AC Bookmarks */
#define KEY_COMPUTER 157
#define KEY_BACK 158 /* AC Back */
#define KEY_FORWARD 159 /* AC Forward */
#define KEY_CLOSECD 160
#define KEY_EJECTCD 161
#define KEY_EJECTCLOSECD 162
#define KEY_NEXTSONG 163
#define KEY_PLAYPAUSE 164
#define KEY_PREVIOUSSONG 165
#define KEY_STOPCD 166
#define KEY_RECORD 167
#define KEY_REWIND 168
#define KEY_PHONE 169 /* Media Select Telephone */
#define KEY_ISO 170
#define KEY_CONFIG 171 /* AL Consumer Control Configuration */
#define KEY_HOMEPAGE 172 /* AC Home */
#define KEY_REFRESH 173 /* AC Refresh */
#define KEY_EXIT 174 /* AC Exit */
#define KEY_MOVE 175
#define KEY_EDIT 176
#define KEY_SCROLLUP 177
#define KEY_SCROLLDOWN 178
#define KEY_KPLEFTPAREN 179
#define KEY_KPRIGHTPAREN 180
#define KEY_NEW 181 /* AC New */
#define KEY_REDO 182 /* AC Redo/Repeat */ #define KEY_F13 183
#define KEY_F14 184
#define KEY_F15 185
#define KEY_F16 186
#define KEY_F17 187
#define KEY_F18 188
#define KEY_F19 189
#define KEY_F20 190
#define KEY_F21 191
#define KEY_F22 192
#define KEY_F23 193
#define KEY_F24 194 #define KEY_PLAYCD 200
#define KEY_PAUSECD 201
#define KEY_PROG3 202
#define KEY_PROG4 203
#define KEY_DASHBOARD 204 /* AL Dashboard */
#define KEY_SUSPEND 205
#define KEY_CLOSE 206 /* AC Close */
#define KEY_PLAY 207
#define KEY_FASTFORWARD 208
#define KEY_BASSBOOST 209
#define KEY_PRINT 210 /* AC Print */
#define KEY_HP 211
#define KEY_CAMERA 212
#define KEY_SOUND 213
#define KEY_QUESTION 214
#define KEY_EMAIL 215
#define KEY_CHAT 216
#define KEY_SEARCH 217
#define KEY_CONNECT 218
#define KEY_FINANCE 219 /* AL Checkbook/Finance */
#define KEY_SPORT 220
#define KEY_SHOP 221
#define KEY_ALTERASE 222
#define KEY_CANCEL 223 /* AC Cancel */
#define KEY_BRIGHTNESSDOWN 224
#define KEY_BRIGHTNESSUP 225
#define KEY_MEDIA 226 #define KEY_SWITCHVIDEOMODE 227 /* Cycle between available video
outputs (Monitor/LCD/TV-out/etc) */
#define KEY_KBDILLUMTOGGLE 228
#define KEY_KBDILLUMDOWN 229
#define KEY_KBDILLUMUP 230 #define KEY_SEND 231 /* AC Send */
#define KEY_REPLY 232 /* AC Reply */
#define KEY_FORWARDMAIL 233 /* AC Forward Msg */
#define KEY_SAVE 234 /* AC Save */
#define KEY_DOCUMENTS 235 #define KEY_BATTERY 236 #define KEY_BLUETOOTH 237
#define KEY_WLAN 238
#define KEY_UWB 239 #define KEY_UNKNOWN 240 #define KEY_VIDEO_NEXT 241 /* drive next video source */
#define KEY_VIDEO_PREV 242 /* drive previous video source */
#define KEY_BRIGHTNESS_CYCLE 243 /* brightness up, after max is min */
#define KEY_BRIGHTNESS_AUTO 244 /* Set Auto Brightness: manual
brightness control is off,
rely on ambient */
#define KEY_BRIGHTNESS_ZERO KEY_BRIGHTNESS_AUTO
#define KEY_DISPLAY_OFF 245 /* display device to off state */ #define KEY_WWAN 246 /* Wireless WAN (LTE, UMTS, GSM, etc.) */
#define KEY_WIMAX KEY_WWAN
#define KEY_RFKILL 247 /* Key that controls all radios */ #define KEY_MICMUTE 248 /* Mute / unmute the microphone */ /* Code 255 is reserved for special needs of AT keyboard driver */
 
可通过 getevent 指令查看上报的键值,键值为十六进制显示:
Android : 输入设备键值从底层到应用层的映射流程
 

  首先要确定按键输入设备是对应/dev/input目录下哪个event,根据VID PID匹配对应的kl文件,可通过如下命令 cat /proc/bus/input/devices 查看设备信息:

shell@flo:/ $ cat /proc/bus/input/devices
I: Bus= Vendor= Product= Version=
N: Name="elan-touchscreen"
P: Phys=
S: Sysfs=/devices/virtual/input/input0
U: Uniq=
H: Handlers=event0 cpufreq
B: PROP=
B: EV=b
B: KEY=
B: ABS= I: Bus= Vendor= Product= Version=
N: Name="lid_input"
P: Phys=/dev/input/lid_indev
S: Sysfs=/devices/virtual/input/input1
U: Uniq=
H: Handlers=event1 cpufreq
B: PROP=
B: EV=
B: SW= I: Bus= Vendor= Product= Version=
N: Name="apq8064-tabla-snd-card Button Jack"
P: Phys=ALSA
S: Sysfs=/devices/platform/soc-audio./sound/card0/input2
U: Uniq=
H: Handlers=event2 cpufreq
B: PROP=
B: EV=
B: KEY=ff I: Bus= Vendor= Product= Version=
N: Name="apq8064-tabla-snd-card Headset Jack"
P: Phys=ALSA
S: Sysfs=/devices/platform/soc-audio./sound/card0/input3
U: Uniq=
H: Handlers=event3 cpufreq
B: PROP=
B: EV=
B: SW=1c054 I: Bus= Vendor= Product= Version=
N: Name="h2w button"
P: Phys=
S: Sysfs=/devices/virtual/input/input4
U: Uniq=
H: Handlers=kbd event4 cpufreq
B: PROP=
B: EV=
B: KEY= I: Bus= Vendor= Product= Version=
N: Name="gpio-keys"
P: Phys=gpio-keys/input0
S: Sysfs=/devices/platform/gpio-keys./input/input5
U: Uniq=
H: Handlers=kbd event5 keychord cpufreq
B: PROP=
B: EV=
B: KEY=1c0000 I: Bus= Vendor= Product=001D Version=
N: Name="Smart Remote"
P: Phys=
S: Sysfs=/devices/virtual/misc/uhid/input7
U: Uniq=
H: Handlers=sysrq kbd event6 keychord cpufreq
B: PROP=
B: EV=10001f
B: KEY=4837fff 72ff32d bf544446 30f90 8b17c007 ffff7bfa d9415fff febeffdf ffefffff ffffffff fffffffe
B: REL=
B: ABS=
B: MSC=

  如上我的设备名是:"Smart Remote"  , VID PID信息是:Vendor=0030 Product=001D ,则对应 /system/usr/keylayout/Vendor_0030_Product_001D.kl,如果该目录下没有对应VID PID的.kl则默认使用 Generic.kl,根据系统差异可能另外有 /data/system/devices/keylayout/Vendor_XXXX_Product_XXXX_Version_XXXX.kl ,此外还有键值对应字符的转换表:/system/usr/keychars/Generic.kcm 。

所以上面通过getevent获得的原始键值是0x44(十进制:68),然后由 hid-input.c 可知 hid_keyboard[68]=87 而 input.h 中定义是 #define KEY_F11 87,所以Android系统层获取到内核转换后的键值为<87>,然后通过加载Generic.kl解析<87>的含义是"F11"(一般都是和内核头文件定义相匹配,也可以自己修改使其映射成其他含义):

#
# Generic key layout file for full alphabetic US English PC style external keyboards.
#
# This file is intentionally very generic and is intended to support a broad rang of keyboards.
# Do not edit the generic key layout to support a specific keyboard; instead, create
# a new key layout file with the required keyboard configuration.
# key ESCAPE
key
key
key
key
key
key
key
key
key
key
key MINUS
key EQUALS
key DEL
key TAB
key Q
key W
key E
key R
key T
key Y
key U
key I
key O
key P
key LEFT_BRACKET
key RIGHT_BRACKET
key ENTER
key CTRL_LEFT
key A
key S
key D
key F
key G
key H
key J
key K
key L
key SEMICOLON
key APOSTROPHE
key GRAVE
key SHIFT_LEFT
key BACKSLASH
key Z
key X
key C
key V
key B
key N
key M
key COMMA
key PERIOD
key SLASH
key SHIFT_RIGHT
key NUMPAD_MULTIPLY
key ALT_LEFT
key SPACE
key CAPS_LOCK
key F1
key F2
key F3
key F4
key F5
key F6
key F7
key F8
key F9
key F10
key NUM_LOCK
key SCROLL_LOCK
key NUMPAD_7
key NUMPAD_8
key NUMPAD_9
key NUMPAD_SUBTRACT
key NUMPAD_4
key NUMPAD_5
key NUMPAD_6
key NUMPAD_ADD
key NUMPAD_1
key NUMPAD_2
key NUMPAD_3
key NUMPAD_0
key NUMPAD_DOT
# key (undefined)
key ZENKAKU_HANKAKU
key BACKSLASH
key F11
key F12
key RO
# key "KEY_KATAKANA"
# key "KEY_HIRAGANA"
key HENKAN
key KATAKANA_HIRAGANA
key MUHENKAN
key NUMPAD_COMMA
key NUMPAD_ENTER
key CTRL_RIGHT
key NUMPAD_DIVIDE
key SYSRQ
key ALT_RIGHT
# key "KEY_LINEFEED"
key MOVE_HOME
key DPAD_UP
key PAGE_UP
key DPAD_LEFT
key DPAD_RIGHT
key MOVE_END
key DPAD_DOWN
key PAGE_DOWN
key INSERT
key FORWARD_DEL
# key "KEY_MACRO"
key VOLUME_MUTE
key VOLUME_DOWN
key VOLUME_UP
key POWER WAKE
key NUMPAD_EQUALS
# key "KEY_KPPLUSMINUS"
key BREAK
# key (undefined)
key NUMPAD_COMMA
key KANA
key EISU
key YEN
key META_LEFT
key META_RIGHT
key MENU WAKE_DROPPED
key MEDIA_STOP
# key "KEY_AGAIN"
# key "KEY_PROPS"
# key "KEY_UNDO"
# key "KEY_FRONT"
# key "KEY_COPY"
# key "KEY_OPEN"
# key "KEY_PASTE"
# key "KEY_FIND"
# key "KEY_CUT"
# key "KEY_HELP"
key MENU WAKE_DROPPED
key CALCULATOR
# key "KEY_SETUP"
key POWER WAKE
key POWER WAKE
# key "KEY_FILE"
# key "KEY_SENDFILE"
# key "KEY_DELETEFILE"
# key "KEY_XFER"
# key "KEY_PROG1"
# key "KEY_PROG2"
key EXPLORER
# key "KEY_MSDOS"
key POWER WAKE
# key "KEY_DIRECTION"
# key "KEY_CYCLEWINDOWS"
key ENVELOPE
key BOOKMARK
# key "KEY_COMPUTER"
key BACK WAKE_DROPPED
key FORWARD
key MEDIA_CLOSE
key MEDIA_EJECT
key MEDIA_EJECT
key MEDIA_NEXT
key MEDIA_PLAY_PAUSE
key MEDIA_PREVIOUS
key MEDIA_STOP
key MEDIA_RECORD
key MEDIA_REWIND
key CALL
# key "KEY_ISO"
key MUSIC
key HOME
# key "KEY_REFRESH"
# key "KEY_EXIT"
# key "KEY_MOVE"
# key "KEY_EDIT"
key PAGE_UP
key PAGE_DOWN
key NUMPAD_LEFT_PAREN
key NUMPAD_RIGHT_PAREN
# key "KEY_NEW"
# key "KEY_REDO"
# key F13
# key F14
# key F15
# key F16
# key F17
# key F18
# key F19
# key F20
# key F21
# key F22
# key F23
# key F24
# key (undefined)
# key (undefined)
# key (undefined)
# key (undefined)
# key (undefined)
key MEDIA_PLAY
key MEDIA_PAUSE
# key "KEY_PROG3"
# key "KEY_PROG4"
# key (undefined)
# key "KEY_SUSPEND"
# key "KEY_CLOSE"
key MEDIA_PLAY
key MEDIA_FAST_FORWARD
# key "KEY_BASSBOOST"
# key "KEY_PRINT"
# key "KEY_HP"
key CAMERA
key MUSIC
# key "KEY_QUESTION"
key ENVELOPE
# key "KEY_CHAT"
key SEARCH
# key "KEY_CONNECT"
# key "KEY_FINANCE"
# key "KEY_SPORT"
# key "KEY_SHOP"
# key "KEY_ALTERASE"
# key "KEY_CANCEL"
key BRIGHTNESS_DOWN
key BRIGHTNESS_UP
key HEADSETHOOK key BUTTON_1
key BUTTON_2
key BUTTON_3
key BUTTON_4
key BUTTON_5
key BUTTON_6
key BUTTON_7
key BUTTON_8
key BUTTON_9
key BUTTON_10
key BUTTON_11
key BUTTON_12
key BUTTON_13
key BUTTON_14
key BUTTON_15
key BUTTON_16 key BUTTON_1
key BUTTON_2
key BUTTON_3
key BUTTON_4
key BUTTON_5
key BUTTON_6
key BUTTON_7
key BUTTON_8
key BUTTON_9
key BUTTON_10
key BUTTON_11
key BUTTON_12
key BUTTON_13
key BUTTON_14
key BUTTON_15
key BUTTON_16 key BUTTON_A
key BUTTON_B
key BUTTON_C
key BUTTON_X
key BUTTON_Y
key BUTTON_Z
key BUTTON_L1
key BUTTON_R1
key BUTTON_L2
key BUTTON_R2
key BUTTON_SELECT
key BUTTON_START
key BUTTON_MODE
key BUTTON_THUMBL
key BUTTON_THUMBR # key "KEY_OK"
key DPAD_CENTER
# key "KEY_GOTO"
# key "KEY_CLEAR"
# key "KEY_POWER2"
# key "KEY_OPTION"
# key "KEY_INFO"
# key "KEY_TIME"
# key "KEY_VENDOR"
# key "KEY_ARCHIVE"
key GUIDE
# key "KEY_CHANNEL"
# key "KEY_FAVORITES"
# key "KEY_EPG"
key DVR
# key "KEY_MHP"
# key "KEY_LANGUAGE"
# key "KEY_TITLE"
# key "KEY_SUBTITLE"
# key "KEY_ANGLE"
# key "KEY_ZOOM"
# key "KEY_MODE"
# key "KEY_KEYBOARD"
# key "KEY_SCREEN"
# key "KEY_PC"
key TV
# key "KEY_TV2"
# key "KEY_VCR"
# key "KEY_VCR2"
# key "KEY_SAT"
# key "KEY_SAT2"
# key "KEY_CD"
# key "KEY_TAPE"
# key "KEY_RADIO"
# key "KEY_TUNER"
# key "KEY_PLAYER"
# key "KEY_TEXT"
# key "KEY_DVD"
# key "KEY_AUX"
# key "KEY_MP3"
# key "KEY_AUDIO"
# key "KEY_VIDEO"
# key "KEY_DIRECTORY"
# key "KEY_LIST"
# key "KEY_MEMO"
key CALENDAR
# key "KEY_RED"
# key "KEY_GREEN"
# key "KEY_YELLOW"
# key "KEY_BLUE"
key CHANNEL_UP
key CHANNEL_DOWN
# key "KEY_FIRST"
# key "KEY_LAST"
# key "KEY_AB"
# key "KEY_NEXT"
# key "KEY_RESTART"
# key "KEY_SLOW"
# key "KEY_SHUFFLE"
# key "KEY_BREAK"
# key "KEY_PREVIOUS"
# key "KEY_DIGITS"
# key "KEY_TEEN"
# key "KEY_TWEN" key CONTACTS # key "KEY_DEL_EOL"
# key "KEY_DEL_EOS"
# key "KEY_INS_LINE"
# key "KEY_DEL_LINE" key FUNCTION
key ESCAPE FUNCTION
key F1 FUNCTION
key F2 FUNCTION
key F3 FUNCTION
key F4 FUNCTION
key F5 FUNCTION
key F6 FUNCTION
key F7 FUNCTION
key F8 FUNCTION
key F9 FUNCTION
key F10 FUNCTION
key F11 FUNCTION
key F12 FUNCTION
key FUNCTION
key FUNCTION
key D FUNCTION
key E FUNCTION
key F FUNCTION
key S FUNCTION
key B FUNCTION # key KEY_BRL_DOT1
# key KEY_BRL_DOT2
# key KEY_BRL_DOT3
# key KEY_BRL_DOT4
# key KEY_BRL_DOT5
# key KEY_BRL_DOT6
# key KEY_BRL_DOT7
# key KEY_BRL_DOT8 # Keys defined by HID usages
key usage 0x0c006F BRIGHTNESS_UP
key usage 0x0c0070 BRIGHTNESS_DOWN # Joystick and game controller axes.
# Axes that are not mapped will be assigned generic axis numbers by the input subsystem.
axis 0x00 X
axis 0x01 Y
axis 0x02 Z
axis 0x03 RX
axis 0x04 RY
axis 0x05 RZ
axis 0x06 THROTTLE
axis 0x07 RUDDER
axis 0x08 WHEEL
axis 0x09 GAS
axis 0x0a BRAKE
axis 0x10 HAT_X
axis 0x11 HAT_Y

键值从底层上报到上层的流程简图如下:

Android : 输入设备键值从底层到应用层的映射流程

      图2:键值上报流程

  从上图可以看到,framework层通过.kl文件将获取的键值转换成实际按键含义后,又会通过KeycodeLabel转换成相应的keycode,具体文件在:frameworks\native\include\input\KeycodeLabels.h(android 4.4.4源码):

/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ #ifndef _LIBINPUT_KEYCODE_LABELS_H
#define _LIBINPUT_KEYCODE_LABELS_H #include <android/keycodes.h> struct KeycodeLabel {
const char *literal;
int value;
}; static const KeycodeLabel KEYCODES[] = {
{ "SOFT_LEFT", },
{ "SOFT_RIGHT", },
{ "HOME", },
{ "BACK", },
{ "CALL", },
{ "ENDCALL", },
{ "", },
{ "", },
{ "", },
{ "", },
{ "", },
{ "", },
{ "", },
{ "", },
{ "", },
{ "", },
{ "STAR", },
{ "POUND", },
{ "DPAD_UP", },
{ "DPAD_DOWN", },
{ "DPAD_LEFT", },
{ "DPAD_RIGHT", },
{ "DPAD_CENTER", },
{ "VOLUME_UP", },
{ "VOLUME_DOWN", },
{ "POWER", },
{ "CAMERA", },
{ "CLEAR", },
{ "A", },
{ "B", },
{ "C", },
{ "D", },
{ "E", },
{ "F", },
{ "G", },
{ "H", },
{ "I", },
{ "J", },
{ "K", },
{ "L", },
{ "M", },
{ "N", },
{ "O", },
{ "P", },
{ "Q", },
{ "R", },
{ "S", },
{ "T", },
{ "U", },
{ "V", },
{ "W", },
{ "X", },
{ "Y", },
{ "Z", },
{ "COMMA", },
{ "PERIOD", },
{ "ALT_LEFT", },
{ "ALT_RIGHT", },
{ "SHIFT_LEFT", },
{ "SHIFT_RIGHT", },
{ "TAB", },
{ "SPACE", },
{ "SYM", },
{ "EXPLORER", },
{ "ENVELOPE", },
{ "ENTER", },
{ "DEL", },
{ "GRAVE", },
{ "MINUS", },
{ "EQUALS", },
{ "LEFT_BRACKET", },
{ "RIGHT_BRACKET", },
{ "BACKSLASH", },
{ "SEMICOLON", },
{ "APOSTROPHE", },
{ "SLASH", },
{ "AT", },
{ "NUM", },
{ "HEADSETHOOK", },
{ "FOCUS", },
{ "PLUS", },
{ "MENU", },
{ "NOTIFICATION", },
{ "SEARCH", },
{ "MEDIA_PLAY_PAUSE", },
{ "MEDIA_STOP", },
{ "MEDIA_NEXT", },
{ "MEDIA_PREVIOUS", },
{ "MEDIA_REWIND", },
{ "MEDIA_FAST_FORWARD", },
{ "MUTE", },
{ "PAGE_UP", },
{ "PAGE_DOWN", },
{ "PICTSYMBOLS", },
{ "SWITCH_CHARSET", },
{ "BUTTON_A", },
{ "BUTTON_B", },
{ "BUTTON_C", },
{ "BUTTON_X", },
{ "BUTTON_Y", },
{ "BUTTON_Z", },
{ "BUTTON_L1", },
{ "BUTTON_R1", },
{ "BUTTON_L2", },
{ "BUTTON_R2", },
{ "BUTTON_THUMBL", },
{ "BUTTON_THUMBR", },
{ "BUTTON_START", },
{ "BUTTON_SELECT", },
{ "BUTTON_MODE", },
{ "ESCAPE", },
{ "FORWARD_DEL", },
{ "CTRL_LEFT", },
{ "CTRL_RIGHT", },
{ "CAPS_LOCK", },
{ "SCROLL_LOCK", },
{ "META_LEFT", },
{ "META_RIGHT", },
{ "FUNCTION", },
{ "SYSRQ", },
{ "BREAK", },
{ "MOVE_HOME", },
{ "MOVE_END", },
{ "INSERT", },
{ "FORWARD", },
{ "MEDIA_PLAY", },
{ "MEDIA_PAUSE", },
{ "MEDIA_CLOSE", },
{ "MEDIA_EJECT", },
{ "MEDIA_RECORD", },
{ "F1", },
{ "F2", },
{ "F3", },
{ "F4", },
{ "F5", },
{ "F6", },
{ "F7", },
{ "F8", },
{ "F9", },
{ "F10", },
//{ "F11", 141 },
{ "F11", },
{ "F12", },
{ "NUM_LOCK", },
{ "NUMPAD_0", },
{ "NUMPAD_1", },
{ "NUMPAD_2", },
{ "NUMPAD_3", },
{ "NUMPAD_4", },
{ "NUMPAD_5", },
{ "NUMPAD_6", },
{ "NUMPAD_7", },
{ "NUMPAD_8", },
{ "NUMPAD_9", },
{ "NUMPAD_DIVIDE", },
{ "NUMPAD_MULTIPLY", },
{ "NUMPAD_SUBTRACT", },
{ "NUMPAD_ADD", },
{ "NUMPAD_DOT", },
{ "NUMPAD_COMMA", },
{ "NUMPAD_ENTER", },
{ "NUMPAD_EQUALS", },
{ "NUMPAD_LEFT_PAREN", },
{ "NUMPAD_RIGHT_PAREN", },
{ "VOLUME_MUTE", },
{ "INFO", },
{ "CHANNEL_UP", },
{ "CHANNEL_DOWN", },
{ "ZOOM_IN", },
{ "ZOOM_OUT", },
{ "TV", },
{ "WINDOW", },
{ "GUIDE", },
{ "DVR", },
{ "BOOKMARK", },
{ "CAPTIONS", },
{ "SETTINGS", },
{ "TV_POWER", },
{ "TV_INPUT", },
{ "STB_POWER", },
{ "STB_INPUT", },
{ "AVR_POWER", },
{ "AVR_INPUT", },
{ "PROG_RED", },
{ "PROG_GREEN", },
{ "PROG_YELLOW", },
{ "PROG_BLUE", },
{ "APP_SWITCH", },
{ "BUTTON_1", },
{ "BUTTON_2", },
{ "BUTTON_3", },
{ "BUTTON_4", },
{ "BUTTON_5", },
{ "BUTTON_6", },
{ "BUTTON_7", },
{ "BUTTON_8", },
{ "BUTTON_9", },
{ "BUTTON_10", },
{ "BUTTON_11", },
{ "BUTTON_12", },
{ "BUTTON_13", },
{ "BUTTON_14", },
{ "BUTTON_15", },
{ "BUTTON_16", },
{ "LANGUAGE_SWITCH", },
{ "MANNER_MODE", },
{ "3D_MODE", },
{ "CONTACTS", },
{ "CALENDAR", },
{ "MUSIC", },
{ "CALCULATOR", },
{ "ZENKAKU_HANKAKU", },
{ "EISU", },
{ "MUHENKAN", },
{ "HENKAN", },
{ "KATAKANA_HIRAGANA", },
{ "YEN", },
{ "RO", },
{ "KANA", },
{ "ASSIST", },
{ "BRIGHTNESS_DOWN", },
{ "BRIGHTNESS_UP", },
{ "MEDIA_AUDIO_TRACK", }, // NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. { NULL, }
}; // NOTE: If you edit these flags, also edit policy flags in Input.h.
static const KeycodeLabel FLAGS[] = {
{ "WAKE", 0x00000001 },
{ "WAKE_DROPPED", 0x00000002 },
{ "SHIFT", 0x00000004 },
{ "CAPS_LOCK", 0x00000008 },
{ "ALT", 0x00000010 },
{ "ALT_GR", 0x00000020 },
{ "MENU", 0x00000040 },
{ "LAUNCHER", 0x00000080 },
{ "VIRTUAL", 0x00000100 },
{ "FUNCTION", 0x00000200 },
{ NULL, }
}; static const KeycodeLabel AXES[] = {
{ "X", },
{ "Y", },
{ "PRESSURE", },
{ "SIZE", },
{ "TOUCH_MAJOR", },
{ "TOUCH_MINOR", },
{ "TOOL_MAJOR", },
{ "TOOL_MINOR", },
{ "ORIENTATION", },
{ "VSCROLL", },
{ "HSCROLL", },
{ "Z", },
{ "RX", },
{ "RY", },
{ "RZ", },
{ "HAT_X", },
{ "HAT_Y", },
{ "LTRIGGER", },
{ "RTRIGGER", },
{ "THROTTLE", },
{ "RUDDER", },
{ "WHEEL", },
{ "GAS", },
{ "BRAKE", },
{ "DISTANCE", },
{ "TILT", },
{ "GENERIC_1", },
{ "GENERIC_2", },
{ "GENERIC_3", },
{ "GENERIC_4", },
{ "GENERIC_5", },
{ "GENERIC_6", },
{ "GENERIC_7", },
{ "GENERIC_8", },
{ "GENERIC_9", },
{ "GENERIC_10", },
{ "GENERIC_11", },
{ "GENERIC_12", },
{ "GENERIC_13", },
{ "GENERIC_14", },
{ "GENERIC_15", },
{ "GENERIC_16", }, // NOTE: If you add a new axis here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list. { NULL, - }
}; #endif // _LIBINPUT_KEYCODE_LABELS_H

然后app可以通过如下方法获得对应键按下时的keyCode值,即“F11”对应获得的keyCode即为上面自定义的<546>:

    public boolean onKeyDown(int keyCode, KeyEvent event) { //重写的键盘按下监听
alert("获取系统keyCode : "+ keyCode);
return super.onKeyDown(keyCode, event);
}

 三、添加自定义的键值:

(1)Kernel层:

     include/uapi/linux/input.h 中添加: #define KEY_LXL               123
     drivers/hid/hid-input.c 中添加:                case 0x188: map_key_clear(KEY_LXL);      break;   //其中0x188是HID设备上报的原始键值


(2)Android系统层:

  ① bionic/libc/kernel/uapi/linux/input-event-codes.h 中添加  : #define KEY_LXL               123    //与kernel中头文件定义一致
  ②
Generic.kl或Vendor_xxxx_Product_xxxx.kl文件中添加      :  key 123 LXL;
   ③
/frameworks/native/include/android/keycodes.h  中添加  :  AKEYCODE_LXL          = 666,
   ④
/frameworks/native/include/input/KeycodeLabels.h 的KEYCODES[]数组中添加: { "LXL", 666 },
   在frameworks/base/core/res/res/values/attrs.xml 中添加 :  <enum name="KEYCODE_LXL" value="666" />
   ⑥ 在frameworks/base/core/java/android/view/KeyEvent.java添加: public static final int KEYCODE_LXL= 666;

      
       经过如上的步骤就将Linux驱动向上层抛出的"123"键值和Android系统中的KEYCODE_LXL <666>对应起来了,然后可以在Android的framework层的键值处理函数中,捕获按键事件,并进行相应自定义处理,具体在frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.javainterceptKeyBeforeQueueing()函数中实现。

Android : 输入设备键值从底层到应用层的映射流程的更多相关文章

  1. Android 添加键值并上报从驱动到上层

    转载:https://blog.csdn.net/weixin_43854010/article/details/94390803 Android 添加键值并上报从驱动到上层 平台 :RK3288 O ...

  2. Appium的一点一滴&colon;Android KEYCODE键值

    转自:http://blog.csdn.net/crisschan/article/details/50419963 - 电话键 键名 描述 键值 KEYCODE_CALL 拨号键 5 KEYCODE ...

  3. Appium ——Android KEYCODE键值:

    Python下语法: driver.keyevent(键值) 电话按键: 键名 描述 键值 KEYCODE_CALL 拨号键 5 KEYCODE_ENDCALL 挂机键 6 KEYCODE_HOME ...

  4. Android4&period;0 添加一个新的Android 键值

    这里添加新的键值,不是毫无凭据凭空创造的一个键值,而是根据kernel中检测到的按键值,然后转化为Android所需要的数值: 以添加一个Linux键值为217,把它映射为android的键值Brow ...

  5. Android4&period;2增加新键值

    这里添加新的键值,不是毫无凭据凭空创造的一个键值, 而是根据kernel中检测到的按键值,然后转化为android所需要的数值: 以添加一个linux键值为217,把它映射为android的键值Bro ...

  6. 从源码看HashMap键值对集合

    之前我们看过了两种类型的集合,ArrayList集合和LinkedList集合,两种集合各有优势,我们不具体说了,但是本篇要看的集合可以完成它们完成不了的任务.比如:现有一篇文章,要你统计其中出现了哪 ...

  7. Android底层开发之Linux输入子系统要不要推断系统休眠状态上报键值

    Android底层开发之Linux输入子系统要不要推断系统休眠状态上报键值 题外话:一个问题研究到最后,那边记录文档的前半部分基本上都是没用的,甚至是错误的. 重点在最后,前边不过一些假想猜測. ht ...

  8. Android下添加新的自定义键值和按键处理流程【转】

    本文转载自: Android下添加新的自定义键值和按键处理流程     说出来不怕大家笑话,我写这篇博客的原因在于前几天去一个小公司面试Android系统工程师,然后在面试的时候对方的技术总监问了我一 ...

  9. Android下添加新的自定义键值和按键处理流程

            Android下添加新的自定义键值和按键处理流程     说出来不怕大家笑话,我写这篇博客的原因在于前几天去一个小公司面试Android系统工程师,然后在面试的时候对方的技术总监问了我 ...

随机推荐

  1. solr4&period;3 java&period;lang&period;NumberFormatException

    solr java.lang.NumberFormatException 现象:定时每天全量,每隔5分钟增量DIH从mysql导入数据 solr4j返回加过Id列表,一天偶然出现 java.lang. ...

  2. mac ssh localhost

    转自:http://blog.csdn.net/cwj649956781/article/details/37913637 mac 无法ssh localhost,错误提示:bash: /usr/lo ...

  3. ubuntu环境变量

    在Ubuntu中有如下几个文件可以设置环境变量1./etc/profile:在登录时,操作系统定制用户环境时使用的第一个文件,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行.2. ...

  4. PHP 文件创建&sol;写入

    <?php /* PHP 文件创建/写入 fopen() 函数也用于创建文件.也许有点混乱, 但是在 PHP 中,创建文件所用的函数与打开文件的相同. 如果您用 fopen() 打开并不存在的文 ...

  5. yum命令mysql,jdk,tomcat

    一.首先使用Yum list available xxx命令罗列出远程仓库里面可以安装的包 1.列出可以安装的java包 yum list available java* 输出如下: 2.列出可以安装 ...

  6. &lbrack;转&rsqb;Win7下安装配置sharepoint server 2010

    转自:http://blog.sina.com.cn/s/blog_5d93d7aa010151lp.html 要开发SharePoint 2010应用程序,开发人员必须构建一个SharePoint ...

  7. iOS 面试题

    1.Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答:不可以,可以实现多个接口:category是分类,,一般情况下分类 ...

  8. 《JavaScript高级程序设计》心得笔记-----第三篇章

    第十章 1.    DOM1级定义了一个Node接口,以Node类型实现(除IE以外),为了确保跨浏览器兼容,最好用nodeType属性与数字数值进行比较(someNode. nodeType==1) ...

  9. js 使用技巧 - &lbrack;近几年工作中的经验总结的技巧&rsqb;

    1.如果 ajax 返回单一的 json 格式,接收方需要这样再格式化一下赋值: var str = eval("(" + msg + ")"); 开发引用: ...

  10. 【poj2891】同余方程组

    同余方程组 例题1:pku2891Strange Way to Express Integers 中国剩余定理求的同余方程组mod 的数是两两互素的.然而本题(一般情况,也包括两两互素的情况,所以中国 ...