android开发中Home键

转载:http://blog.163.com/chuliang_xu/blog/static/2058271582012102125052919/


android4.0之后应用程序无法再获得Home键消息,这样是对滴,但如果想自己写Launcher就得对Home键相关的一些消息进行处理了。

Home消息是在android framwork中处理的,我们找到Home键处理相关的代码 (不想细看的可以直接看最后)
frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java 中的
PhoneWindowManager.java interceptKeyBeforeDispatching 函数中有以下内容

        // First we always handle the home key here, so applications
        // can never break it, although if keyguard is on, we do let
        // it handle it, because that gives us the correct 5 second
        // timeout.
        if (keyCode == KeyEvent.KEYCODE_HOME) {
            // If we have released the home key, and didn't do anything else
            // while it was pressed, then it is time to go home!
            if (mHomePressed && !down) {
                mHomePressed = false;
                if (!canceled) {
                    // If an incoming call is ringing, HOME is totally disabled.
                    // (The user is already on the InCallScreen at this point,
                    // and his ONLY options are to answer or reject the call.)
                    boolean incomingRinging = false;
                    try {
                        ITelephony telephonyService = getTelephonyService();
                        if (telephonyService != null) {
                            incomingRinging = telephonyService.isRinging(); //是否正好有电话打进来
                        }
                    } catch (RemoteException ex) {
                        Log.w(TAG, "RemoteException from getPhoneInterface()", ex);
                    }

                    if (incomingRinging) {
                        Log.i(TAG, "Ignoring HOME; there's a ringing incoming call."); //来电中的时候可以看到 打印个消息就完了
                    } else {
                        launchHomeFromHotKey(); //可以看到这里有launchHome,应该是这里通知了Launcher程序,继续往下看
                    }
                } else {
                    Log.i(TAG, "Ignoring HOME; event canceled.");
                }
                return -1;
            }


            // If a system window has focus, then it doesn't make sense
            // right now to interact with applications.
           //这一段没有看的很明白,不过很明显没有对Home键处理,只是判断了一些情况然后返回了
            WindowManager.LayoutParams attrs = win != null ? win.getAttrs() : null;
            if (attrs != null) {
                final int type = attrs.type;
                if (type == WindowManager.LayoutParams.TYPE_KEYGUARD
                        || type == WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG) {
                    // the "app" is keyguard, so give it the key
                    return 0;
                }
                final int typeCount = WINDOW_TYPES_WHERE_HOME_DOESNT_WORK.length;
                for (int i=0; i<typeCount; i++) {
                    if (type == WINDOW_TYPES_WHERE_HOME_DOESNT_WORK[i]) {
                        // don't do anything, but also don't pass it to the app
                        return -1;
                    }
                }
            }

            if (down) {
                if (repeatCount == 0) {
                    mHomePressed = true;
                } else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
                    if (!keyguardOn) {
                        handleLongPressOnHome(); //作为长按Home键处理
                    }
                }
            }
            return -1;
        }


现在我们再进入 launchHomeFromHotKey(); 函数看看

    /**
     * A home key -> launch home action was detected.  Take the appropriate action
     * given the situation with the keyguard.
     */
    void launchHomeFromHotKey() {
        if (mKeyguardMediator.isShowingAndNotHidden()) {
            // don't launch home if keyguard showing
            //这个keyguard不知道是什么东东,反正它启动了就不响应Home键,系统已经处理了,跟Launcher没关系
        } else if (!mHideLockScreen && mKeyguardMediator.isInputRestricted()) {
            // when in keyguard restricted mode, must first verify unlock
            // before launching home
            mKeyguardMediator.verifyUnlock(new OnKeyguardExitResult() {
                public void onKeyguardExitResult(boolean success) {
                    if (success) {
                        try {
                            ActivityManagerNative.getDefault().stopAppSwitches(); //关闭这个东东
                        } catch (RemoteException e) {
                        }
                        sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY); //关闭这个东东
                        startDockOrHome(); //启动Dock或者Home 很明显这三个函数都很重要 一个一个去看看
                    }
                }
            });
        } else {
            // no keyguard stuff to worry about, just launch home!
            //这里跟上面是一样处理的
            try {
                ActivityManagerNative.getDefault().stopAppSwitches();
            } catch (RemoteException e) {
            }
            sendCloseSystemWindows(SYSTEM_DIALOG_REASON_HOME_KEY);
            startDockOrHome();
        }
    }

进入sendCloseSystemWindows,startDockOrHome两个函数看看

    void sendCloseSystemWindows() {
        sendCloseSystemWindows(mContext, null);
    }

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

    static void sendCloseSystemWindows(Context context, String reason) {
        if (ActivityManagerNative.isSystemReady()) {
            try {
                ActivityManagerNative.getDefault().closeSystemDialogs(reason); //又是调用这个了
            } catch (RemoteException e) {
            }
        }
    }

    void startDockOrHome() {
        Intent dock = createHomeDockIntent();
        if (dock != null) {
            try {
                mContext.startActivity(dock); //启动HomeDock这个Dock好像是自定义的主界面,这里就不管了
                return;
            } catch (ActivityNotFoundException e) {
            }
        }
        mContext.startActivity(mHomeIntent); //启动HomeIntent(其实就是发一个Intent消息到主界面)
    }

我们再看看mHomeIntent是怎么定义的
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);

Launcher中接受Intent的地方在
Launcher2\Launcher2\src\com\android\launcher2\launcher.java
protected void onNewIntent(Intent intent) {}函数中

这里就不分析了,先试试能不能接受到再说。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值