截屏功能是大家经常用到的一项功能,使用截屏功能能便捷且快速地把手机当前屏幕显示的信息以图片的形式存储到手机中。
截屏操作一般有两种途径:
- 下拉手机屏幕上方状态栏点击快捷功能面板中的截屏(部分手机品牌中支持此功能)。
- 同时按住手机侧方的电源键+音量减键来实现截屏。
这两种截屏的方式其根本原理是一样的,实现的流程都是一样的,不同的是触发方式。
一、截屏
a. 电源键+音量键截屏
Android 系统中对各类物理与虚拟按键的处理都是在 Framework 层中的 PhoneWindowManager.java 内实现。
- 对电源键的监听处理
/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java @Override public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { … case KeyEvent.KEYCODE_POWER: {//匹配电源键 // 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) {//当电源键被按下状态时 interceptPowerKeyDown(event, interactive); } else { interceptPowerKeyUp(event, interactive, canceled); } break; } … } private void interceptPowerKeyDown(KeyEvent event, boolean interactive) { .... // Latch power key state to detect screenshot chord. if (interactive && !mScreenshotChordPowerKeyTriggered && (event.getFlags() &KeyEvent.FLAG_FALLBACK) == 0) { mScreenshotChordPowerKeyTriggered = true; //Power 键被触发的标示符 mScreenshotChordPowerKeyTime = event.getDownTime(); //获取 Power 键的触发时间 interceptScreenshotChord(); } } private void interceptScreenshotChord() { if (mScreenshotChordEnabled //系统是否开启截屏功能 &&mScreenshotChordVolumeDownKeyTriggered //音量减键已被按下 &&mScreenshotChordPowerKeyTriggered //电源减键已被按下 && !mA11yShortcutChordVolumeUpKeyTriggered) { //音量减键未被按下 final long now = SystemClock.uptimeMillis(); //获取当前的时间 //当前时间要小于或等于音量减键被按下时间+150S if (now < = mScreenshotChordVolumeDownKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS // 当前时间要小于或等于电源键被按下时间+150S && now < = mScreenshotChordPowerKeyTime + SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS) { mScreenshotChordVolumeDownKeyConsumed = true; cancelPendingPowerKeyAction(); mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN); mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay()); } } } //截屏是有两种模式,一种是全屏截屏,另一种是区域截屏。默认是全屏截屏 private class ScreenshotRunnable implements Runnable { private int mScreenshotType = TAKE_SCREENSHOT_FULLSCREEN;//默认截屏方式是全屏截取 public void setScreenshotType(int screenshotType) { mScreenshotType = screenshotType; } @Override public void run() { takeScreenshot(mScreenshotType)