Android中Home鍵的監聽和攔截

scott_tiger 7年前發布 | 9K 次閱讀 安卓開發 Android開發 移動開發

首先大家應該先了解一種情況,就是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);

創建一個啟動到桌面的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();
                }
            }
        }
    }

這樣就可以監聽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();
    }
}

//進入handleShortPressOnHome
private 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();
    }

進入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();
            }
        }
    }

以上方法可處理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);
    }

好啦,這里就對Home鍵進行簡單的監聽和攔截。

 

來自:http://blog.csdn.net/dongxianfei/article/details/55049991

 

 本文由用戶 scott_tiger 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!