如何在没有root权限的情况下以编程方式截取其他应用,例如Screenshot UX Trial?
我知道我可以在我的应用中捕获根视图的位图。但是当我的应用程序在后台运行时,我无法获得其他应用程序的根视图
bitmap = Bitmap.createBitmap(rootview.getDrawingCache());
有权在Manifest中捕获当前帧缓冲区:android.permission.READ_FRAME_BUFFER
。但是有些网站表示它只适用于签名应用程序。
尝试使用屏幕截图UX试用版后,我读取了权限:
似乎SYSTEM_ALERT_WINDOW
或GET_TASKS
允许该应用截取屏幕截图。
我有两个猜测它是如何工作的:
Activity
,它获取Activity
的根视图,捕获其屏幕截图。glreadpixels
如果您尝试我的猜测,请告诉我结果。
答案 0 :(得分:106)
这非常困难。我花了几年时间试图去做。我最终成功了,但任何解决方案都涉及商业和技术方面的努力。
以下大多数内容不再是最新的。经过这么多年,现在已经有了android.media.projection
个包裹
https://developer.android.com/reference/android/media/projection/package-summary.html
最终允许你需要的东西!
为了完整起见,我想包含您自己的评论,您可以使用Bitmap.createBitmap(rootview.getDrawingCache());
和类似的机制捕获您自己的应用程序的图像。
READ_FRAMEBUFFER
权限首先,您是正确的,正常的应用程序无法使用READ_FRAMEBUFFER
权限,因为它是"签名" -level。这意味着您必须使用与Android系统ROM相同的密钥进行签名才能获取此类屏幕截图。
我觉得这有点难过,所以早在2009年我就提交了一个Android开源项目提交,要求它开放1。 Android架构师Dianne Hackborn的回应是:
嗯,不。绝对肯定不是。
那么,那就顺利了!因此,此权限仍然是signature
- 到今天为止。
但是,如果您拥有此权限,则可以致电captureScreen
2的ISurfaceComposer
成员。您需要使用Android NDK以及一些未记录的API来编写一些本机代码来访问此功能。但是,这是可能的。
在Android图形子系统内部,它使用glReadPixels
调用将GPU中的像素检索回CPU。 (GPU用于Android上的大部分合成。事实上,Android 4.0+支持额外的硬件合成器,而Surface Flinger必须做更多工作才能将这些像素拉回CPU。)
除了一些小问题外,这个电话很有效:
......还有一个大问题......
但是,在大多数Android设备上,你可以获得每秒10帧的速度。更好的是,这个API实际上支持在GPU上的硬件中缩放生成的图像 ,所以如果你更聪明,你可以在像素均匀之前将图像预缩放到你需要的尺寸。打了CPU。所以它可以是非常高的性能。
当然,请注意,作为应用程序编写者,您无法调用glReadPixels
,因为您无法访问相关的OpenGL上下文。它由地面抛弃物拥有。
/dev/graphics/fb0
和类似的有些人试图尝试阅读代表帧缓冲区的这些Linux设备文件。但是,有三个问题:
captureScreen
API来获取正确的图片。现在我们进入需要商业行动的解决方案。
与Android芯片组制造商交谈时经常提出解决方案。由于他们设计了硬件,因此他们可以访问帧缓冲区 - 而且他们通常只需直接访问自定义内核驱动程序就可以提供完全避免Android权限模型的库。
如果你的目标是特定的手机型号,这往往是一个很好的方法。当然,您可能需要与手机制造商以及硅制造商合作。
有时,这可以提供杰出的结果。例如,我听说可以在某些硬件上将电话硬件帧缓冲器直接传输到手机硬件H.264视频编码器中,并检索电话屏幕上任何内容的预编码视频流。优秀。 (不幸的是,我只是知道这可能在TI OMAP芯片上逐渐退出电话市场3。)
Android严格执行其权限模型,并且安全漏洞很少。然而,Android OEM有时会更粗心。
例如,名称以S开头的主要OEM已实现了使用击键捕获屏幕的方法。它将其保存到SD卡上的世界可读文件中。假设您可以找到截取这些键的内容并查看其工作原理。也许你可以做类似的事情。
也许还有另一种主要OEM的方式,其名称也以S开头。
不,我不打算详细介绍这一部分。要弄清楚如何做这些事情,我需要有逆向工程软件,这可能是非法的。祝你好运。
如前所述,手机制造商可以随时访问可行的API 。手机制造商需要signature
级权限。
因此,您需要做的就是安排手机制造商签署您的软件。
然而,这是 hard 。通过签署软件,手机制造商保证其质量 - 因此他们应该想要审核您的源代码。此外,由于Android的性质 - 如果他们签署软件,他们需要是分发它的人。如果由其他人签名,您就无法将其投放市场。
然而,OEM不需要将其包含在ROM中 - 他们仍然可以在Android市场上分发它。但你不能。
一个好的解决方案是,如果每个供应商签署了一个小型库,然后可以通过通用SDK访问。这引导我进入......
我对此非常了解,因为我曾经在RealVNC工作过。我们与所有主要的Android手机供应商合作,以访问这些签名级API。我不能过分强调实现这一目标所需的许多工作量(商业和技术上)。一些OEM公布了这项工作 - 例如4。
我不再在RealVNC上工作,所以我在宣传他们的软件时没有任何好处。但是,如果您真的希望能够在多个Android设备上捕获屏幕,您可能希望与他们联系以重新使用他们的远程控制服务或Android VNC SDK 5。它不是开源的,所以你应该期望支付,并且相信我这是公平的,因为与所有这些Android OEM合作的史诗努力。
为了平衡,我应该指出其他供应商也与手机制造商合作 - 例如技工机构。但我相信它们都提供特定的设备管理解决方案,而不是通用的远程控制/事件注入SDK。
另一个选项 - 通过USB侦听调试连接的adb
守护程序具有比普通应用程序更多的权限,这就是它能够抓取屏幕的原因(您可以使用ddms
工具)。如果您能够使用adb
运行任何命令,那么您也可以获得这些权限(根据之前链接的android-screenshot-library)。
最终这个问题让我陷入了灰尘,我离开了更加绿色的牧场,并没有试图从Android手机中挤出像素。
在我离开RealVNC之前,我们再次尝试将这些API贡献给Android开源项目。这次我们得到了更积极的反应6。简而言之,有人建议我们的安全方法几乎是正确的,但图形系统处于太大的混乱状态才能接受我们的补丁。嗯,好消息是图形系统不再处于动荡之中 - 事实上它现在有captureScreen
API,这意味着不需要任何图形系统更改。因此,可以围绕此API向AOSP提交新的安全机制,最终解决了这个问题。
祝你好运!
答案 1 :(得分:3)
也许android-screenshot-library可以提供帮助。但是在他们的用法页面中,它说它需要一个以adb开头的本机服务(来自android sdk)。
PS:请记住,屏幕截图用户体验不适用于每个无根电话。
答案 2 :(得分:-1)
我认为Android不允许您访问其他应用的帧缓冲区。这只是Android安全性的一部分。每个应用程序都应该保留自己的资源。
如果您确实需要获取任何应用的屏幕截图,我建议使用原生屏幕抓取“手势”。例如,对于Nexus 7,只需“......同时按住电源按钮和音量降低按钮约2秒钟。”
Google搜索通常会找到您设备的技巧。