`
coolerbaosi
  • 浏览: 725014 次
文章分类
社区版块
存档分类
最新评论

Android4.x 如何处理Power按键

 
阅读更多

1. 简介

Android4.x在Framework的PhoneWindowManager对Power(KeyEvent.KEYCODE_POWER)和Home(KeyEvent.KEYCODE_HOME)键做了处理,不会把这些键传送上层应用程序。如需要把这些键发送给Activity和Service,需要在PhoneWindowManager处理这些键时“发送一个广播出去,然后在应用程序接收到广播后做处理”。

如果应用程序只需要获取获取待机、唤醒、关机、网络状态变化消息,则可监听以下广播消息:
1) 待机:
广播消息:android.intent.action.SCREEN_OFF (代码)
2) 唤醒:
广播消息:android.intent.action.SCREEN_ON (代码)
3) 关机:
广播消息:android.intent.action.ACTION_SHUTDOWN (XML或代码)
4) 网络状态变化:
广播消息:android.net.conn.CONNECTIVITY_CHANGE (XML或代码)
然后调用下面的isNetworkAvailable获取当前网络状态。
public static boolean isNetworkAvailable(Context context) {

ConnectivityManager mgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] info = mgr.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
return false;
}

2. 短按Power键处理流程

短按Power键处理流程如下图所示:

3. 长按Power键处理流程

长按Power键处理流程如下图所示:

3.1 Message超时处理流程

如果长按Power键(超过500ms),则此消息(Message.callback为mPowerLongPress)将被执行。mPowerLongPress (PhoneWindowManager.java)定义如下:

    private final Runnable mPowerLongPress = new Runnable() {
        public void run() {
            // The context isn't read
            if (mLongPressOnPowerBehavior < 0) {
                mLongPressOnPowerBehavior = mContext.getResources().getInteger(
                        com.android.internal.R.integer.config_longPressOnPowerBehavior);
            }
            switch (mLongPressOnPowerBehavior) {
            case LONG_PRESS_POWER_NOTHING:
                break;
            case LONG_PRESS_POWER_GLOBAL_ACTIONS:
                mPowerKeyHandled = true;
                performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
                showGlobalActionsDialog();
                break;
            case LONG_PRESS_POWER_SHUT_OFF:
                mPowerKeyHandled = true;
                performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);
                sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
                ShutdownThread.shutdown(mContext, true);
                break;
            }
        }
    };

当超时时,其执行流程如下图所示:

3.2 reboot系统调用流程

reboot系统调用流程如下图所示:

4. 如何处理短按和长按电源键

长按电源键:弹出关机确认对话框(KeyDown之后,如果 500ms之内,没有收到KeyUp则弹出关机确认对话框)

短按电源键:执行待机(KeyUp时执行<wmActions=4>)或唤醒(KeyDown时执行<wmActions=2>)

对于长按电源键,在PhoneWindowManager.java的interceptKeyBeforeQueueing函数中进行处理,其相关代码如下:

            case KeyEvent.KEYCODE_POWER: {
                result &= ~ACTION_PASS_TO_USER;
                if (down) {
                    if (isScreenOn && !mPowerKeyTriggered
                            && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                        mPowerKeyTriggered = true;
                        mPowerKeyTime = event.getDownTime();
                        interceptScreenshotChord();
                    }
                   
                    ...
                    // Power Key down, set mPowerLongPress executing after 500ms
                    interceptPowerKeyDown(!isScreenOn || hungUp
                            || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered);
                } else {
                    mPowerKeyTriggered = false;
                    cancelPendingScreenshotChordAction();
                    if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
                        result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
                    }
                    // Power key up, remove the mPowerLongPress, that is, if user release
                    // power key during 500ms, mPowerLongPress will not be execute, then execute sleep
                    mPendingPowerKeyUpCanceled = false;
                }
                break;
            }

    private void interceptPowerKeyDown(boolean handled) {
        mPowerKeyHandled = handled;
        if (!handled) {
            mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout()/*500ms*/);
        }
    }

    private boolean interceptPowerKeyUp(boolean canceled) {
        if (!mPowerKeyHandled) {
            mHandler.removeCallbacks(mPowerLongPress);
            return !canceled;
        }
        return false;
    }


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics