[置顶] Android4.x对长按电源键(挂断键)和短按电源键(挂断键)的详细处理流程
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;
- }
- }
- };
它是一个匿名内部类,它是一个实现Runnable的类的对象引用,因此
new Runnable() {
public void run(){
...
}
};
它包括了定义这个类(只不过这个类没有名字)和实例化这个类的对象。
当超时时,其执行流程如下图所示:

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;
- }
[置顶] Android4.x对长按电源键(挂断键)和短按电源键(挂断键)的详细处理流程的更多相关文章
- [置顶] Android4.0中修改挂断键(ENDCALL)的默认行为
文件: frameworks/base/core/java/android/provider/Setings.java public static final String END_BUTTON_BE ...
- [置顶] 与小伙伴共勉的java有关jvm的知识(一),小鸟尽量写得详细哦,欢迎讨论,谢绝喷子
JAVA运行在JVM之上,JVM的运行状况会对程序产生很大的影响,因此了解一些JVM的东东,对于编写稳定的,高性能的java程序至关重要.这是JVM的规范中定义的标准结构图: 以上标准是JVM标准中定 ...
- [置顶] IIS应用程序池多工作进程设置及Session共享
[置顶] IIS应用程序池多工作进程设置及Session共享 在调优iis的时候,朋友分享给我一个特别棒的设置方法步骤,感谢好朋友的分享. IIS应用程序池多工作进程设置及Session共享 1 ...
- RecyclerView实现侧滑删除、置顶、滑动
1.首先在build.gradle里添加 compile 'com.github.mcxtzhang:SwipeDelMenuLayout:V1.2.1' 2.设置recyclerView的item布 ...
- 在UWP中页面滑动导航栏置顶
最近在研究掌上英雄联盟,主要是用来给自己看新闻,顺便copy个界面改一下段位装装逼,可是在我copy的时候发现这个东西 当你滑动到一定距离的时候导航栏会置顶不动,这个特性在微博和淘宝都有,我看了@ms ...
- WinFrom窗体始终置顶
调用WindowsAPI使窗体始终保持置顶效果,不被其他窗体遮盖: [DllImport("user32.dll", CharSet = CharSet.Auto)] privat ...
- winform窗体置顶
winform窗体置顶 金刚 winform 置顶 今天做了一个winform小工具.需要设置置顶功能. 网上找了下,发现百度真的很垃圾... 还是必应靠谱些. 找到一个可以链接. https://s ...
- 自定义置顶TOP按钮
简述一下,分为三个步骤: 1. 添加Html代码 2. 调整Css样式 3. 添加Jquery代码 具体代码如下: <style type="text/css"> #G ...
- ahk之路:利用ahk在window7下实现窗口置顶
操作系统:win7 64位 ahk版本:autohotkey_L1.1.24.03 今天安装了AutoHotkey_1.1.24.03.SciTE.PuloversMacroCreator,重新开始我 ...
随机推荐
- 菜农群课笔记之ICP与ISP----20110412(整理版)
耗时一上午时间对HOT大叔昨晚的群课内容进行温故并整理,现将其上传,若想看直播可到下面链接处下载:http://bbs.21ic.com/icview-229746-1-1.html 成 ...
- java面试题系列11
华为的JAVA面试题 QUESTION NO: 1 publicclass Test1 { publicstaticvoid changeStr(String str){ ...
- 自制的七个C,总结的太好了
拿破仑·希尔把它叫做:“自制的七个C”: 1.控制自己的时间(Clock). 时间虽不断流逝,但也可以任人支配.你可以选择时间来工作.游戏.休息.烦恼..虽然客观的环境不一定能任人掌握,但人却可以自己 ...
- csv批量导入mysql命令
今天把从Kaggle上下载下来的csv数据导入mysql,想做个统计分析,怎奈csv文件有些大.所以仅仅能用mysql 命令导入,现mark下,以备以后不时之需: 1. 导入: 基本的语法: load ...
- liquibase之快速入门
第一步: 创建一个Changelog File: 这个database Changelog file列举了数据库中所有的改变情况,该文件是以xml为基础的,下面是一个空的xml文件: <?xm ...
- 使用AJAX日历控件,显示某些日期(CalendarExtender)
1. The HTML Markup <div> <ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1&q ...
- 使用LiveWriter发布Orchard博客
我们可以Windows Live Writer来发布Orchard博客 在Dashboard–> Modules菜单找到 Remote Blog Publishing 模块.点击 Enable ...
- SQL中distinct的用法(转)
原文:http://www.cnblogs.com/rainman/archive/2013/05/03/3058451.html 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出 ...
- Dojo实现Tabs页报错(三)
用Dojo实现tab页的过程中,没有引用“on.js”,但是firebug调试时一直提示如下错误: on.js源码如下: define(["./has!dom-addeventlistene ...
- ASP.NET 定时通知
ASP.NET 定时通知 using System; using System.Collections.Generic; using System.Linq; using System.Web; us ...