前言
最近项目中遇到一个问题,在客户的launcher上按下 menu
键之后按上下左右键都没有响应,虽然最后通过修改文件 PhoneWindow.java
解决了问题,但是感觉对TV按键事件的分发流程还不是很明白,这里就带着问题来跟踪源码去探索TV 按键事件在 Framework 到底是怎么传递下来的。本篇博客分析的源码是Amlogic平台 Android 5.1 的代码,其它高版本也是适用的。
本篇博客分为以下几个部分:
1、此次项目中menu按键问题的分析定位
2、TV按键事件的分发流程
第一部分主要是这个问题的分析,对此部分不感兴趣的同学可以看直接第二部分。
一、Menu按键问题分析
这个问题是在客户的launcher上按下 menu
键之后按上下左右键都没有响应,只有再按一下 Back
键或者 Menu
键才能恢复正常。我截取了部分log如下
D/WindowManager( 4169): interceptKeyTq keycode=82 interactive=true keyguardActive=false policyFlags=22000000
D/WindowManager( 4169): interceptKeyTi keyCode=82 down=true repeatCount=0 keyguardOn=false mHomePressed=false canceled=false
V/PinyinIME( 4709): onKeyDown:82
I/PinyinIME( 4709): onKeyDown:System handler the keyevent
D/WindowManager( 4169): interceptKeyTq keycode=82 interactive=true keyguardActive=false policyFlags=22000000
D/WindowManager( 4169): interceptKeyTi keyCode=82 down=false repeatCount=0 keyguardOn=false mHomePressed=false canceled=false
I/PinyinIME( 4709): onKeyUp:82
I/PinyinIME( 4709): onKeyUp:System handler the keyevent
--------- beginning of system
V/WindowManager( 4169): Adding window Window{
33b8842d u0 AtchDlg:com.unitedview.phenix.launcher/com.unitedview.phenix.launcher.activity.LauncherActivity} at 2 of 4 (after Window{
371c5e78 u0 com.unitedview.phenix.launcher/com.unitedview.phenix.launcher.activity.LauncherActivity})
D/WindowManager( 4169): interceptKeyTq keycode=22 interactive=true keyguardActive=false policyFlags=22000000
D/WindowManager( 4169): interceptKeyTi keyCode=22 down=true repeatCount=0 keyguardOn=false mHomePressed=false canceled=false
D/WindowManager( 4169): Unhandled key: win=Window{
33b8842d u0 AtchDlg:com.unitedview.phenix.launcher/com.unitedview.phenix.launcher.activity.LauncherActivity}, action=0, flags=8, keyCode=22, scanCode=106, metaState=0, repeatCount=0, policyFlags=1644167168
D/WindowManager( 4169): No fallback.
D/WindowManager( 4169): interceptKeyTq keycode=22 interactive=true keyguardActive=false policyFlags=22000000
D/WindowManager( 4169): interceptKeyTi keyCode=22 down=false repeatCount=0 keyguardOn=false mHomePressed=false canceled=false
D/WindowManager( 4169): Unhandled key: win=Window{
33b8842d u0 AtchDlg:com.unitedview.phenix.launcher/com.unitedview.phenix.launcher.activity.LauncherActivity}, action=1, flags=8, keyCode=22, scanCode=106, metaState=0, repeatCount=0, policyFlags=1644167168
D/WindowManager( 4169): No fallback.
D/WindowManager( 4169): interceptKeyTq keycode=21 interactive=true keyguardActive=false policyFlags=22000000
D/WindowManager( 4169): interceptKeyTi keyCode=21 down=true repeatCount=0 keyguardOn=false mHomePressed=false canceled=false
D/WindowManager( 4169): Unhandled key: win=Window{
33b8842d u0 AtchDlg:com.unitedview.phenix.launcher/com.unitedview.phenix.launcher.activity.LauncherActivity}, action=0, flags=8, keyCode=21, scanCode=105, metaState=0, repeatCount=0, policyFlags=1644167168
D/WindowManager( 4169): No fallback.
通过这个log看,貌似是按下 Menu
键后,添加了一个新的window,但是在这个window上没有响应按键事件,导致按上下左右键没有作用。我怀疑是这个第三方的launcher添加了一个类似于menu菜单的东西,因为我在其他应用的界面按 Menu
键不会出现这种情况。为了验证我的猜想。我自己写了一个app,按键弹出menu菜单。代码如下:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
//创建菜单项的点击事件
switch (item.getItemId()) {
case R.id.mune_enter:
Toast.makeText(this, "点击了登陆", Toast.LENGTH_SHORT).show();
break;
case R.id.mune_setting:
Toast.makeText(this, "点击了设置", Toast.LENGTH_SHORT).show();
break;
case R.id.mune_out:
Toast.makeText(this, "点击了退出", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {