Android如何截取屏幕截图?

Pat*_*ney 7 android screenshot

我知道如何截取屏幕截图,但我想知道它是如何工作的.

至少从Android 4.0开始,您可以通过按住手机上的音量减小+电源键来拍摄屏幕截图,Android将捕获当前屏幕并将其保存到SD卡.

我只是想知道是否有人知道这是如何工作的,如果它是一个在后台不断运行的服务,或者每个应用程序中内置的东西,或者.此外,它位于Android的源代码中的哪个位置?

谢谢!

Jus*_*ris 6

如果您只是想拍摄一个非常直接的屏幕截图:

public Bitmap screenShot(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
            view.getHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}
Run Code Online (Sandbox Code Playgroud)

只需使用您想要快照的视图调用此方法..所以如果您希望整个屏幕只是传递给您最顶层ViewGroup.如果你想要系统控件也只是调用:

screenShot((ViewGroup) view.getParent());
Run Code Online (Sandbox Code Playgroud)

现在,如果您想知道"音量降低+电源键"的工作原理是如何在操作系统中更深入,而不是您可以访问的.无法拦截APK AFAIK的电源按钮.


Pat*_*ney 6

我刚刚在源代码树中找到了代码:https://github.com/android/platform_frameworks_base/tree/master/packages/SystemUI/src/com/android/systemui/screenshot

我想这只是通过阅读它来更好地理解这个过程的问题.


gbt*_*mon 1

Android 应用程序使用意图来调用系统级资源。例如,大多数运行相机的软件都是由操作系统提供的。Android 操作系统基于 unix/linux 内核,因此使用相机将如下所示。

  1. 应用程序/进程决定它想要使用相机。
  2. 该应用程序/进程构建一个意图并将其传递给操作系统。
  3. Intent由操作系统处理,相机软件在新进程中执行(exec)。如果调用进程同步调用意图,则调用进程可以阻止它,也可以异步运行,并且调用应用程序和意图调用的应用程序可以同时运行。在相机的示例中,它可能会被同步调用并阻塞。
  4. 相机进程供用户用来拍照。
  5. 相机进程退出并产生错误或图片。
  6. 操作系统执行一些 ipc(进程间通信)以将图片传回调用进程。根据应用程序调用的意图类型,选择使用管道还是消息传递由操作系统决定。相机可能会使用消息传递,因为子进程运行时父进程被阻止。
  7. 现在,阻塞等待意图返回的调用进程被操作系统唤醒并返回到运行状态。
  8. 图片已返回到调用应用程序,以便其按需要使用。

当您拍摄屏幕截图时,这正是发生的情况。有一个正在运行的进程来处理用户界面。它基本上等待输入并过滤任何应该由操作系统解释的内容,然后再通过管道传输到当前正在运行的应用程序。这是另一个 Unix 约定,目前在我能想到的每个操作系统中都是标准的——管道输入流。它允许操作系统捕获更高优先级的输入,例如操作系统控制命令,然后再将其传递给应用程序。(想想Windows中的ctrl-alt-delete,或者unix中的ctrl-c/ctrl-z。)当按下屏幕截图键时,这个上游io进程会执行一个特殊的程序来拍摄屏幕截图(通过意图)和命令从未真正传递给“正在运行”的应用程序。该程序在新进程中执行(exec),构建屏幕位图,将其保存到图库空间,然后终止 - 所有这些都与处理时间共享的调度程序异步,因此手机始终感觉“响应”。您可以在 John Bokers 的回答中看到源代码以及实现此功能的所有 gorp。