SystemUI之ScreenShot
ScreenShot流程
base/services/core/java/com/android/server/policy/PhoneWindowManager.java
物理截屏:按下power键和音量下键
private void initKeyCombinationRules() {mKeyCombinationManager = new KeyCombinationManager();final boolean screenshotChordEnabled = mContext.getResources().getBoolean(com.android.internal.R.bool.config_enableScreenshotChord);if (screenshotChordEnabled) {mKeyCombinationManager.addRule(//按下电源键和音量下键new TwoKeysCombinationRule(KEYCODE_VOLUME_DOWN, KEYCODE_POWER) {@Overridevoid execute() {mPowerKeyHandled = true;interceptScreenshotChord();}@Overridevoid cancel() {cancelPendingScreenshotChordAction();}});}
}
收到截屏指令后,执行interceptScreenshotChord方法,
设置截屏类型
全屏:TAKE_SCREENSHOT_FULLSCREEN
用户选择区域:TAKE_SCREENSHOT_SELECTED_REGION
调用者提供的图像:TAKE_SCREENSHOT_PROVIDED_IMAGE
设置截屏来源
SCREENSHOT_KEY_CHORD
SCREENSHOT_KEY_OTHER
SCREENSHOT_OVERVIEW
SCREENSHOT_ACCESSIBILITY_ACTIONS
SCREENSHOT_OTHER
SCREENSHOT_VENDOR_GESTURE
private void interceptScreenshotChord() {mHandler.removeCallbacks(mScreenshotRunnable);mScreenshotRunnable.setScreenshotType(TAKE_SCREENSHOT_FULLSCREEN);mScreenshotRunnable.setScreenshotSource(SCREENSHOT_KEY_CHORD);mHandler.postDelayed(mScreenshotRunnable, getScreenshotChordLongPressDelay());}
执行ScreenRunnale.run()方法
private class ScreenshotRunnable implements Runnable {private int mScreenshotType = TAKE_SCREENSHOT_FULLSCREEN;private int mScreenshotSource = SCREENSHOT_KEY_OTHER;public void setScreenshotType(int screenshotType) {mScreenshotType = screenshotType;}public void setScreenshotSource(int screenshotSource) {mScreenshotSource = screenshotSource;}@Overridepublic void run() {mDefaultDisplayPolicy.takeScreenshot(mScreenshotType, mScreenshotSource);}}
截屏takeScreenshot()
base/services/core/java/com/android/server/wm/DisplayPolicy.java
public void takeScreenshot(int screenshotType, int source) {if (mScreenshotHelper != null) {mScreenshotHelper.takeScreenshot(screenshotType,getStatusBar() != null && getStatusBar().isVisible(),getNavigationBar() != null && getNavigationBar().isVisible(),source, mHandler, null /* completionConsumer */);}}
base/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotService.java
创建一个 GlobalScreenshot 对象,通过GlobalScreenshot对象实现截屏 private final GlobalScreenshot mScreenshot;
在Handler中对三种截屏方式做处理
private Handler mHandler = new Handler(Looper.myLooper()) {@Overridepublic void handleMessage(Message msg) {final Messenger callback = msg.replyTo;Consumer<Uri> uriConsumer = uri -> {Message reply = Message.obtain(null, SCREENSHOT_MSG_URI, uri);try {callback.send(reply);} catch (RemoteException e) {}};Runnable onComplete = () -> {Message reply = Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE);try {callback.send(reply);} catch (RemoteException e) {}};// If the storage for this user is locked, we have no place to store// the screenshot, so skip taking it instead of showing a misleading// animation and error notification.if (!mUserManager.isUserUnlocked()) {Log.w(TAG, "Skipping screenshot because storage is locked!");post(() -> uriConsumer.accept(null));post(onComplete);return;}ScreenshotHelper.ScreenshotRequest screenshotRequest =(ScreenshotHelper.ScreenshotRequest) msg.obj;mUiEventLogger.log(ScreenshotEvent.getScreenshotSource(screenshotRequest.getSource()));switch (msg.what) {case WindowManager.TAKE_SCREENSHOT_FULLSCREEN:mScreenshot.takeScreenshot(uriConsumer, onComplete);break;case WindowManager.TAKE_SCREENSHOT_SELECTED_REGION:mScreenshot.takeScreenshotPartial(uriConsumer, onComplete);break;case WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE:Bitmap screenshot = BitmapUtil.bundleToHardwareBitmap(screenshotRequest.getBitmapBundle());Rect screenBounds = screenshotRequest.getBoundsInScreen();Insets insets = screenshotRequest.getInsets();int taskId = screenshotRequest.getTaskId();int userId = screenshotRequest.getUserId();ComponentName topComponent = screenshotRequest.getTopComponent();mScreenshot.handleImageAsScreenshot(screenshot, screenBounds, insets,taskId, userId, topComponent, uriConsumer, onComplete);break;default:Log.d(TAG, "Invalid screenshot option: " + msg.what);}}};
当截取全屏时
base/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
private void takeScreenshot(Consumer<Uri> finisher, Rect crop) {// copy the input Rect, since SurfaceControl.screenshot can mutate itRect screenRect = new Rect(crop);int rot = mDisplay.getRotation();int width = crop.width();int height = crop.height();takeScreenshot(SurfaceControl.screenshot(crop, width, height, rot), finisher, screenRect,Insets.NONE, true);}private void takeScreenshot(Bitmap screenshot, Consumer<Uri> finisher, Rect screenRect,Insets screenInsets, boolean showFlash) {dismissScreenshot("new screenshot requested", true);mScreenBitmap = screenshot;if (mScreenBitmap == null) {mNotificationsController.notifyScreenshotError(R.string.screenshot_failed_to_capture_text);finisher.accept(null);mOnCompleteRunnable.run();return;}if (!isUserSetupComplete()) {// User setup isn't complete, so we don't want to show any UI beyond a toast, as editing// and sharing shouldn't be exposed to the user.saveScreenshotAndToast(finisher);return;}// OptimizationsmScreenBitmap.setHasAlpha(false);mScreenBitmap.prepareToDraw();onConfigChanged(mContext.getResources().getConfiguration());if (mDismissAnimation != null && mDismissAnimation.isRunning()) {mDismissAnimation.cancel();}// The window is focusable by defaultsetWindowFocusable(true);// Start the post-screenshot animationstartAnimation(finisher, screenRect, screenInsets, showFlash);}
截屏之后开始截屏动画
private void startAnimation(final Consumer<Uri> finisher, Rect screenRect, Insets screenInsets,boolean showFlash) {// If power save is on, show a toast so there is some visual indication that a// screenshot has been taken.PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);if (powerManager.isPowerSaveMode()) {Toast.makeText(mContext, R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show();}mScreenshotHandler.post(() -> {if (!mScreenshotLayout.isAttachedToWindow()) {mWindowManager.addView(mScreenshotLayout, mWindowLayoutParams);}mScreenshotAnimatedView.setImageDrawable(createScreenDrawable(mScreenBitmap, screenInsets));setAnimatedViewSize(screenRect.width(), screenRect.height());// Show when the animation startsmScreenshotAnimatedView.setVisibility(View.GONE);mScreenshotPreview.setImageDrawable(createScreenDrawable(mScreenBitmap, screenInsets));// make static preview invisible (from gone) so we can query its location on screenmScreenshotPreview.setVisibility(View.INVISIBLE);mScreenshotHandler.post(() -> {mScreenshotLayout.getViewTreeObserver().addOnComputeInternalInsetsListener(this);mScreenshotAnimation =createScreenshotDropInAnimation(screenRect, showFlash);saveScreenshotInWorkerThread(finisher, new ActionsReadyListener() {@Overridevoid onActionsReady(SavedImageData imageData) {showUiOnActionsReady(imageData);}});// Play the shutter sound to notify that we've taken a screenshotmCameraSound.play(MediaActionSound.SHUTTER_CLICK);mScreenshotPreview.setLayerType(View.LAYER_TYPE_HARDWARE, null);mScreenshotPreview.buildLayer();mScreenshotAnimation.start();});});}
SystemUI之ScreenShot相关推荐
- 屏幕截图 take screenshot
ScreenCapture.CaptureScreenshotAsTexture yield return new WaitForEndOfFrame(); var screenShotTexture ...
- Android 4.0 截屏(Screenshot)代码流程小结
Android 4.0 截屏 在Android 4.0 之前,Android手机上如果要使用截屏功能,只能通过Root手机,且使用第3方截图软件来实现截屏功能. Android4.0中,系统自带了截屏 ...
- Android核心程序之SystemUI - (一)开篇
UI是实现用户交互的重要途径之一,而Android中一个重要的UI元素就是SystemUI,本文分析基于Android 5.1,分析SystemUI的启动及运行过程. SystemUI源代码所在路径为 ...
- Android 4.0 ICS SystemUI浅析——SystemUI启动流程
阅读Android 4.0源码也有一段时间了,这次是针对SystemUI的一个学习过程.本文只是对SystemUI分析的一个开始--启动流程的分析,网上有很多关于2.3的SystemUI的分析,可4. ...
- Android源码学习------SystemUI(二)
SystemUI----AndroidManifest文件 AndroidManifest是Android应用程序中最重要的文件之一.它是Android程序的全局配置文件,是每个 android程序中 ...
- SystemUi概述
一.SystemUI概述 在Android系统中SystemUI是以应用的形式运行的.即编译SystemUI会产生APK文件.但它和普通的APK不同,它是开机启动的A并且不可以退出, SystemUI ...
- android 6.0 SystemUI源码分析(1)-SystemUI介绍
1. SystemUI介绍 SystemUI是一个系统应用,主要功能有: 1)状态栏信息显示,比如电池,wifi信号,3G/4G等icon显示 2)通知面板,比如系统消息,第三方应用消息,都是在通知面 ...
- SystemUI架构分析学习
目录 1.SystemUI路径及概念介绍 2.SystemUI主要功能 2.1Status bars详解 2.2Notification流程 2.3Navigation bars详解 1.System ...
- SystemUI深度裁剪
SystemUI深度裁剪 前言 SystemUI AOSP包含了很多组件, Status bars,Navigation bars,Notification,Lockscreen,Quick sett ...
最新文章
- ednote服务器运行失败,endnote搜索文献时连不上服务器 Endnote连接服务器问题
- 解析自动驾驶算法四大模块的问题与后续发展
- #Sora#OpenStack基础库oslo.config试用总结
- Window.Open- ShowModalDialog- Window.Open Session丢失的Solution
- JMeter初探五-配置元件与参数化
- js数组去重,合集等操作
- 【bzoj4444】[Scoi2015]国旗计划 倍增
- linux学习笔记(11)df命令
- HCIE-OSPFV3
- 运行通达信行情接口软件的电脑需要什么配置?
- 在线浏览 Stata 15 PDF 全套电子手册
- 智能控制器在风机及水泵中的应用
- 头指针、头节点、首元结点——《王道数据结构》
- word2010怎样显示分节符?
- 幼儿园调查过程怎么写_幼儿园的调查报告范文
- Oracle管理的文件(OMF)的具体含义
- 方差分析介绍(结合COVID-19案例)
- 钟汉良日记:做短视频和直播的基础能力
- 大厂面试题含答案(二)
- 敏捷开发:一文了解影响地图和用户故事地图之间的那些事儿
热门文章
- su: failed to execute /bin/bash: Permission denied问题解决
- 英文论文-城市云脑,基于互联网云脑的智慧城市新架构
- 广东某大型餐厨垃圾处理设备 解决方案
- 【msvcp140.dll怎么下载】吃鸡msvcp140.dll丢失的解决方法
- 运动控制卡的运动控制介绍
- 解决中兴U880手机IMEI串号丢失的方法
- 安卓虚拟键盘_这是第一台安卓手机,当年谷歌和HTC靠它正面刚苹果|极客博物馆...
- Python爬虫实战:爬取贝壳网二手房40000条数据
- iCloud学习笔记
- 手把手带你免费部署https