在 Android KeyEvent 中区分文本键码和控制键码

Differentiating text keycode from control keycode in Android KeyEvent

284 KeyEvent key codes个。其中一些表示 Unicode 字符(如 KEYCODE_AKEYCODE_1),而另一些表示控制字符(如 KEYCODE_DEL)。

我正在制作 custom view that handles keyboard input。它从输入连接获取大部分输入,但有时键盘会发送键码(通常与硬键盘输入相关联)。我也需要处理它。我是否需要详尽地处理每个控制键代码,然后将其余部分转换为文本(使用 (char) event.getUnicodeChar()),或者是否有一种内置的方法来区分文本代码和控制代码?

KeyEvent.getUnicodeChar() documentation

Returns 0 if the key is not one that is used to type Unicode characters.

因此很容易区分文本代码和控制代码,如下所示:

if (keyEvent.getUnicodeChar() != 0) {
    // unicode text
    char unicodeChar = (char) keyEvent.getUnicodeChar();
} else {
    // control char
}

这是帮助我得出这个结论的列表:

// keyCode, Unicode, char, keyCode name

0   0   ��  KEYCODE_UNKNOWN
1   0   ��  KEYCODE_SOFT_LEFT
2   0   ��  KEYCODE_SOFT_RIGHT
3   0   ��  KEYCODE_HOME
4   0   ��  KEYCODE_BACK
5   0   ��  KEYCODE_CALL
6   0   ��  KEYCODE_ENDCALL
7   48  0   KEYCODE_0
8   49  1   KEYCODE_1
9   50  2   KEYCODE_2
10  51  3   KEYCODE_3
11  52  4   KEYCODE_4
12  53  5   KEYCODE_5
13  54  6   KEYCODE_6
14  55  7   KEYCODE_7
15  56  8   KEYCODE_8
16  57  9   KEYCODE_9
17  42  *   KEYCODE_STAR
18  35  #   KEYCODE_POUND
19  0   ��  KEYCODE_DPAD_UP
20  0   ��  KEYCODE_DPAD_DOWN
21  0   ��  KEYCODE_DPAD_LEFT
22  0   ��  KEYCODE_DPAD_RIGHT
23  0   ��  KEYCODE_DPAD_CENTER
24  0   ��  KEYCODE_VOLUME_UP
25  0   ��  KEYCODE_VOLUME_DOWN
26  0   ��  KEYCODE_POWER
27  0   ��  KEYCODE_CAMERA
28  0   ��  KEYCODE_CLEAR
29  97  a   KEYCODE_A
30  98  b   KEYCODE_B
31  99  c   KEYCODE_C
32  100 d   KEYCODE_D
33  101 e   KEYCODE_E
34  102 f   KEYCODE_F
35  103 g   KEYCODE_G
36  104 h   KEYCODE_H
37  105 i   KEYCODE_I
38  106 j   KEYCODE_J
39  107 k   KEYCODE_K
40  108 l   KEYCODE_L
41  109 m   KEYCODE_M
42  110 n   KEYCODE_N
43  111 o   KEYCODE_O
44  112 p   KEYCODE_P
45  113 q   KEYCODE_Q
46  114 r   KEYCODE_R
47  115 s   KEYCODE_S
48  116 t   KEYCODE_T
49  117 u   KEYCODE_U
50  118 v   KEYCODE_V
51  119 w   KEYCODE_W
52  120 x   KEYCODE_X
53  121 y   KEYCODE_Y
54  122 z   KEYCODE_Z
55  44  ,   KEYCODE_COMMA
56  46  .   KEYCODE_PERIOD
57  0   ��  KEYCODE_ALT_LEFT
58  0   ��  KEYCODE_ALT_RIGHT
59  0   ��  KEYCODE_SHIFT_LEFT
60  0   ��  KEYCODE_SHIFT_RIGHT
61  9       KEYCODE_TAB
62  32      KEYCODE_SPACE
63  0   ��  KEYCODE_SYM
64  0   ��  KEYCODE_EXPLORER
65  0   ��  KEYCODE_ENVELOPE
66  10      KEYCODE_ENTER
67  0   ��  KEYCODE_DEL
68  96  `   KEYCODE_GRAVE
69  45  -   KEYCODE_MINUS
70  61  =   KEYCODE_EQUALS
71  91  [   KEYCODE_LEFT_BRACKET
72  93  ]   KEYCODE_RIGHT_BRACKET
73  92  \   KEYCODE_BACKSLASH
74  59  ;   KEYCODE_SEMICOLON
75  39  '   KEYCODE_APOSTROPHE
76  47  /   KEYCODE_SLASH
77  64  @   KEYCODE_AT
78  0   ��  KEYCODE_NUM
79  0   ��  KEYCODE_HEADSETHOOK
80  0   ��  KEYCODE_FOCUS
81  43  +   KEYCODE_PLUS
82  0   ��  KEYCODE_MENU
83  0   ��  KEYCODE_NOTIFICATION
84  0   ��  KEYCODE_SEARCH
85  0   ��  KEYCODE_MEDIA_PLAY_PAUSE
86  0   ��  KEYCODE_MEDIA_STOP
87  0   ��  KEYCODE_MEDIA_NEXT
88  0   ��  KEYCODE_MEDIA_PREVIOUS
89  0   ��  KEYCODE_MEDIA_REWIND
90  0   ��  KEYCODE_MEDIA_FAST_FORWARD
91  0   ��  KEYCODE_MUTE
92  0   ��  KEYCODE_PAGE_UP
93  0   ��  KEYCODE_PAGE_DOWN
94  0   ��  KEYCODE_PICTSYMBOLS
95  0   ��  KEYCODE_SWITCH_CHARSET
96  0   ��  KEYCODE_BUTTON_A
97  0   ��  KEYCODE_BUTTON_B
98  0   ��  KEYCODE_BUTTON_C
99  0   ��  KEYCODE_BUTTON_X
100 0   ��  KEYCODE_BUTTON_Y
101 0   ��  KEYCODE_BUTTON_Z
102 0   ��  KEYCODE_BUTTON_L1
103 0   ��  KEYCODE_BUTTON_R1
104 0   ��  KEYCODE_BUTTON_L2
105 0   ��  KEYCODE_BUTTON_R2
106 0   ��  KEYCODE_BUTTON_THUMBL
107 0   ��  KEYCODE_BUTTON_THUMBR
108 0   ��  KEYCODE_BUTTON_START
109 0   ��  KEYCODE_BUTTON_SELECT
110 0   ��  KEYCODE_BUTTON_MODE
111 0   ��  KEYCODE_ESCAPE
112 0   ��  KEYCODE_FORWARD_DEL
113 0   ��  KEYCODE_CTRL_LEFT
114 0   ��  KEYCODE_CTRL_RIGHT
115 0   ��  KEYCODE_CAPS_LOCK
116 0   ��  KEYCODE_SCROLL_LOCK
117 0   ��  KEYCODE_META_LEFT
118 0   ��  KEYCODE_META_RIGHT
119 0   ��  KEYCODE_FUNCTION
120 0   ��  KEYCODE_SYSRQ
121 0   ��  KEYCODE_BREAK
122 0   ��  KEYCODE_MOVE_HOME
123 0   ��  KEYCODE_MOVE_END
124 0   ��  KEYCODE_INSERT
125 0   ��  KEYCODE_FORWARD
126 0   ��  KEYCODE_MEDIA_PLAY
127 0   ��  KEYCODE_MEDIA_PAUSE
128 0   ��  KEYCODE_MEDIA_CLOSE
129 0   ��  KEYCODE_MEDIA_EJECT
130 0   ��  KEYCODE_MEDIA_RECORD
131 0   ��  KEYCODE_F1
132 0   ��  KEYCODE_F2
133 0   ��  KEYCODE_F3
134 0   ��  KEYCODE_F4
135 0   ��  KEYCODE_F5
136 0   ��  KEYCODE_F6
137 0   ��  KEYCODE_F7
138 0   ��  KEYCODE_F8
139 0   ��  KEYCODE_F9
140 0   ��  KEYCODE_F10
141 0   ��  KEYCODE_F11
142 0   ��  KEYCODE_F12
143 0   ��  KEYCODE_NUM_LOCK
144 0   ��  KEYCODE_NUMPAD_0
145 0   ��  KEYCODE_NUMPAD_1
146 0   ��  KEYCODE_NUMPAD_2
147 0   ��  KEYCODE_NUMPAD_3
148 0   ��  KEYCODE_NUMPAD_4
149 0   ��  KEYCODE_NUMPAD_5
150 0   ��  KEYCODE_NUMPAD_6
151 0   ��  KEYCODE_NUMPAD_7
152 0   ��  KEYCODE_NUMPAD_8
153 0   ��  KEYCODE_NUMPAD_9
154 47  /   KEYCODE_NUMPAD_DIVIDE
155 42  *   KEYCODE_NUMPAD_MULTIPLY
156 45  -   KEYCODE_NUMPAD_SUBTRACT
157 43  +   KEYCODE_NUMPAD_ADD
158 0   ��  KEYCODE_NUMPAD_DOT
159 44  ,   KEYCODE_NUMPAD_COMMA
160 10      KEYCODE_NUMPAD_ENTER
161 61  =   KEYCODE_NUMPAD_EQUALS
162 40  (   KEYCODE_NUMPAD_LEFT_PAREN
163 41  )   KEYCODE_NUMPAD_RIGHT_PAREN
164 0   ��  KEYCODE_VOLUME_MUTE
165 0   ��  KEYCODE_INFO
166 0   ��  KEYCODE_CHANNEL_UP
167 0   ��  KEYCODE_CHANNEL_DOWN
168 0   ��  KEYCODE_ZOOM_IN
169 0   ��  KEYCODE_ZOOM_OUT
170 0   ��  KEYCODE_TV
171 0   ��  KEYCODE_WINDOW
172 0   ��  KEYCODE_GUIDE
173 0   ��  KEYCODE_DVR
174 0   ��  KEYCODE_BOOKMARK
175 0   ��  KEYCODE_CAPTIONS
176 0   ��  KEYCODE_SETTINGS
177 0   ��  KEYCODE_TV_POWER
178 0   ��  KEYCODE_TV_INPUT
179 0   ��  KEYCODE_STB_POWER
180 0   ��  KEYCODE_STB_INPUT
181 0   ��  KEYCODE_AVR_POWER
182 0   ��  KEYCODE_AVR_INPUT
183 0   ��  KEYCODE_PROG_RED
184 0   ��  KEYCODE_PROG_GREEN
185 0   ��  KEYCODE_PROG_YELLOW
186 0   ��  KEYCODE_PROG_BLUE
187 0   ��  KEYCODE_APP_SWITCH
188 0   ��  KEYCODE_BUTTON_1
189 0   ��  KEYCODE_BUTTON_2
190 0   ��  KEYCODE_BUTTON_3
191 0   ��  KEYCODE_BUTTON_4
192 0   ��  KEYCODE_BUTTON_5
193 0   ��  KEYCODE_BUTTON_6
194 0   ��  KEYCODE_BUTTON_7
195 0   ��  KEYCODE_BUTTON_8
196 0   ��  KEYCODE_BUTTON_9
197 0   ��  KEYCODE_BUTTON_10
198 0   ��  KEYCODE_BUTTON_11
199 0   ��  KEYCODE_BUTTON_12
200 0   ��  KEYCODE_BUTTON_13
201 0   ��  KEYCODE_BUTTON_14
202 0   ��  KEYCODE_BUTTON_15
203 0   ��  KEYCODE_BUTTON_16
204 0   ��  KEYCODE_LANGUAGE_SWITCH
205 0   ��  KEYCODE_MANNER_MODE
206 0   ��  KEYCODE_3D_MODE
207 0   ��  KEYCODE_CONTACTS
208 0   ��  KEYCODE_CALENDAR
209 0   ��  KEYCODE_MUSIC
210 0   ��  KEYCODE_CALCULATOR
211 0   ��  KEYCODE_ZENKAKU_HANKAKU
212 0   ��  KEYCODE_EISU
213 0   ��  KEYCODE_MUHENKAN
214 0   ��  KEYCODE_HENKAN
215 0   ��  KEYCODE_KATAKANA_HIRAGANA
216 0   ��  KEYCODE_YEN
217 0   ��  KEYCODE_RO
218 0   ��  KEYCODE_KANA
219 0   ��  KEYCODE_ASSIST
220 0   ��  KEYCODE_BRIGHTNESS_DOWN
221 0   ��  KEYCODE_BRIGHTNESS_UP
222 0   ��  KEYCODE_MEDIA_AUDIO_TRACK
223 0   ��  KEYCODE_SLEEP
224 0   ��  KEYCODE_WAKEUP
225 0   ��  KEYCODE_PAIRING
226 0   ��  KEYCODE_MEDIA_TOP_MENU
227 0   ��  KEYCODE_11
228 0   ��  KEYCODE_12
229 0   ��  KEYCODE_LAST_CHANNEL
230 0   ��  KEYCODE_TV_DATA_SERVICE
231 0   ��  KEYCODE_VOICE_ASSIST
232 0   ��  KEYCODE_TV_RADIO_SERVICE
233 0   ��  KEYCODE_TV_TELETEXT
234 0   ��  KEYCODE_TV_NUMBER_ENTRY
235 0   ��  KEYCODE_TV_TERRESTRIAL_ANALOG
236 0   ��  KEYCODE_TV_TERRESTRIAL_DIGITAL
237 0   ��  KEYCODE_TV_SATELLITE
238 0   ��  KEYCODE_TV_SATELLITE_BS
239 0   ��  KEYCODE_TV_SATELLITE_CS
240 0   ��  KEYCODE_TV_SATELLITE_SERVICE
241 0   ��  KEYCODE_TV_NETWORK
242 0   ��  KEYCODE_TV_ANTENNA_CABLE
243 0   ��  KEYCODE_TV_INPUT_HDMI_1
244 0   ��  KEYCODE_TV_INPUT_HDMI_2
245 0   ��  KEYCODE_TV_INPUT_HDMI_3
246 0   ��  KEYCODE_TV_INPUT_HDMI_4
247 0   ��  KEYCODE_TV_INPUT_COMPOSITE_1
248 0   ��  KEYCODE_TV_INPUT_COMPOSITE_2
249 0   ��  KEYCODE_TV_INPUT_COMPONENT_1
250 0   ��  KEYCODE_TV_INPUT_COMPONENT_2
251 0   ��  KEYCODE_TV_INPUT_VGA_1
252 0   ��  KEYCODE_TV_AUDIO_DESCRIPTION
253 0   ��  KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP
254 0   ��  KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN
255 0   ��  KEYCODE_TV_ZOOM_MODE
256 0   ��  KEYCODE_TV_CONTENTS_MENU
257 0   ��  KEYCODE_TV_MEDIA_CONTEXT_MENU
258 0   ��  KEYCODE_TV_TIMER_PROGRAMMING
259 0   ��  KEYCODE_HELP
260 0   ��  KEYCODE_NAVIGATE_PREVIOUS
261 0   ��  KEYCODE_NAVIGATE_NEXT
262 0   ��  KEYCODE_NAVIGATE_IN
263 0   ��  KEYCODE_NAVIGATE_OUT
264 0   ��  KEYCODE_STEM_PRIMARY
265 0   ��  KEYCODE_STEM_1
266 0   ��  KEYCODE_STEM_2
267 0   ��  KEYCODE_STEM_3
268 0   ��  KEYCODE_DPAD_UP_LEFT
269 0   ��  KEYCODE_DPAD_DOWN_LEFT
270 0   ��  KEYCODE_DPAD_UP_RIGHT
271 0   ��  KEYCODE_DPAD_DOWN_RIGHT
272 0   ��  KEYCODE_MEDIA_SKIP_FORWARD
273 0   ��  KEYCODE_MEDIA_SKIP_BACKWARD
274 0   ��  KEYCODE_MEDIA_STEP_FORWARD
275 0   ��  KEYCODE_MEDIA_STEP_BACKWARD
276 0   ��  KEYCODE_SOFT_SLEEP
277 0   ��  KEYCODE_CUT
278 0   ��  KEYCODE_COPY
279 0   ��  KEYCODE_PASTE
280 0   ��  KEYCODE_SYSTEM_NAVIGATION_UP
281 0   ��  KEYCODE_SYSTEM_NAVIGATION_DOWN
282 0   ��  KEYCODE_SYSTEM_NAVIGATION_LEFT
283 0   ��  KEYCODE_SYSTEM_NAVIGATION_RIGHT

死键

请注意,可能还需要 dead keys into account. The docs

The system recognizes the following Unicode characters as combining diacritical dead key characters.

  • '\u0300': Grave accent.
  • '\u0301': Acute accent.
  • '\u0302': Circumflex accent.
  • '\u0303': Tilde accent.
  • '\u0308': Umlaut accent.

When a dead key is typed followed by another character, the dead key and the following characters are composed. For example, when the user types a grave accent dead key followed by the letter 'a', the result is 'à'.

要获得死键 KeyEvent.getDeadChar(), COMBINING_ACCENT, and COMBINING_ACCENT_MASK are used. The following method is used in many open source projects 的组合,将硬键事件发送到 InputConnection

/**
 * This translates incoming hard key events in to edit operations on an
 * InputConnection.  It is only needed when using the
 * PROCESS_HARD_KEYS option.
 */
private boolean translateKeyDown(int keyCode, KeyEvent event) {
    mMetaState = MetaKeyKeyListener.handleKeyDown(mMetaState,
            keyCode, event);
    int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(mMetaState));
    mMetaState = MetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState);
    InputConnection ic = getCurrentInputConnection();
    if (c == 0 || ic == null) {
        return false;
    }

    boolean dead = false;

    if ((c & KeyCharacterMap.COMBINING_ACCENT) != 0) {
        dead = true;
        c = c & KeyCharacterMap.COMBINING_ACCENT_MASK;
    }

    if (mComposing.length() > 0) {
        char accent = mComposing.charAt(mComposing.length() -1 );
        int composed = KeyEvent.getDeadChar(accent, c);

        if (composed != 0) {
            c = composed;
            mComposing.setLength(mComposing.length()-1);
        }
    }

    onKey(c, null);

    return true;
}

另一种方式?

@pskink 提到 TextKeyListener, BaseKeyListener and KeyListener。这些很可能是更好的方法。但是,我找不到关于如何使用它们的充分解释和示例。