一般android手机都可以通过“电源键+音量键”组合触发系统截图功能,那么自己开发通过代码如何实现呢?
通过源码分析得知,按下截图组合键后,会发送一个键值KeyEvent.KEYCODE_SYSRQ到framework进行处理:
frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
interceptKeyBeforeDispatching()先接收到截屏按键KEYCODE_SYSRQ
// TODO(b/117479243): handle it in InputPolicy
/** {@inheritDoc} */
@Override
public long interceptKeyBeforeDispatching(IBinder focusedToken, KeyEvent event,
int policyFlags) {
...
switch(keyCode) {
case KeyEvent.KEYCODE_HOME:
// First we always handle the home key here, so applications
// can never break it, although if keyguard is on, we do let
// it handle it, because that gives us the correct 5 second
// timeout.
DisplayHomeButtonHandler handler = mDisplayHomeButtonHandlers.get(displayId);
if (handler == null) {
handler = new DisplayHomeButtonHandler(displayId);
mDisplayHomeButtonHandlers.put(displayId, handler);
}
return -1;
//return handler.handleHomeButton(focusedToken, event);
case KeyEvent.KEYCODE_MENU:
// Hijack modified menu keys for debugging features
final int chordBug = KeyEvent.META_SHIFT_ON;
if (down && repeatCount == 0) {
if (mEnableShiftMenuBugReports && (metaState & chordBug) == chordBug) {
Intent intent = new Intent(Intent.ACTION_BUG_REPORT);
mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT,
null, null, null, 0, null, null);
return key_consumed;
}
}
break;
...
case KeyEvent.KEYCODE_SYSRQ: //截图事件
if (down && repeatCount == 0) {
mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);
mScreenshotRunnable.setScreenshotSource(SCREENSHOT_KEY_OTHER);
mHandler.post(mScreenshotRunnable);
}
return key_consumed;
继续搜索截图任务mHandler.post(mScreenshotRunnable);惊喜发现系统还注册了一个广播来处理截图功能:
BroadcastReceiver mScreenshotReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
mHandler.post(mScreenshotRunnable);
}
};
// register for screenshot broadcasts
filter = new IntentFilter();
filter.addAction("android.intent.action.SCREENSHOT");
context.registerReceiver(mScreenshotReceiver, filter);
那么也就是说在任何第三方应用开发时,只需发送一条android.intent.action.SCREENSHOT即可触发系统截图功能。先通过adb模拟发送广播测试:
adb sshell am broadcast -a "android.intent.action.SCREENSHOT"
结果成功触发了系统截图,所以实现系统截图功能一行代码,发送个广播就可以了。
//触发系统截图
sendBroadcast(new Intent("android.intent.action.SCREENSHOT"));