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

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

 

3. 长按Power键处理流程

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

 

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.             mPowerKeyHandled = true;    
  13.             performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);    
  14.             sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);    
  15.             showGlobalActionsDialog();    
  16.             break;    
  17.         case LONG_PRESS_POWER_SHUT_OFF:    
  18.             mPowerKeyHandled = true;    
  19.             performHapticFeedbackLw(null, HapticFeedbackConstants.LONG_PRESS, false);    
  20.             sendCloseSystemWindows(SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS);    
  21.             ShutdownThread.shutdown(mContext, true);    
  22.             break;    
  23.         }    
  24.     }    
  25. };    

它是一个匿名内部类,它是一个实现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
plain
copy

  1. case KeyEvent.KEYCODE_POWER: {    
  2.     result &= ~ACTION_PASS_TO_USER;    
  3.     if (down) {    
  4.         if (isScreenOn && !mPowerKeyTriggered    
  5.                 && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {    
  6.             mPowerKeyTriggered = 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.         mPowerKeyTriggered = 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.         mPendingPowerKeyUpCanceled = false;    
  24.     }    
  25.     break;    
  26. }    

[java] view
plain
copy

  1. private void interceptPowerKeyDown(boolean handled) {    
  2.     mPowerKeyHandled = handled;    
  3.     if (!handled) {    
  4.         mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout()/*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. }    
时间: 2024-10-31 21:18:48

Android 长按电源键和短按电源键的详细处理流程的相关文章

Android4.x对长按电源键(挂断键)和短按电源键(挂断键)的详细处理流程

1. 简介         Android4.x在Framework的PhoneWindowManager对Power(KeyEvent.KEYCODE_POWER)和Home(KeyEvent.KEYCODE_HOME)键做了处理,不会把这些键传送上层应用程序.如需要把这些键发送给Activity和Service,需要在PhoneWindowManager处理这些键时"发送一个广播出去,然后在应用程序接收到广播后做处理".        如果应用程序只需要获取获取待机.唤醒.关机.网

Android 长按电源键关机整个流程小学习

Android 长按电源键关机整个流程小学习              最近研究了一下android关机跟重新启动功能,看了一些长按电源键到弹出关机对话框,到真正关机的一系列处理过程. 首先还是来看看这个长按电源键都干了些什么吧?一般来说,电源键都是接到PMU上的,PMU来判断是长按还短按,当有按键消息产生的时候,系统会有中断,然后去读PMU的状态就可以知道是什么了.笔者以全志平台的AXP209小议一下,先贴上关键代码: static int axp_battery_event(struct n

Amazon正在以己之长,攻人之短

摘要: 作者Michael Mace 是苹果和Palm前高管,有着 10 年的苹果工作经验,曾负责全球客户竞争分析. 一直以来,我对 Amazon Fire Phone 都难下定论.乏味是我的第一反应,但我将来还是会好奇满满 作者Michael Mace 是苹果和Palm前高管,有着 10 年的苹果工作经验,曾负责全球客户&竞争分析. 一直以来,我对 Amazon Fire Phone 都难下定论."乏味"是我的第一反应,但我将来还是会好奇满满地试用看看,或许对它能有更好的感受

android 长时间运行导致程序奔溃

问题描述 android 长时间运行导致程序奔溃 偶发性bug,不知道哪里引起的错误,程序太大没办法贴出代码,请大神帮忙看看是哪里出错了可以给个提示.没调过这方面的bug,请大神教教方法 谢谢了 06-02 13:56:25.920: A/libc(15969): Fatal signal 6 (SIGABRT) at 0x00003e61 (code=-6), thread 15969 (.clov4r.ad.nil1) 06-02 13:56:26.030: I/DEBUG(107): **

为了更有效率地偷钱,Android root木马开始试水短信扣费诈骗

本文讲的是为了更有效率地偷钱,Android root木马开始试水短信扣费诈骗, 自2006年9月以来,我们就一直在监控Google Play商店有关Ztorg木马的各种新变异版本 ,到目前为止,我们已经发现了几十个新的Ztorg木马的变异程序.所有这些都是恶意程序无一例外都是利用漏洞在受感染的设备上获得root权限. 不过,在2017年5月下旬以来,在我们捕获的Ztorg木马的变异程序中,却发现它们都没有使用设备的root权限.通过对Google Play上的两个恶意应用程序进行研究发现,它们

android下java可以接收普通短信吗?

问题描述 android下java可以接收普通短信吗?不会象J2ME一样要端口号吧? 解决方案 解决方案二:可以接收,不需要端口号,使用SmsManager即可完成

Android 界面下面三个按钮三角形(返回键)/圆形(home键)/方形的控件信息如何获取?

问题描述 Android 界面下面三个按钮三角形(返回键)/圆形(home键)/方形的控件信息如何获取? 求教,如题! 用uiautomator不能, appium inspector也是一样 ,谢谢! 解决方案 你想问的是不是BACK,HOME,MENU呀? 解决方案二: @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return super.onKeyDown(keyCode, event); } 解决方案

浅析Android手机卫士之手机实现短信指令获取位置_Android

推荐阅读: 浅析Android手机卫士sim卡绑定 深入浅析Android手机卫士保存密码时进行md5加密 详解Android 手机卫士设置向导页面 浅析Android手机卫士关闭自动更新 浅析Android手机卫士自定义控件的属性 浅析Android手机卫士读取联系人 浅析Android手机卫士接收短信指令执行相应操作 浅析Android手机卫士手机定位的原理 获取位置 新建一个service的包 新建一个GPSService类继承系统的Service类 清单文件中注册一下 重写onCreat

Android实现双模(CDMA/GSM)手机短信监听的方法_Android

本文实例讲述了Android实现双模(CDMA/GSM)手机短信监听的方法.分享给大家供大家参考,具体如下: 一.问题分析: 最近在做一个通过短信远程启动应用的功能,要用到短信监听,代码如下: import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telepho