Android 系统按键码对照表:KeyEvent 常用键值与调试指南

在 Android 里,按键事件通常通过 KeyEvent 表达。无论是实体键、遥控器、车机按键、扫码枪、游戏手柄,还是通过 adb shell input keyevent 模拟的按键,最终都会落到一组 KEYCODE_* 常量上。
这篇文章整理一份常用 Android 系统按键码对照表,并补充实际开发中如何接收、分发和调试按键事件。
1. 先看结论
Android 按键码主要有三种常见使用方式:
adb shell input keyevent 4
adb shell input keyevent KEYCODE_BACK
adb shell input keyevent --longpress KEYCODE_POWER
对应到代码里,一般会看到:
override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
return when (keyCode) {
KeyEvent.KEYCODE_BACK -> {
// 处理返回键
true
}
KeyEvent.KEYCODE_VOLUME_UP -> {
// 处理音量加
true
}
else -> super.onKeyDown(keyCode, event)
}
}
如果只是做自动化测试、遥控器适配或硬件按键排查,优先记住这几个:
| 按键 | KeyEvent 常量 | 数值 |
|---|---|---|
| 返回 | KEYCODE_BACK |
4 |
| Home | KEYCODE_HOME |
3 |
| 菜单 | KEYCODE_MENU |
82 |
| 电源 | KEYCODE_POWER |
26 |
| 音量加 | KEYCODE_VOLUME_UP |
24 |
| 音量减 | KEYCODE_VOLUME_DOWN |
25 |
| 确认 / 中键 | KEYCODE_DPAD_CENTER |
23 |
| 方向上 | KEYCODE_DPAD_UP |
19 |
| 方向下 | KEYCODE_DPAD_DOWN |
20 |
| 方向左 | KEYCODE_DPAD_LEFT |
21 |
| 方向右 | KEYCODE_DPAD_RIGHT |
22 |
| 删除 | KEYCODE_DEL |
67 |
| 回车 | KEYCODE_ENTER |
66 |
2. 系统与导航按键
| 数值 | KeyEvent 常量 | 说明 |
|---|---|---|
0 |
KEYCODE_UNKNOWN |
未知按键 |
1 |
KEYCODE_SOFT_LEFT |
左软键,早期设备常见 |
2 |
KEYCODE_SOFT_RIGHT |
右软键,早期设备常见 |
3 |
KEYCODE_HOME |
Home 键,普通应用通常无法拦截 |
4 |
KEYCODE_BACK |
返回键 |
5 |
KEYCODE_CALL |
拨号键 |
6 |
KEYCODE_ENDCALL |
挂断键 |
26 |
KEYCODE_POWER |
电源键,普通应用通常无法拦截 |
27 |
KEYCODE_CAMERA |
相机键 |
28 |
KEYCODE_CLEAR |
清除键 |
80 |
KEYCODE_FOCUS |
相机半按对焦 |
82 |
KEYCODE_MENU |
菜单键 |
83 |
KEYCODE_NOTIFICATION |
通知键 |
84 |
KEYCODE_SEARCH |
搜索键 |
176 |
KEYCODE_SETTINGS |
设置键 |
219 |
KEYCODE_ASSIST |
助手键 |
231 |
KEYCODE_VOICE_ASSIST |
语音助手键 |
280 |
KEYCODE_SYSTEM_NAVIGATION_UP |
系统导航上 |
281 |
KEYCODE_SYSTEM_NAVIGATION_DOWN |
系统导航下 |
282 |
KEYCODE_SYSTEM_NAVIGATION_LEFT |
系统导航左 |
283 |
KEYCODE_SYSTEM_NAVIGATION_RIGHT |
系统导航右 |
284 |
KEYCODE_ALL_APPS |
所有应用 |
注意:HOME、POWER 这类系统级按键通常不会完整交给普通应用处理,系统会优先拦截。应用层能不能收到,取决于设备类型、窗口焦点、权限、系统版本和厂商定制。
3. 数字与字母按键
3.1 数字键
| 数值 | KeyEvent 常量 | 字符 |
|---|---|---|
7 |
KEYCODE_0 |
0 |
8 |
KEYCODE_1 |
1 |
9 |
KEYCODE_2 |
2 |
10 |
KEYCODE_3 |
3 |
11 |
KEYCODE_4 |
4 |
12 |
KEYCODE_5 |
5 |
13 |
KEYCODE_6 |
6 |
14 |
KEYCODE_7 |
7 |
15 |
KEYCODE_8 |
8 |
16 |
KEYCODE_9 |
9 |
3.2 字母键
| 数值 | KeyEvent 常量 | 字符 |
|---|---|---|
29 |
KEYCODE_A |
A |
30 |
KEYCODE_B |
B |
31 |
KEYCODE_C |
C |
32 |
KEYCODE_D |
D |
33 |
KEYCODE_E |
E |
34 |
KEYCODE_F |
F |
35 |
KEYCODE_G |
G |
36 |
KEYCODE_H |
H |
37 |
KEYCODE_I |
I |
38 |
KEYCODE_J |
J |
39 |
KEYCODE_K |
K |
40 |
KEYCODE_L |
L |
41 |
KEYCODE_M |
M |
42 |
KEYCODE_N |
N |
43 |
KEYCODE_O |
O |
44 |
KEYCODE_P |
P |
45 |
KEYCODE_Q |
Q |
46 |
KEYCODE_R |
R |
47 |
KEYCODE_S |
S |
48 |
KEYCODE_T |
T |
49 |
KEYCODE_U |
U |
50 |
KEYCODE_V |
V |
51 |
KEYCODE_W |
W |
52 |
KEYCODE_X |
X |
53 |
KEYCODE_Y |
Y |
54 |
KEYCODE_Z |
Z |
4. 符号、编辑与输入控制
| 数值 | KeyEvent 常量 | 说明 |
|---|---|---|
17 |
KEYCODE_STAR |
* |
18 |
KEYCODE_POUND |
# |
55 |
KEYCODE_COMMA |
逗号 |
56 |
KEYCODE_PERIOD |
句号 |
57 |
KEYCODE_ALT_LEFT |
左 Alt |
58 |
KEYCODE_ALT_RIGHT |
右 Alt |
59 |
KEYCODE_SHIFT_LEFT |
左 Shift |
60 |
KEYCODE_SHIFT_RIGHT |
右 Shift |
61 |
KEYCODE_TAB |
Tab |
62 |
KEYCODE_SPACE |
空格 |
63 |
KEYCODE_SYM |
符号键 |
66 |
KEYCODE_ENTER |
回车 |
67 |
KEYCODE_DEL |
退格删除 |
68 |
KEYCODE_GRAVE |
反引号 |
69 |
KEYCODE_MINUS |
减号 |
70 |
KEYCODE_EQUALS |
等号 |
71 |
KEYCODE_LEFT_BRACKET |
左中括号 |
72 |
KEYCODE_RIGHT_BRACKET |
右中括号 |
73 |
KEYCODE_BACKSLASH |
反斜杠 |
74 |
KEYCODE_SEMICOLON |
分号 |
75 |
KEYCODE_APOSTROPHE |
单引号 |
76 |
KEYCODE_SLASH |
斜杠 |
77 |
KEYCODE_AT |
@ |
78 |
KEYCODE_NUM |
数字修饰键 |
81 |
KEYCODE_PLUS |
加号 |
112 |
KEYCODE_FORWARD_DEL |
向前删除 |
113 |
KEYCODE_CTRL_LEFT |
左 Ctrl |
114 |
KEYCODE_CTRL_RIGHT |
右 Ctrl |
115 |
KEYCODE_CAPS_LOCK |
Caps Lock |
116 |
KEYCODE_SCROLL_LOCK |
Scroll Lock |
120 |
KEYCODE_SYSRQ |
Print Screen / SysRq |
121 |
KEYCODE_BREAK |
Break / Pause |
122 |
KEYCODE_MOVE_HOME |
移到行首或文首 |
123 |
KEYCODE_MOVE_END |
移到行尾或文末 |
124 |
KEYCODE_INSERT |
Insert |
143 |
KEYCODE_NUM_LOCK |
Num Lock |
111 |
KEYCODE_ESCAPE |
Esc |
5. 方向键、翻页与遥控器常用键
这组按键在 Android TV、车机、投屏盒子、工业设备和无触屏设备上尤其常见。
| 数值 | KeyEvent 常量 | 说明 |
|---|---|---|
19 |
KEYCODE_DPAD_UP |
方向上 |
20 |
KEYCODE_DPAD_DOWN |
方向下 |
21 |
KEYCODE_DPAD_LEFT |
方向左 |
22 |
KEYCODE_DPAD_RIGHT |
方向右 |
23 |
KEYCODE_DPAD_CENTER |
确认 / 中键 |
92 |
KEYCODE_PAGE_UP |
上翻页 |
93 |
KEYCODE_PAGE_DOWN |
下翻页 |
108 |
KEYCODE_BUTTON_START |
开始键 |
109 |
KEYCODE_BUTTON_SELECT |
选择键 |
110 |
KEYCODE_BUTTON_MODE |
模式键 |
131 |
KEYCODE_F1 |
F1 |
132 |
KEYCODE_F2 |
F2 |
133 |
KEYCODE_F3 |
F3 |
134 |
KEYCODE_F4 |
F4 |
135 |
KEYCODE_F5 |
F5 |
136 |
KEYCODE_F6 |
F6 |
137 |
KEYCODE_F7 |
F7 |
138 |
KEYCODE_F8 |
F8 |
139 |
KEYCODE_F9 |
F9 |
140 |
KEYCODE_F10 |
F10 |
141 |
KEYCODE_F11 |
F11 |
142 |
KEYCODE_F12 |
F12 |
如果是 TV 页面焦点问题,优先排查三件事:
- 当前控件是否
focusable。 - 焦点移动规则是否被
nextFocusUp / nextFocusDown / nextFocusLeft / nextFocusRight改写。 onKeyDown是否消费了事件,导致子控件或系统无法继续处理。
6. 音量、媒体播放与耳机线控
| 数值 | KeyEvent 常量 | 说明 |
|---|---|---|
24 |
KEYCODE_VOLUME_UP |
音量加 |
25 |
KEYCODE_VOLUME_DOWN |
音量减 |
79 |
KEYCODE_HEADSETHOOK |
耳机线控 |
85 |
KEYCODE_MEDIA_PLAY_PAUSE |
播放 / 暂停 |
86 |
KEYCODE_MEDIA_STOP |
停止 |
87 |
KEYCODE_MEDIA_NEXT |
下一首 |
88 |
KEYCODE_MEDIA_PREVIOUS |
上一首 |
89 |
KEYCODE_MEDIA_REWIND |
快退 |
90 |
KEYCODE_MEDIA_FAST_FORWARD |
快进 |
91 |
KEYCODE_MUTE |
静音 |
126 |
KEYCODE_MEDIA_PLAY |
播放 |
127 |
KEYCODE_MEDIA_PAUSE |
暂停 |
128 |
KEYCODE_MEDIA_CLOSE |
关闭媒体 |
129 |
KEYCODE_MEDIA_EJECT |
弹出 |
130 |
KEYCODE_MEDIA_RECORD |
录制 |
164 |
KEYCODE_VOLUME_MUTE |
音量静音 |
222 |
KEYCODE_MEDIA_AUDIO_TRACK |
切换音轨 |
媒体键不一定直接进入当前 Activity。如果应用需要处理后台播放控制,通常要通过 MediaSession 暴露播放状态和控制能力,而不是只依赖 Activity.onKeyDown()。
最小示例如下:
val mediaSession = MediaSessionCompat(context, "PlayerSession")
mediaSession.setCallback(object : MediaSessionCompat.Callback() {
override fun onPlay() {
// 开始播放
}
override fun onPause() {
// 暂停播放
}
override fun onSkipToNext() {
// 下一首
}
override fun onSkipToPrevious() {
// 上一首
}
})
mediaSession.isActive = true
7. 电话、浏览器与应用快捷键
| 数值 | KeyEvent 常量 | 说明 |
|---|---|---|
64 |
KEYCODE_EXPLORER |
浏览器 / Explorer |
65 |
KEYCODE_ENVELOPE |
邮件 |
94 |
KEYCODE_PICTSYMBOLS |
图片符号 |
95 |
KEYCODE_SWITCH_CHARSET |
切换字符集 |
207 |
KEYCODE_CONTACTS |
联系人 |
208 |
KEYCODE_CALENDAR |
日历 |
209 |
KEYCODE_MUSIC |
音乐 |
210 |
KEYCODE_CALCULATOR |
计算器 |
220 |
KEYCODE_BRIGHTNESS_DOWN |
亮度减 |
221 |
KEYCODE_BRIGHTNESS_UP |
亮度加 |
223 |
KEYCODE_SLEEP |
休眠 |
224 |
KEYCODE_WAKEUP |
唤醒 |
276 |
KEYCODE_SOFT_SLEEP |
软休眠 |
8. 小键盘按键
| 数值 | KeyEvent 常量 | 说明 |
|---|---|---|
144 |
KEYCODE_NUMPAD_0 |
小键盘 0 |
145 |
KEYCODE_NUMPAD_1 |
小键盘 1 |
146 |
KEYCODE_NUMPAD_2 |
小键盘 2 |
147 |
KEYCODE_NUMPAD_3 |
小键盘 3 |
148 |
KEYCODE_NUMPAD_4 |
小键盘 4 |
149 |
KEYCODE_NUMPAD_5 |
小键盘 5 |
150 |
KEYCODE_NUMPAD_6 |
小键盘 6 |
151 |
KEYCODE_NUMPAD_7 |
小键盘 7 |
152 |
KEYCODE_NUMPAD_8 |
小键盘 8 |
153 |
KEYCODE_NUMPAD_9 |
小键盘 9 |
154 |
KEYCODE_NUMPAD_DIVIDE |
小键盘除号 |
155 |
KEYCODE_NUMPAD_MULTIPLY |
小键盘乘号 |
156 |
KEYCODE_NUMPAD_SUBTRACT |
小键盘减号 |
157 |
KEYCODE_NUMPAD_ADD |
小键盘加号 |
158 |
KEYCODE_NUMPAD_DOT |
小键盘点号 |
159 |
KEYCODE_NUMPAD_COMMA |
小键盘逗号 |
160 |
KEYCODE_NUMPAD_ENTER |
小键盘回车 |
161 |
KEYCODE_NUMPAD_EQUALS |
小键盘等号 |
162 |
KEYCODE_NUMPAD_LEFT_PAREN |
小键盘左括号 |
163 |
KEYCODE_NUMPAD_RIGHT_PAREN |
小键盘右括号 |
9. 游戏手柄按键
部分游戏手柄按键码会和遥控器、方向控制场景复用,例如 KEYCODE_BUTTON_SELECT 也可能出现在非游戏设备上。判断业务语义时,除了看 keyCode,也可以结合 event.device、event.source 和具体设备类型。
| 数值 | KeyEvent 常量 | 说明 |
|---|---|---|
96 |
KEYCODE_BUTTON_A |
A 键 |
97 |
KEYCODE_BUTTON_B |
B 键 |
98 |
KEYCODE_BUTTON_C |
C 键 |
99 |
KEYCODE_BUTTON_X |
X 键 |
100 |
KEYCODE_BUTTON_Y |
Y 键 |
101 |
KEYCODE_BUTTON_Z |
Z 键 |
102 |
KEYCODE_BUTTON_L1 |
L1 |
103 |
KEYCODE_BUTTON_R1 |
R1 |
104 |
KEYCODE_BUTTON_L2 |
L2 |
105 |
KEYCODE_BUTTON_R2 |
R2 |
106 |
KEYCODE_BUTTON_THUMBL |
左摇杆按下 |
107 |
KEYCODE_BUTTON_THUMBR |
右摇杆按下 |
108 |
KEYCODE_BUTTON_START |
Start |
109 |
KEYCODE_BUTTON_SELECT |
Select |
110 |
KEYCODE_BUTTON_MODE |
Mode |
188 |
KEYCODE_BUTTON_1 |
通用按键 1 |
189 |
KEYCODE_BUTTON_2 |
通用按键 2 |
190 |
KEYCODE_BUTTON_3 |
通用按键 3 |
191 |
KEYCODE_BUTTON_4 |
通用按键 4 |
192 |
KEYCODE_BUTTON_5 |
通用按键 5 |
193 |
KEYCODE_BUTTON_6 |
通用按键 6 |
194 |
KEYCODE_BUTTON_7 |
通用按键 7 |
195 |
KEYCODE_BUTTON_8 |
通用按键 8 |
196 |
KEYCODE_BUTTON_9 |
通用按键 9 |
197 |
KEYCODE_BUTTON_10 |
通用按键 10 |
198 |
KEYCODE_BUTTON_11 |
通用按键 11 |
199 |
KEYCODE_BUTTON_12 |
通用按键 12 |
200 |
KEYCODE_BUTTON_13 |
通用按键 13 |
201 |
KEYCODE_BUTTON_14 |
通用按键 14 |
202 |
KEYCODE_BUTTON_15 |
通用按键 15 |
203 |
KEYCODE_BUTTON_16 |
通用按键 16 |
10. TV、机顶盒与频道控制
| 数值 | KeyEvent 常量 | 说明 |
|---|---|---|
165 |
KEYCODE_INFO |
信息 |
166 |
KEYCODE_CHANNEL_UP |
频道加 |
167 |
KEYCODE_CHANNEL_DOWN |
频道减 |
168 |
KEYCODE_ZOOM_IN |
放大 |
169 |
KEYCODE_ZOOM_OUT |
缩小 |
170 |
KEYCODE_TV |
TV |
171 |
KEYCODE_WINDOW |
窗口 |
172 |
KEYCODE_GUIDE |
节目指南 |
173 |
KEYCODE_DVR |
DVR |
174 |
KEYCODE_BOOKMARK |
书签 |
175 |
KEYCODE_CAPTIONS |
字幕 |
177 |
KEYCODE_TV_POWER |
TV 电源 |
178 |
KEYCODE_TV_INPUT |
TV 输入源 |
179 |
KEYCODE_STB_POWER |
机顶盒电源 |
180 |
KEYCODE_STB_INPUT |
机顶盒输入源 |
181 |
KEYCODE_AVR_POWER |
音视频接收器电源 |
182 |
KEYCODE_AVR_INPUT |
音视频接收器输入源 |
183 |
KEYCODE_PROG_RED |
红色功能键 |
184 |
KEYCODE_PROG_GREEN |
绿色功能键 |
185 |
KEYCODE_PROG_YELLOW |
黄色功能键 |
186 |
KEYCODE_PROG_BLUE |
蓝色功能键 |
226 |
KEYCODE_MEDIA_TOP_MENU |
媒体顶层菜单 |
227 |
KEYCODE_11 |
数字 11 |
228 |
KEYCODE_12 |
数字 12 |
229 |
KEYCODE_LAST_CHANNEL |
上一个频道 |
230 |
KEYCODE_TV_DATA_SERVICE |
TV 数据服务 |
232 |
KEYCODE_TV_RADIO_SERVICE |
TV 广播服务 |
233 |
KEYCODE_TV_TELETEXT |
图文电视 |
234 |
KEYCODE_TV_NUMBER_ENTRY |
TV 数字输入 |
235 |
KEYCODE_TV_TERRESTRIAL_ANALOG |
地面模拟电视 |
236 |
KEYCODE_TV_TERRESTRIAL_DIGITAL |
地面数字电视 |
237 |
KEYCODE_TV_SATELLITE |
卫星电视 |
238 |
KEYCODE_TV_SATELLITE_BS |
BS 卫星 |
239 |
KEYCODE_TV_SATELLITE_CS |
CS 卫星 |
240 |
KEYCODE_TV_SATELLITE_SERVICE |
卫星服务 |
241 |
KEYCODE_TV_NETWORK |
TV 网络 |
242 |
KEYCODE_TV_ANTENNA_CABLE |
天线 / 有线 |
243 |
KEYCODE_TV_INPUT_HDMI_1 |
HDMI 1 |
244 |
KEYCODE_TV_INPUT_HDMI_2 |
HDMI 2 |
245 |
KEYCODE_TV_INPUT_HDMI_3 |
HDMI 3 |
246 |
KEYCODE_TV_INPUT_HDMI_4 |
HDMI 4 |
247 |
KEYCODE_TV_INPUT_COMPOSITE_1 |
Composite 1 |
248 |
KEYCODE_TV_INPUT_COMPOSITE_2 |
Composite 2 |
249 |
KEYCODE_TV_INPUT_COMPONENT_1 |
Component 1 |
250 |
KEYCODE_TV_INPUT_COMPONENT_2 |
Component 2 |
251 |
KEYCODE_TV_INPUT_VGA_1 |
VGA 1 |
252 |
KEYCODE_TV_AUDIO_DESCRIPTION |
音频描述 |
253 |
KEYCODE_TV_AUDIO_DESCRIPTION_MIX_UP |
音频描述混音加 |
254 |
KEYCODE_TV_AUDIO_DESCRIPTION_MIX_DOWN |
音频描述混音减 |
255 |
KEYCODE_TV_ZOOM_MODE |
TV 缩放模式 |
256 |
KEYCODE_TV_CONTENTS_MENU |
TV 内容菜单 |
257 |
KEYCODE_TV_MEDIA_CONTEXT_MENU |
TV 媒体上下文菜单 |
258 |
KEYCODE_TV_TIMER_PROGRAMMING |
TV 定时编程 |
259 |
KEYCODE_HELP |
帮助 |
11. 导航、Wear 与剪贴板按键
| 数值 | KeyEvent 常量 | 说明 |
|---|---|---|
260 |
KEYCODE_NAVIGATE_PREVIOUS |
导航到上一个 |
261 |
KEYCODE_NAVIGATE_NEXT |
导航到下一个 |
262 |
KEYCODE_NAVIGATE_IN |
导航进入 |
263 |
KEYCODE_NAVIGATE_OUT |
导航退出 |
264 |
KEYCODE_STEM_PRIMARY |
主 Stem 键 |
265 |
KEYCODE_STEM_1 |
Stem 1 |
266 |
KEYCODE_STEM_2 |
Stem 2 |
267 |
KEYCODE_STEM_3 |
Stem 3 |
268 |
KEYCODE_DPAD_UP_LEFT |
方向左上 |
269 |
KEYCODE_DPAD_DOWN_LEFT |
方向左下 |
270 |
KEYCODE_DPAD_UP_RIGHT |
方向右上 |
271 |
KEYCODE_DPAD_DOWN_RIGHT |
方向右下 |
272 |
KEYCODE_MEDIA_SKIP_FORWARD |
媒体向前跳过 |
273 |
KEYCODE_MEDIA_SKIP_BACKWARD |
媒体向后跳过 |
274 |
KEYCODE_MEDIA_STEP_FORWARD |
媒体单步向前 |
275 |
KEYCODE_MEDIA_STEP_BACKWARD |
媒体单步向后 |
276 |
KEYCODE_SOFT_SLEEP |
软休眠 |
277 |
KEYCODE_CUT |
剪切 |
278 |
KEYCODE_COPY |
复制 |
279 |
KEYCODE_PASTE |
粘贴 |
这一节里的部分按键更偏硬件厂商、可穿戴设备或系统组件使用,普通手机应用很少直接适配。开发时不要只按数字硬编码,优先使用 KeyEvent.KEYCODE_* 常量,可读性和跨版本维护性都更好。
补充:特殊事件类型 ACTION_MULTIPLE
大多数物理按键会成对发送 ACTION_DOWN 和 ACTION_UP,但部分输入法、扫码枪或外接输入设备可能发送 ACTION_MULTIPLE,一次性携带多个字符。遇到“没有逐个收到字母数字键,但输入框突然出现一整串内容”的情况,可以检查这个分支。
override fun onKeyMultiple(
keyCode: Int,
repeatCount: Int,
event: KeyEvent
): Boolean {
val characters = event.characters
if (!characters.isNullOrEmpty()) {
handleInput(characters)
return true
}
return super.onKeyMultiple(keyCode, repeatCount, event)
}
12. 应用里如何处理按键事件
12.1 Activity 层处理
适合处理当前页面级别的返回、确认、音量、扫码枪回车等事件。需要注意,扫码枪通常会先模拟键盘输入一串字符,最后再发送 KEYCODE_ENTER。如果在 dispatchKeyEvent() 里直接消费回车,但没有读取已经输入的内容,就可能让业务拿不到完整扫码结果。
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
if (event.action == KeyEvent.ACTION_DOWN &&
event.keyCode == KeyEvent.KEYCODE_ENTER
) {
val scanResult = (currentFocus as? EditText)
?.text
?.toString()
.orEmpty()
if (scanResult.isNotBlank()) {
handleBarcode(scanResult)
}
// 默认不消费,继续走 super.dispatchKeyEvent(event),让 EditText 正常处理回车。
// 如果 ENTER 表示“确认提交”且不需要继续传递,可以在这里 return true。
}
return super.dispatchKeyEvent(event)
}
dispatchKeyEvent() 比 onKeyDown() 更靠前,适合统一拦截;onKeyDown() 更适合当前页面没有子控件消费时再兜底处理。
12.2 View 层处理
适合处理局部控件的按键逻辑,例如 TV 焦点控件、输入框快捷键、游戏区域按键。
view.setOnKeyListener { _, keyCode, event ->
if (event.action == KeyEvent.ACTION_DOWN &&
keyCode == KeyEvent.KEYCODE_DPAD_CENTER
) {
// 当前 View 处理确认键
true
} else {
false
}
}
如果返回 true,表示事件已消费,后续父控件和系统默认逻辑一般不会继续处理;如果返回 false,事件会继续向后分发。
13. 如何用 adb 调试按键
13.1 模拟单次按键
adb shell input keyevent KEYCODE_BACK
adb shell input keyevent 4
13.2 模拟长按
adb shell input keyevent --longpress KEYCODE_POWER
13.3 模拟组合输入
input keyevent 本身更适合发送单个 key code。复杂组合键或底层输入事件,需要结合设备能力、输入源和系统权限排查,普通应用自动化场景不建议依赖厂商私有行为。
13.4 实时监听底层输入事件
当不确定实体键、遥控器或外接设备实际发送了什么事件时,可以用 getevent 先观察底层输入:
adb shell getevent -l
输出大致如下:
/dev/input/event1: EV_KEY KEY_VOLUMEUP DOWN
/dev/input/event1: EV_KEY KEY_VOLUMEUP UP
getevent 看到的是 Linux 输入事件和扫描码层面的信息,不一定等同于应用层最终收到的 KeyEvent.KEYCODE_*。它适合用来确认硬件有没有发事件,再结合应用日志反查 Android 层的 keyCode。
14. 排查按键不生效的顺序
遇到“按键码发了,但应用没反应”,建议按这个顺序排查:
- 确认设备当前焦点是否在目标应用窗口。
- 用
adb shell input keyevent <code>验证系统是否能收到模拟输入。 - 在
dispatchKeyEvent()打日志,确认事件有没有进入Activity。 - 检查是否被子 View、输入法、系统导航、媒体会话或厂商 Framework 提前消费。
- 检查是否使用了错误输入源,例如把遥控器方向键当作触摸事件处理。
- 对系统保留键保持预期克制,例如
HOME、POWER、部分音量键不一定能被普通应用拦截。
15. 开发建议
- 业务代码里优先使用
KeyEvent.KEYCODE_BACK这种常量,不要直接写4。 - 只有在自动化脚本、设备协议或日志分析里,才建议直接使用数字按键码。
- 处理遥控器和键盘时,要区分
ACTION_DOWN、ACTION_UP和长按重复事件。 - 处理媒体键时优先考虑
MediaSession,不要只依赖前台页面。 - 适配 TV 或车机时,要把焦点链路当作核心逻辑,而不是只监听方向键。
16. 常见问题
16.1 为什么 KEYCODE_BACK 收不到?
可能原因包括:当前页面没有焦点、系统手势导航优先处理、Dialog 或 Fragment 先消费、使用了 OnBackPressedDispatcher,或者事件被某个 View 的 OnKeyListener 提前消费。
新项目里处理返回键,建议优先使用 AndroidX 的 OnBackPressedDispatcher 或 Compose 的 BackHandler,而不是只重写 onKeyDown()。
16.2 为什么 KEYCODE_HOME 拦截不了?
HOME 是典型系统保留键,普通应用通常不能拦截。Launcher、系统应用、设备管理场景或 kiosk 模式会有更特殊的策略,但不属于普通应用能力范围。
16.3 扫码枪输入应该监听哪个按键?
很多扫码枪会模拟键盘输入:先输入一串字符,最后发送 KEYCODE_ENTER。常见做法是在输入框监听文本变化和回车键,而不是为每个字符单独写按键分支。
17. 总结
Android 按键码的核心不是背数字,而是理解事件从系统到应用的分发路径:
硬件 / adb / 输入设备
-> Android 输入系统
-> Window / Activity
-> View 树
-> 业务处理或系统默认行为
日常开发中,数字按键码适合脚本和日志定位,业务代码则应该使用 KeyEvent.KEYCODE_* 常量。遇到按键不生效时,不要只怀疑按键码本身,更要检查窗口焦点、事件分发顺序、系统保留键和厂商定制行为。
相关推荐
更多推荐



所有评论(0)