首先大家应该先了解一种情况,就是Android在应用中是无法拦截Home键的,今天我们带大家看一下Home键的三种情况。


1、在应用中按下Home键的逻辑处理

当我们在应用中按下Home键时界面会启动到桌面,我们在frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.Java类中可以看到其实现原理,其不外乎就是调用了以下代码。

    Intent mHomeIntent;    mHomeIntent = new Intent(Intent.ACTION_MAIN, null);    mHomeIntent.addCategory(Intent.CATEGORY_HOME);    mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);    startActivity(mHomeIntent);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

创建一个启动到桌面的Intent。

2、在应用中监听Home键

在Android应用中如果想监听Home键可以使用广播机制,这个在源码中也有体现。

static public final String SYSTEM_DIALOG_REASON_KEY = "reason";    static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";    static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";    static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";    static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";    @Override    public void onReceive(Context arg0, Intent arg1) {        String action = arg1.getAction();        //按下Home键会发送ACTION_CLOSE_SYSTEM_DIALOGS的广播        if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {            String reason = arg1.getStringExtra(SYSTEM_DIALOG_REASON_KEY);            if (reason != null) {                if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {                    // 短按home键                    Toast.makeText(arg0, "短按Home键", Toast.LENGTH_SHORT).show();                } else if (reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {                    // RECENT_APPS键                    Toast.makeText(arg0, "RECENT_APPS", Toast.LENGTH_SHORT).show();                }            }        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

这样就可以监听Home的是否被按下。

3、在Frameworks层拦截Home键

在frameworks\base\policy\src\com\android\internal\policy\impl\PhoneWindowManager.java文件中我们首先看一下interceptKeyBeforeDispatching()方法。

public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {    //......    if (keyCode == KeyEvent.KEYCODE_HOME) {        //......        handleShortPressOnHome();    }}//进入handleShortPressOnHomeprivate void handleShortPressOnHome() {        // 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();    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

进入launchHomeFromHotKey方法。

static public final String SYSTEM_DIALOG_REASON_KEY = "reason";    static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";    static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";    static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";    static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";void launchHomeFromHotKey() {        if (isKeyguardShowingAndNotOccluded()) {            // don't launch home if keyguard showing        } else 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();                    }                }            });        } else {            // no keyguard stuff to worry about, just launch home!            try {                ActivityManagerNative.getDefault().stopAppSwitches();            } catch (RemoteException e) {            }            if (mRecentsVisible) {                // Hide Recents and notify it to launch Home                awakenDreams();                sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);                hideRecentApps(false, true);            } else {                // Otherwise, just launch Home                sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);                //启动Launcher界面                startDockOrHome();            }        }    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

以上方法可处理Home键的拦截操作,接下来我们进入startDockOrHome方法。

void startDockOrHome() {        if (OptConfig.LC_RAM_SUPPORT) {            try {                ActivityManagerNative.getDefault().startHomePre();            } catch (RemoteException re) {            }        }        awakenDreams();        Intent dock = createHomeDockIntent();        if (dock != null) {            try {                startActivityAsUser(dock, UserHandle.CURRENT);                return;            } catch (ActivityNotFoundException e) {            }        }        //intent的相关设置        mHomeIntent =  new Intent(Intent.ACTION_MAIN, null);        mHomeIntent.addCategory(Intent.CATEGORY_HOME);        mHomeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK                | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);        startActivityAsUser(mHomeIntent, UserHandle.CURRENT);    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

好啦,这里就对Home键进行简单的监听和拦截。

更多相关文章

  1. Android ListView 滚动的N种方法
  2. Android解决输入法自动弹出方法大全
  3. Android 微信分享操作后 在当前界面提示方案 解决
  4. Android 从硬件到应用:一步一步向上爬 4 -- 使用 JNI 方法调硬件
  5. Android启动界面优化技巧-Splash Screens的正确方式
  6. Android实现界面刷新
  7. Android高手进阶教程(十一)之----Android 通用获取Ip的方法(判断

随机推荐

  1. [SQL Server] 数据库日志文件自动增长导
  2. 通过SQL语句访问远程数据库
  3. linux使用freetds 连接连远程服务器sqlse
  4. Statement及PreparedStatement执行多个sq
  5. win10+java+mysql+tomcat+jpress环境搭建
  6. SQLite格式编号始终为2位小数
  7. windows下搭建Apache+Mysql+PHP开发环境
  8. 线程往数据库里插数据时偶尔会报错
  9. OSX下完全删除MySQL和怎样使MySQL支持中
  10. ORACLE 01843. 00000 - “不是有效月份