您的位置:首页 > 移动开发 > Android开发

Android4.x Power按键的处理 : KEYCODE_POWER

2013-11-08 14:03 225 查看


转自:http://blog.csdn.net/myarrow/article/details/8143717




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)定义如下:

[cpp] view
plaincopy

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;

}

}

};

它是一个匿名内部类,它是一个实现Runnable的类的对象引用,因此

new Runnable() {

public void run(){

...

}

};

它包括了定义这个类(只不过这个类没有名字)和实例化这个类的对象。

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




3.2 reboot系统调用流程

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




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

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

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

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

[java] view
plaincopy

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;

}

[java] view
plaincopy

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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: