Power长按、组合键分析

原创 2016年02月29日 18:43:48

1.Power长按功能原理

 当按下power时

                    Log.i(TAG, "PowerKey down, isScreenOn = " + isScreenOn);
                    interceptPowerKeyDown(!isScreenOn || hungUp
                            || mVolumeDownKeyTriggered || mVolumeUpKeyTriggered);
    private void interceptPowerKeyDown(boolean handled) {
        mPowerKeyHandled = handled;
        if (!handled || mChangeLongPressPowerKey) {
            if(mChangeLongPressPowerKey) {
                Log.d(TAG,"fast boot acquire cpu wakelock for timeout :"+(ViewConfiguration.getGlobalActionKeyTimeout()+100));
                PowerManager.WakeLock fastBootWake = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "FastBootWake");
                fastBootWake.acquire(ViewConfiguration.getGlobalActionKeyTimeout()+100);
             }
            mHandler.postDelayed(mPowerLongPress, ViewConfiguration.getGlobalActionKeyTimeout());
        }
    }

抬起手时
                    Log.i(TAG, "PowerKey up");
                    mPowerKeyTriggered = false;
                    cancelPendingScreenshotChordAction();
                    if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) {
                        result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP;
                    }
                    mPendingPowerKeyUpCanceled = false;
    private boolean interceptPowerKeyUp(boolean canceled) {
        if (!mPowerKeyHandled) {
            mHandler.removeCallbacks(mPowerLongPress);
            return !canceled;
        }
        if (mChangeLongPressPowerKey) {
            mHandler.removeCallbacks(mPowerLongPress);
        }
        return false;
    }

根据以上代码分析知,在亮屏、音量键没触发、power键没进行挂电话行为时,按下power会进入mPowerLongPress启动的倒计时,当抬起手时会判断power键的事件是否被消耗,如果没被消耗则移除mPowerLongPress事件,并返回传进来的boolean的相反值。

mPendingPowerKeyUpCanceled的值控制如下

    private void cancelPendingPowerKeyAction() {
        if (!mPowerKeyHandled) {
            mHandler.removeCallbacks(mPowerLongPress);
        }
        if (mPowerKeyTriggered) {
            mPendingPowerKeyUpCanceled = true;
        }
    }

总结来说:要想实现长按,需要1.一个boolean值用于判断按下的事件是否消费,如mPowerKeyHandled。2.handler延迟执行长按的事件,并且在长按事件的执行代码中把事件boolean设置为消费状态。3.up事件中判断这次按下事件是否被消耗,如果没则处理单点流程。

长按实现:记录下第一次按下的时间,记录此次事件是否被消费,在down事件中判断是否达到了长按时间,在up事件中把事件归零并判断事件是否消费并重置。

2.组合键原理

长按power+音量下可以截图,以此为例分析

在power键的down事件中有如下代码

                    if (isScreenOn && !mPowerKeyTriggered
                            && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                        mPowerKeyTriggered = true;
                        mPowerKeyTime = event.getDownTime();
                        interceptScreenshotChord();
                    }

    private void interceptScreenshotChord() {
        if (mScreenshotChordEnabled
                && mVolumeDownKeyTriggered && mPowerKeyTriggered && !mVolumeUpKeyTriggered) {
            final long now = SystemClock.uptimeMillis();
            if (now <= mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
                    && now <= mPowerKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
                mVolumeDownKeyConsumedByScreenshotChord = true;
                cancelPendingPowerKeyAction();

                mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay());
            }
        }
    }

音量-按键down事件
                        if (isScreenOn && !mVolumeDownKeyTriggered
                                && (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
                            mVolumeDownKeyTriggered = true;
                            mVolumeDownKeyTime = event.getDownTime();
                            mVolumeDownKeyConsumedByScreenshotChord = false;
                            cancelPendingPowerKeyAction();
                            interceptScreenshotChord();
                        }
根据以上代码可以分析出;power键按下时记下按下的时间并且mPowerKeyTriggered设为true,音量键同样如此,两个都调用了interceptScreenshotChord()方法,也就是说先按下哪个键不影响。在interceptScreenshotChord()方法中,如果power被触发、音量down被触发,音量up没被触发则继续判断两个按键按下的间隔是否在一定时间内,如果是则开始进入截屏流程,并把mVolumeDownKeyConsumedByScreenshotChord设为true,mVolumeDownKeyConsumedByScreenshotChord值用于阻止音量按键事件往下传递用,在interceptKeyBeforeDispatching方法内
        if (mScreenshotChordEnabled && (flags & KeyEvent.FLAG_FALLBACK) == 0) {
            if (mVolumeDownKeyTriggered && !mPowerKeyTriggered) {
                final long now = SystemClock.uptimeMillis();
                final long timeoutTime = mVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS;
                if (now < timeoutTime) {
                    return timeoutTime - now;
                }
            }
            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
                    && mVolumeDownKeyConsumedByScreenshotChord) {
                if (!down) {
                    mVolumeDownKeyConsumedByScreenshotChord = false;
                }
                return -1;
            }
        }
