Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
621 views
in Technique[技术] by (71.8m points)

unicode - Differentiating text keycode from control keycode in Android KeyEvent

There are 284 KeyEvent key codes. Some of them represent Unicode characters (like KEYCODE_A and KEYCODE_1), while others represent control characters (like KEYCODE_DEL).

I am making a custom view that handles keyboard input. It gets most of its input from an Input Connection, but sometimes keyboards send key codes (normall associated with hard keyboard input). I need to handle that, too. Do I need to exhaustively handle every control key code and then convert the rest to text (with (char) event.getUnicodeChar()) or is there a built in way to differentiate the text codes from the control codes?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The KeyEvent.getUnicodeChar() documentation says

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

Thus it is easy to differentiate text codes from control codes like this:

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

Here is a list that helped me reach this conclution:

// 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

Note that it might also be necessary to take dead keys into account. The docs say

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 'à'.

To get the dead key a combination of KeyEvent.getDeadChar(), COMBINING_ACCENT, and COMBINING_ACCENT_MASK are used. The following method is used in many open source projects to send hard key events on to the 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);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...