Android 监听Home键按键事件

标签(空格分隔):Android Home键


在Android开发中有很多按键事件需要在App中捕获从而做出一些针对性的操作,例如返回键,音量键等都可以直接在dispatchKeyEventonKeyDown等回调方法中捕获,但是Home键事件却不能在这个方法中捕获。在Android源码KeyEvent中对于Home键的定义有这样的注释:
This key is handled by the framework and is never delivered to applications.
就是说Home被系统Framework拦截了,并且不会抛出来让App捕获。

但是,很多时候需要在App中捕获Home键的按键事件并作出一些操作。查资料会发现大家都推荐去监听ACTION_CLOSE_SYSTEM_DIALOGS这个系统广播,在按下Home键后系统会发出这个广播,是不是可靠,我们来看下Android framework的源码。

先不管Android怎么从底层一步步把按键事件传递上来,这里直接从Framework中的PhoneWindowManager方法开始分析。

按键事件会在PhoneWindowManager中的interceptKeyBeforeDispatching方法中进行一些预处理,Home键的事件就是在这里被拦截并处理。

public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {    final int keyCode = event.getKeyCode();    final boolean down = event.getAction() == KeyEvent.ACTION_DOWN;    /** 这里省略不知道多少代码 */    if (keyCode == KeyEvent.KEYCODE_HOME) {            /** 这里也省略不知道多少代码 */            handleShortPressOnHome();            return -1;        }

可以看到短按Home键最终是调用handleShortPressOnHome这个方法,那我们来看下这个方法中究竟干了啥?

private void handleShortPressOnHome() {    // Turn on the connected TV and switch HDMI input if we're a HDMI playback device.    getHdmiControl().turnOnTv();    // If there's a dream running then use home to escape the dream    // but don't actually go home.    if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) {        mDreamManagerInternal.stopDream(false /*immediate*/);        return;    }    // Go home!    launchHomeFromHotKey();}

可以看到这里最终调用了launchHomeFromHotKey这个方法。

void launchHomeFromHotKey(final boolean awakenFromDreams, final boolean respectKeyguard) {    if (respectKeyguard) {        if (isKeyguardShowingAndNotOccluded()) {            // don't launch home if keyguard showing            return;        }        if (!mHideLockScreen && mKeyguardDelegate.isInputRestricted()) {            // when in keyguard restricted mode, must first verify unlock            // before launching home            mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() {                @Override                public void onKeyguardExitResult(boolean success) {                    if (success) {                        try {                            ActivityManagerNative.getDefault().stopAppSwitches();                        } catch (RemoteException e) {                        }                        sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);                        startDockOrHome(true /*fromHomeKey*/, awakenFromDreams);                    }                }            });            return;        }    }

可以看到最后调用了sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);这个方法里面就有我们要找的答案。

这个方法的实现如下:

void sendCloseSystemWindows(String reason) {    PhoneWindow.sendCloseSystemWindows(mContext, reason);}

这里调到了PhoneWindow里面的

public static void sendCloseSystemWindows(Context context, String reason) {    if (ActivityManagerNative.isSystemReady()) {        try {            ActivityManagerNative.getDefault().closeSystemDialogs(reason);        } catch (RemoteException e) {        }    }}

这个方法中调用的ActivityManagerNative.getDefault()本质是通过jnibinder调用得到ActivityManagerService的实例,调用ActivityManagerServicecloseSystemDialogs方法,这个方法最终调用ActivityManagerServicecloseSystemDialogsLocked方法:

void closeSystemDialogsLocked(String reason) {    Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY            | Intent.FLAG_RECEIVER_FOREGROUND);    if (reason != null) {        intent.putExtra("reason", reason);    }    mWindowManager.closeSystemDialogs(reason);    mStackSupervisor.closeSystemDialogsLocked();    broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,            AppOpsManager.OP_NONE, null, false, false,            -1, Process.SYSTEM_UID, UserHandle.USER_ALL);}

这里就是答案了,可以看出这里最终通过broadcastIntentLocked发送了ACTION_CLOSE_SYSTEM_DIALOGS广播

至于具体的代码实现可以参考我封装的一个类HomeKeyListener

更多相关文章

  1. android四大组件--ContentProvider详解
  2. 百度地图android sdk拖拽overlay item
  3. Android上的resample处理
  4. handle的用法
  5. Android面试系列文章2018之Android部分AsyncTask机制篇
  6. Handler与异步消息处理
  7. Flutter(Android(安卓)混合开发)
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android中的常用的对话框
  2. Android(安卓)Studio 3.0开始android Dev
  3. android插件汇总
  4. Android修改字体样式
  5. Android(安卓)设置EditText光标Curso颜色
  6. APIDEMO PREFERENCE 学习 ACTIVTIY
  7. 【Android】使用LiveData KTX Builder让
  8. android 包管理系统分析
  9. Android(安卓)获取存储卡路径和空间使用
  10. Android下模拟按键输入