Android 原生截屏方式为,power键和音量下键的组合键,那么想要分析截屏流程就从按键的处理流程开始往下进行分析
1. PhoneWindowManager -- Android按键分发
public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
//音量键按下
if (down) {
// Any activity on the vol down button stops the ringer toggle shortcut
cancelPendingRingerToggleChordAction();
if (interactive && !mScreenshotChordVolumeDownKeyTriggered
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
//该值在后面的判断中会需要
mScreenshotChordVolumeDownKeyTriggered = true;
mScreenshotChordVolumeDownKeyTime = event.getDownTime();
mScreenshotChordVolumeDownKeyConsumed = false;
cancelPendingPowerKeyAction();
interceptScreenshotChord();
interceptAccessibilityShortcutChord();
}
} else {
mScreenshotChordVolumeDownKeyTriggered = false;
cancelPendingScreenshotChordAction();
cancelPendingAccessibilityShortcutAction();
}
}
break;
}
case KeyEvent.KEYCODE_POWER: {
EventLogTags.writeInterceptPower(
KeyEvent.actionToString(event.getAction()),
mPowerKeyHandled ? 1 : 0, mPowerKeyPressCounter);
// Any activity on the power button stops the accessibility shortcut
cancelPendingAccessibilityShortcutAction();
result &= ~ACTION_PASS_TO_USER;
isWakeKey = false; // wake-up will be handled separately
if (down) {
//power键按下事件处理
interceptPowerKeyDown(event, interactive);
} else {
interceptPowerKeyUp(event, interactive, canceled);
}
break;
}
}
在PhoneWindowManager中处理power键的事件及音量下键的事件, 截图时Power键为按下状态,所以去看power键的按下事件处理
private void interceptPowerKeyDown(KeyEvent event, boolean interactive) {
......
//锁屏电源键状态并且检测屏幕截图
if (interactive && !mScreenshotChordPowerKeyTriggered
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) {
//power键按下的标志
mScreenshotChordPowerKeyTriggered = true;
//获取 Power 键的触发时间
mScreenshotChordPowerKeyTime = event.getDownTime();
//处理屏幕截图事件
interceptScreenshotChord();
interceptRingerToggleChord();
}
......
}
private void interceptScreenshotChord() {
/*
mScreenshotChordEnabled 其值为mContext.getResources().getBoolean(com.android.internal.R.bool.config_enableScreenshotChord);
mScreenshotChordVolumeDownKeyTriggered 音量下键按下时值为true
mScreenshotChordPowerKeyTriggered 电源键按下时值为true
mA11yShortcutChordVolumeUpKeyTriggered 音量上键抬起时为false , 按下时为true
*/
if (mScreenshotChordEnabled
&& mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered
&& !mA11yShortcutChordVolumeUpKeyTriggered) {
//获取当前时间
final long now = SystemClock.uptimeMillis();
//当前时间小于 音量下键按下时间 + 150ms
//当前时间小于 power键按下时间 + 150ms
if (now <= mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS
&& now <= mScreenshotChordPowerKeyTime
+ SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) {
mScreenshotChordVolumeDownKeyConsumed = true;
cancelPendingPowerKeyAction();
//使用全屏截图--type
mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);
mScreenshotRunnable.setScreenshotSource(SCREENSHOT_KEY_CHORD);
//执行mScreenshotRunnable
mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay());
}
}
}
继续查看ScreenshotRunnable, 此时会一步步向下调用,最终到SystemUI
private class ScreenshotRunnable implements Runnable {
private int&