如何在没有root权限的情况下以编程方式获取其他应用程序的屏幕截图,例如Screenshot UX Trial?

Vic*_*ang 53 android android-ui

如何在没有root权限的情况下以编程方式获取其他应用程序的屏幕截图,例如Screenshot UX Trial?

  1. 我知道我可以在我的应用程序中捕获根视图的位图.但是当我的应用程序在后台运行时,我无法获得其他应用程序的根视图

    bitmap = Bitmap.createBitmap(rootview.getDrawingCache());

  2. 在Manifest中有权捕获当前帧缓冲区:android.permission.READ_FRAME_BUFFER.但是一些网站说它只适用于签名应用.

    检查Android权限 - 保护级别

在尝试使用屏幕截图UX试用版后,我阅读了权限:

  • INTERNET:用于连接到roothost手机的localhost屏幕截图服务器.
  • SYSTEM_ALERT_WINDOW:用于最顶层的相机按钮.
  • 振动:用于振动反馈.
  • WRITE_EXTERNAL_STORAGE:保存屏幕截图.
  • GET_TASKS:用于检测非根和非预加载捕获方法的前景开发设置活动.

它似乎SYSTEM_ALERT_WINDOWGET_TASKS允许应用程序截取屏幕截图.我有两个猜测它是如何工作的:

  1. 它可能能够访问Activity前景活动,它获取其根视图Activity,捕获其截图.
  2. 调用 glreadpixels

如果您尝试我的猜测,请告诉我结果.

Adr*_*lor 109

这非常困难.我花了几年时间试图去做.我最终成功了,但任何解决方案都涉及商业和技术方面的努力.


2015年3月更新

下面的大部分内容都不再是最新的.经过这么多年,现在有了一个android.media.projectionhttps://developer.android.com/reference/android/media/projection/package-summary.html ,它最终可以满足您的需求!


捕获您自己的应用程序的屏幕图像

为了完整起见,我想包括你自己的评论,你可以捕捉自己的应用程序中使用的图像Bitmap.createBitmap(rootview.getDrawingCache());和类似的机制.

当你在后台时捕捉另一个应用程序的屏幕

使用READ_FRAMEBUFFER权限

首先,你是正确的,普通的应用程序不能使用READ_FRAMEBUFFER权限,因为它是"签名"级别.这意味着您必须使用与Android系统ROM相同的密钥进行签名才能获取此类屏幕截图.

我觉得这有点难过,所以早在2009年我就提出了一个Android开源项目提交,要求它开放1.Android架构师Dianne Hackborn的回应是:

不.绝对肯定不是.

那么,那就顺利了!因此,这种许可至今仍然是水平的signature.

但是,如果您拥有此权限,则可以致电2captureScreen成员.您需要使用Android NDK以及一些未记录的API来编写一些本机代码来访问此功能.但是,这是可能的.ISurfaceComposer

在Android图形子系统内部,它使用glReadPixels调用将GPU中的像素检索回CPU.(GPU用于Android上的大多数合成.事实上,Android 4.0+支持额外的硬件合成器,而Surface Flinger必须做更多工作才能将这些像素拉回CPU.)

除了一些小问题之外,此调用工作得非常好:

  • 使用不受支持的API的风险可能随时中断;
  • 用C++调用它的麻烦
  • 它导致GPU流水线停滞,这可能会扰乱GPU设计人员,但实际上并不会造成问题
  • 它依赖于从GPU大的带宽给CPU.这有时是有问题的,因为存储器架构被设计为以相反的方向发送数据.但是,我似乎记得所有现代Android芯片组架构都直接在GPU和CPU之间共享内存,除了一个(它可能是Broadcom? - 我记不起来),这可能导致这种机制非常慢.

......还有一个大问题......

  • 最重要的是,作为普通的应用程序编写者,由于需要签名级权限,您甚至无法调用此API.

不过,在大多数Android设备上,你可以获得每秒10帧的速度.更好的是,这个API实际上支持在GPU上的硬件中缩放生成的图像,所以如果你很聪明,你可以在像素甚至击中CPU之前将图像预缩放到你需要的尺寸.所以它可以是非常高的性能.

当然,请注意,您作为应用程序编写者无法调用,glReadPixels因为您无权访问相关的OpenGL上下文.它由表面抛弃物所拥有.

使用/dev/graphics/fb0和类似

