1 Android


 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键处理流程如下图所示:

Android 长按电源键和短按电源键的详细处理流程_java

3. 长按Power键处理流程

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

 

Android 长按电源键和短按电源键的详细处理流程_android_02

3.1 Message超时处理流程

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

[java] 
​​view plain​​​
​​​copy​​​
​​​​​​
​​​​​





1. private final Runnable mPowerLongPress = new Runnable() {
2. public void run() {
3. // The context isn't read
4. if (mLongPressOnPowerBehavior < 0) {
5. mLongPressOnPowerBehavior = mContext.getResources().getInteger(
6. com.android.internal.R.integer.config_longPressOnPowerBehavior);
7. }
8. switch (mLongPressOnPowerBehavior) {
9. case LONG_PRESS_POWER_NOTHING:
10. break;
11. case LONG_PRESS_POWER_GLOBAL_ACTIONS:
12. true;
13. null, HapticFeedbackConstants.LONG_PRESS, false);
14. sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
15. showGlobalActionsDialog();
16. break;
17. case LONG_PRESS_POWER_SHUT_OFF:
18. true;
19. null, HapticFeedbackConstants.LONG_PRESS, false);
20. sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);
21. true);
22. break;
23. }
24. }
25. };


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

 

new Runnable() {
public void run(){
...
}
};

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

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

Android 长按电源键和短按电源键的详细处理流程_java_03


     

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

Android 长按电源键和短按电源键的详细处理流程_java_04

 

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

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

    

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


[java]    ​​view plain​​​   ​​copy​​​   ​​​​​   ​​​​    


1. case KeyEvent.KEYCODE_POWER: {
2. result &= ~ACTION_PASS_TO_USER;
3. if (down) {
4. if (isScreenOn && !mPowerKeyTriggered
5. 0) {
6. true;
7. mPowerKeyTime = event.getDownTime();
8. interceptScreenshotChord();
9. }
10.
11. ...
12. // Power Key down, set mPowerLongPress executing after 500ms
13. interceptPowerKeyDown(!isScreenOn || hungUp
14. || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered);
15. else {
16. false;
17. cancelPendingScreenshotChordAction();
18. if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
19. result = (result & ~ACTION_POKE_USER_ACTIVITY) | ACTION_GO_TO_SLEEP;
20. }
21. // Power key up, remove the mPowerLongPress, that is, if user release
22. // power key during 500ms, mPowerLongPress will not be execute, then execute sleep
23. false;
24. }
25. break;
26. }

[java] ​​view plain​​​ ​​copy​​​ ​​​​​ ​​​​


1. private void interceptPowerKeyDown(boolean handled) {
2. mPowerKeyHandled = handled;
3. if (!handled) {
4. /*500ms*/);
5. }
6. }
7.
8. private boolean interceptPowerKeyUp(boolean canceled) {
9. if (!mPowerKeyHandled) {
10. mHandler.removeCallbacks(mPowerLongPress);
11. return !canceled;
12. }
13. return false;
14. }