如何在没有 root 权限的情况下以编程方式截取其他应用程序的屏幕截图,例如 Screenshot UX Trial?
bitmap = Bitmap.createBitmap(rootview.getDrawingCache());
android.permission.READ_FRAME_BUFFER
。但是有些网站说它仅适用于签名应用程序。Check Android Permissions - Protection Levels
在尝试 Screenshot UX Trial 后,我阅读了权限:
似乎
SYSTEM_ALERT_WINDOW
或 GET_TASKS
允许应用程序截取屏幕截图。我有两个猜测它是如何工作的:
Activity
,获取Activity
的根 View ,截图。 glreadpixels
如果您尝试我的猜测之一,请告诉我结果。
最佳答案
这是极其困难的。我花了几年的时间试图做到这一点。我最终成功了,但任何解决方案都将涉及商业和技术方面的努力。
2015 年 3 月更新
下面的大部分内容不再是最新的。经过这么多年,现在有了一个 android.media.projection
包
https://developer.android.com/reference/android/media/projection/package-summary.html
这最终允许你需要什么!
捕获您自己的应用程序的屏幕图像
为了完整起见,我想包括您自己的评论,您可以使用 Bitmap.createBitmap(rootview.getDrawingCache());
和类似机制捕获自己的应用程序的图像。
在后台捕获另一个应用程序的屏幕
使用 READ_FRAMEBUFFER
权限
首先,普通应用程序不能使用 READ_FRAMEBUFFER
权限是对的,因为它是“签名”级别的。这意味着您必须使用与 Android 系统 ROM 相同的 key 签名才能截取此类屏幕截图。
我觉得这有点令人伤心,所以早在 2009 年我就提交了一个 Android 开源项目提交,要求将其开放 1 。 Android 架构师 Dianne Hackborn 的回应是:
Um, no. Absolutely positively not.
那么,一切顺利!因此,直到今天,此权限仍然是
signature
级别。但是,如果您拥有此权限,则可以调用
captureScreen
2 的 ISurfaceComposer
成员。您需要使用 Android NDK 和一些未公开的 API 编写一些 native 代码来访问此功能。然而,这是可能的。在 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 卡上的一个世界可读的文件中。假设您可以找到拦截这些键的内容并查看它是如何工作的。也许你可以做一些类似的事情。
也许还有一种方法可以让另一家名称也以 S 开头的主要 OEM 厂商。
不,我不打算详细介绍这一部分。为了弄清楚如何做这些事情,我需要有逆向工程软件,这可能是非法的。不过祝你好运。
与手机制造商合作
如前所述,手机制造商可以随时访问有效的 API。并且手机制造商拥有所需的
signature
级权限。因此,您需要做的就是安排让手机制造商对您的软件进行签名。
然而,这很难。通过签署软件,手机制造商保证了它的质量——所以他们应该审核你的源代码。此外,由于 Android 的性质 - 如果他们签署软件,他们需要成为分发它的人。如果它是由其他人签名的,则您不能将其转换市场。
但是,OEM 不需要将它包含在 ROM 中——他们仍然可以在 Android 市场上分发它。但你不能。
一个好的解决方案是,如果每个供应商都签署了一个小型库,然后可以通过通用 SDK 访问该库。这让我...
与已经解决了这个问题的软件合作伙伴合作
我对此非常了解,因为我曾经在 RealVNC 工作过。我们与所有主要的 Android 手机供应商合作,以访问这些签名级 API。为实现这一目标需要付出很多很多人年的努力(商业和技术上),我再怎么强调也不为过。一些 OEM 已经公布了这项工作——例如 4。
我不再在 RealVNC 工作,所以我从他们的软件广告中没有任何好处。但是,如果您真的希望能够在多个 Android 设备上捕获屏幕,您可能希望与他们联系以重新使用他们的远程控制服务或 Android VNC SDK 5 。它不是开源的,所以你应该期望付费,相信我,考虑到与所有这些 Android OEM 合作所付出的巨大努力,这已经足够公平了。
为了平衡起见,我应该指出其他供应商也在这方面与手机制造商合作 - 例如索蒂。但我相信他们都提供特定的设备管理解决方案,而不是通用的远程控制/事件注入(inject) SDK。
通过 USB
另一种选择 -
adb
守护进程通过 USB 监听调试连接,其权限比普通应用程序略多,这就是它能够抓取屏幕的原因(您可以使用 ddms
工具查看其图像)。如果您能够使用 adb
运行任何命令,那么您也可以获得这些权限(根据之前链接的 android-screenshot-library)。为 Android 开源项目做贡献
最终,这个问题让我尘埃落定,我离开了更绿色的牧场,这不涉及试图从 Android 手机中挤出像素。
在我离开 RealVNC 之前,我们再次尝试将这些 API 贡献给 Android 开源项目。这次我们得到了更积极的 react 6 。简而言之,有人认为我们的安全方法几乎是正确的,但图形系统太困惑而无法接受我们的补丁。好吧,好消息是图形系统不再处于困惑状态 - 事实上它现在拥有
captureScreen
API,这意味着不需要任何图形系统更改。因此,有可能围绕这个 API 向 AOSP 提交新的安全机制,最终解决这个问题。祝你好运!
关于android - 如何在没有 root 权限的情况下以编程方式截取其他应用程序的屏幕截图,例如 Screenshot UX Trial?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12462944/