有些人试图尝试阅读代表帧缓冲区的这些Linux设备文件.但是,有三个问题:

  • 你需要root.
  • 有时他们甚至不在那里.
  • 通常,它们不代表真实的屏幕图像.请记住,在Android上,图形是在GPU上合成的.因此,CPU没有理由可以访问完整合成屏幕图像的副本,而且通常不会.此文件有时包含撕裂(最好)和垃圾图像(最坏).有趣的是,有根电话的一些工具确实使用了这种方法,我认为这是一个错误.如果您已经拥有root权限,那么根据定义,您拥有所有Android权限,因此可以调用上述captureScreenAPI来获取正确的图像.

使用硬件伙伴

现在我们进入需要商业行动的解决方案.

与Android芯片组制造商交谈经常提出一个解决方案.由于他们设计硬件,他们可以访问帧缓冲区 - 他们通常只需要直接访问自定义内核驱动程序就可以提供完全避免Android权限模型的库.

如果您的目标是特定的手机型号,这往往是一个很好的方法.当然,您需要与手机制造商以及硅制造商合作.

有时这可以提供出色的结果.例如,我听说在一些硬件上可以将手机硬件帧缓冲器直接传输到手机硬件H.264视频编码器中,并检索电话屏幕上任何内容的预编码视频流.优秀.(不幸的是,我只知道这可能是TI OMAP芯片,它正在逐渐退出手机市场3).

使用安全漏洞

Android严格执行其权限模型,并且几乎没有安全漏洞.然而,Android OEM有时会更粗心.

例如,名称以S开头的主要OEM已经实现了使用击键捕获屏幕的方法.它将其保存到SD卡上的世界可读文件中.假设您可以找到截取这些键的内容并查看其工作原理.也许你可以做类似的事情.

也许还有另一种主要OEM的方式,其名称也以S开头.

不,我不打算详细介绍这一部分.要弄清楚如何做这些事情,我需要有逆向工程软件,这可能是非法的.祝你好运.

与手机制造商合作

如前所述,手机制造商可以随时访问可行的API .手机制造商需要具备signature级别的权限.

因此,您需要做的就是安排手机制造商签署您的软件.

然而,这很难.通过签署软件,手机制造商保证其质量 - 因此他们应该想要审核您的源代码.此外,由于Android的性质 - 如果他们签署软件,他们需要是分发它的人.如果由其他人的签名签名,您不能将其投放市场.

但是,OEM不需要将其包含在ROM中 - 它们仍然可以在Android市场上分发它.但你不能.

一个好的解决方案是,如果每个供应商签署了一个小型库,然后可以通过通用SDK访问.这导致我...

与已经解决此问题的软件合作伙伴合作

我对此了解很多,因为我曾经在RealVNC工作过.我们与所有主要的Android手机供应商合作,以访问这些签名级API.我不能过分强调实现这一目标所需的许多工作量(商业和技术上).一些原始设备制造商宣传了这项工作 - 例如4.

不再在RealVNC 工作了,所以我在宣传他们的软件时没有任何好处.但如果您真的希望能够在多个Android设备上捕获屏幕,您可能希望与他们联系以重新使用他们的远程控制服务或Android VNC SDK 5.它不是开源的,所以你应该期望付费,并且相信我这是公平的,因为与所有这些Android OEM合作的史诗努力.

为了平衡,我应该指出其他供应商也与手机制造商合作 - 例如Soti.但我相信他们都提供特定的设备管理解决方案,而不是一般的远程控制/事件注入SDK.

通过USB

另一个选项 - adb通过USB监听调试连接的守护进程具有比普通应用程序更多的权限,这就是为什么它能够抓取屏幕(您可以使用该ddms工具查看其图像).如果您能够使用任何命令运行,adb那么您也可以获得这些权限(根据之前链接的android-screenshot-library).

参与Android开源项目

最终这个问题让我陷入了灰尘,我离开了更加绿色的牧场,这并不涉及尝试从Android手机中挤出像素.

在我离开RealVNC之前,我们再次尝试将这些API贡献给Android开源项目.这次我们得到了更积极的反应6.简而言之,有人建议我们的安全方法几乎是正确的,但图形系统处于太大的混乱状态才能接受我们的补丁.嗯,好消息是图形系统不再处于动荡之中 - 事实上它现在有了这个captureScreenAPI,这意味着无需任何图形系统更改.因此,可以围绕此API向AOSP提交新的安全机制,最终解决了这个问题.

祝你好运!

  • 非常感谢您的广泛答案! (4认同)

DNa*_*Nax 3

也许android-screenshot-library可以提供帮助。但在他们的使用页面中,它说它需要一个以 adb 启动的本机服务(来自 android sdk)。

PS:请记住,Screenshot UX 并不适用于所有未 root 的手机。