可以看出,如果先按的是音量-键,那么在一定时间内事件是没有被传递下去,当抬手时则mVolumeDownKeyConsumedByScreenshotChord=true.不过mVolumeDownKeyConsumedByScreenshotChord好像没什么用。

总结:要想实现组合键,1、记录两个按键的按下时间。2、记录两个按键是否按下触发。3、每个按键按下时触发同一个方法并在此方法内判读两个按键按下的时间差是否在一定时间内,如果是则组合按键生效。

注意:power按键之所以在组合按键起效时不响应点击或者长按事件,因为处理时判断了音量键是否按下去了,如果按下了则不起效。而如果power键先按,则在音量键按下时调用了mVolumeDownKeyConsumedByScreenshotChord

    private void cancelPendingPowerKeyAction() {
        if (!mPowerKeyHandled) {
            mHandler.removeCallbacks(mPowerLongPress);
        }
        if (mPowerKeyTriggered) {
            mPendingPowerKeyUpCanceled = true;
        }
    }
mPendingPowerKeyUpCanceled的用途是阻止power松开时灭屏


android6.0 power按键深入分析

这篇博客主要分析power按键点亮屏幕和灭屏,而且我们主要分析在PhoneWIndowManager的流程。 之前的博客我们分析过按键的流程,当有按键会先到PhoneWindowManager的int...
  • kc58236582
  • kc58236582
  • 2016年06月02日 20:28
  • 6923

Android 5.1 长按power键流程分析

安全模式简述 android平台,在长按power / menu键时会快速进入一个模式选择,部分定制的平台是直接进入安装模式,也可以定制成公司需要的一些特定功能模式,比如报警 ...  power 也...
  • kehyuanyu
  • kehyuanyu
  • 2015年06月30日 22:08
  • 4241

MTK8127_FB710项目调试长按power键重启改动

客户有需求需要长按power键进行重启  调试过程:           1.现在版本机器上实现的长按power键进入强制关机,继续长按无法重启           2.由于硬件上存在强制关机电...
  • w72139
  • w72139
  • 2014年11月04日 10:09
  • 1269

Android 5.1 截屏事件分析(Power + VolumeDown)组合键分析

为了实现组合键启动app的功能,参考了Android中截屏事件的处理流程,实现同时按下Power+音量增键启动电阻屏校准App的功能,下面是Android 代码中关于截屏按键部分的处理代码简要分析: ...
  • lizuobin2
  • lizuobin2
  • 2017年07月24日 17:22
  • 487

捕捉Power键的长按与短按处理

1. PhoneWindowManager.java中监听KeyEvent.KEYCODE_POWER事件(代码:mKeyguardMediator.onWakeKeyWhenKeyguardShow...
  • hjj0212
  • hjj0212
  • 2013年01月23日 11:18
  • 7474

android5.1添加android长按power键重启功能

当用户长按power键的时候,系统会在PhoneWindowManager中调用  mGlobalActions.showDialog,来显示关机、飞行、重启等界面选项。 而我们需要在Global...
  • kc58236582
  • kc58236582
  • 2015年05月20日 09:26
  • 3333

Android4.2 长按POWER键休眠

A你平板或手机上, 长按POWER键, 一般会弹出关机选择界面, 提示关机或切换模式...
  • qilu0882
  • qilu0882
  • 2014年11月17日 13:38
  • 768

长按power键弹出关机菜单,点击关机会弹出提示框,点击重启没有提示框确认直接进入重启状态,添加确认提示框

--- a/idh.code/frameworks/base/core/res/res/values-es/strings.xml +++ b/idh.code/frameworks/base/cor...
  • silence_cdsn
  • silence_cdsn
  • 2015年01月07日 10:15
  • 1438

android5.1添加android长按power键重启功能

当用户长按power键的时候,系统会在PhoneWindowManager中调用  mGlobalActions.showDialog,来显示关机、飞行、重启等界面选项。 而我们需要在Glo...
  • q1183345443
  • q1183345443
  • 2016年11月30日 17:01
  • 373

安卓源代码修改之framework下面长按power键,修改安卓原生的关机、重启界面,并让界面背景变成模糊(三)

界面模糊背景
  • sinat_33338482
  • sinat_33338482
  • 2016年04月12日 10:31
  • 506
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Power长按、组合键分析
举报原因:
原因补充:

(最多只允许输入30个字)