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

2023-12-02

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

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

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

  2. Manifest中有一个捕获当前帧缓冲区的权限:android.permission.READ_FRAME_BUFFER。但有些网站说它仅适用于签名应用程序。

    检查 Android 权限 - 保护级别

尝试 Screenshot UX Trial 后,我阅读了权限:

  • 互联网:用于连接到本地主机屏幕截图服务器以获取 root 权限的手机。
  • SYSTEM_ALERT_WINDOW:用于最上面的相机按钮。
  • VIBRATE:用于振动反馈。
  • WRITE_EXTERNAL_STORAGE:保存屏幕截图。
  • GET_TASKS:用于检测非rooted&非预加载捕获方法的前台开发设置活动。

看来要么SYSTEM_ALERT_WINDOW or GET_TASKS允许应用程序截屏。 我对其工作原理有两种猜测:

  1. 它也许能够访问Activity的前台活动,它获取根视图Activity,捕获其屏幕截图。
  2. Calling glreadpixels

如果您尝试我的猜测之一,请告诉我结果。


This is extremely difficult. I spent several years trying to do it. I eventually succeeded, but any solution will involve commercial as well as technical effort.


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 相同的密钥进行签名才能进行此类屏幕截图。

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

不。绝对不是。

那么,一切顺利!因此这个权限仍然是signature至今为止的水平。

但是,如果您有此权限,您可以致电captureScreen成员ISurfaceComposer2。您需要使用 Android NDK 以及一些未记录的 API 编写一些本机代码来访问此函数。然而,这是可能的。

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

除了一些小问题之外,这个调用工作得很好:

  • 使用不受支持的 API 的风险可能随时中断;
  • 在C++中调用它的麻烦
  • 它会导致 GPU 管道停顿,这可能会让 GPU 设计者感到不安,但实际上并不会造成问题
  • 它依赖于 GPU 的大带宽back到CPU。这有时会产生问题,因为内存架构被设计为以相反的方向发送数据。然而,我似乎记得所有现代 Android 芯片组架构都直接在 GPU 和 CPU 之间共享内存,除了一个(可能是 Broadcom? - 我不记得了),这可能会导致该机制非常慢。

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

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

尽管如此,在大多数 Android 设备上,您仍可以获得每秒 10 帧的速度。更好的是,这个 API 实际上支持缩放结果图像在 GPU 上的硬件中,所以如果您足够聪明,您可以在像素到达 CPU 之前将图像预先缩放到您需要的大小。因此它可以具有极高的性能。

当然,请注意,作为应用程序编写者,您无法调用glReadPixels因为您无权访问相关的 OpenGL 上下文。它属于表面抛掷器所有。

Using /dev/graphics/fb0和类似的

有些人试图读取这些代表帧缓冲区的 Linux 设备文件。然而,存在三个问题:

  • 你需要root。
  • 有时他们甚至不在那里。
  • 通常,它们并不代表真实的屏幕图像。请记住,在 Android 上,图形是在 GPU 上合成的。因此,CPU 没有理由有权访问完整合成屏幕图像的副本,而且通常也不能访问。该文件有时包含撕裂(最好的情况)和垃圾图像(最坏的情况)。有趣的是,一些针对root手机的工具确实使用了这种方法,我认为这是一个错误。如果你有root权限,那么根据定义你就拥有所有Android权限,因此可以调用上面的命令captureScreen用于获取正确图像的 API。

使用硬件合作伙伴

现在我们讨论需要商业行动的解决方案。

与 Android 芯片组制造商交谈通常会提出解决方案。由于他们设计了硬件,因此他们可以访问帧缓冲区 - 并且他们通常能够通过直接访问其自定义内核驱动程序来提供完全避免 Android 权限模型的库。

如果您的目标是特定的手机型号,这通常是一个很好的方法。当然,您很可能需要与手机制造商以及芯片制造商合作。

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

利用安全漏洞

Android 严格执行其权限模型,并且几乎没有安全漏洞。然而,Android OEM 厂商有时可能会比较粗心。

例如,一家名称以 S 开头的主要 OEM 已经实现了一种使用击键来捕获屏幕的方法。它将其保存到 SD 卡上的全球可读文件中。假设您也许能够找到拦截这些密钥的内容并了解其工作原理。也许你可以做类似的事情。

也许另一家名称也以 S 开头的主要 OEM 有办法。

不,我不会详细介绍本节。为了弄清楚如何做这些事情,我需要有逆向工程软件,这可能是非法的。不过祝你好运。

与手机制造商合作

如前所述,手机制造商可以随时访问 API,该 API确实有效。手机制造商有signature需要-级权限。

因此,您所需要做的就是安排手机制造商对您的软件进行签名。

然而,这是hard。通过对软件进行签名,手机制造商可以保证其质量 - 因此他们应该审核您的源代码。此外,由于 Android 的性质 - 如果他们签署了该软件,他们就必须是分发该软件的人。如果它是由其他人签名的,则您不能将其放入市场。

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

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

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

我对这方面了解很多,因为我曾经在 RealVNC 工作过。我们与所有主要 Android 手机供应商合作,以访问这些签名级 API。我无法过分强调实现这一目标所需的许多、许多人年的努力(商业上和技术上)。一些 OEM 已经公开了这项工作 - 例如4.

I 不工作我不再在 RealVNC 工作了,所以我从广告他们的软件中得不到任何好处。但如果你真的真的希望能够在多个 Android 设备上捕获屏幕,您可能希望与他们联系以重新使用他们的远程控制服务或 Android VNC SDK5。它不是开源的,所以你应该期待付费,相信我,考虑到与所有这些 Android OEM 合作所付出的巨大努力,这是足够公平的。

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

Over USB

另一种选择 -adb通过 USB 侦听调试连接的守护进程比普通应用程序具有稍多的权限,这就是它能够抓取屏幕的原因(您可以使用ddms工具)。如果您能够使用以下命令运行任何命令adb那么您也可以获得这些权限(根据之前链接的 android-screenshot-library)。

为Android开源项目做出贡献

最终这个问题让我灰飞烟灭,我离开了,不再尝试从 Android 手机中榨取像素。

不过,在我离开 RealVNC 之前,我们再次尝试将这些 API 贡献给 Android 开源项目。这次我们得到了更积极的反应6。简而言之,有人认为我们的安全方法几乎是正确的,但图形系统过于混乱而无法接受我们的补丁。好消息是图形系统不再陷入混乱 - 事实上它现在已经有了captureScreenAPI 这意味着无需对图形系统进行任何更改。因此,有可能围绕这个 API 向 AOSP 提交一个新的安全机制,最终解决这个问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

  • 如何获取之前的碎片?

    为了在我的应用程序中重用某些片段 我需要知道哪个片段是返回堆栈上的第二个片段 为了做到这一点 我正在使用getFragmentManager getFragments 显示以下错误 但有效 FragmentManager getFragme
  • 使用 google Directions API 的地图视图绘制方向 - 解码折线

    我正在尝试使用 Google 方向 API 在我的地图视图上显示方向 但我在从 JSON 响应获取数据时遇到困难 我可以获得 级别 和 点 字符串 但无法弄清楚如何将它们解码为地图上的点 任何帮助将非常感激 我有一个类可以为您解码它们 添加
  • 如何强制 Eclipse 将 xml 布局和样式显示为文本?

    我最近升级到带有 ADT 20 0 3 的 Eclipse 4 2 Juno 如果我查看旧项目中的布局或样式 Eclipse 只会向我显示其适当的基于控件的编辑器 我想编辑语法突出显示的 xml 文本 我没有找到将插件的编辑器切换到此模式的
  • Twitter 登录说明

    我想在 Android 中创建一个 Twitter 应用程序 为此 我想创建一个登录页面并登录到 Twitter 为此 我们需要消费者密钥和消费者密钥 这是什么意思 要创建此登录页面 除了 Twitter 帐户之外 我们还需要其他任何东西吗
  • 通过 WhatsApp 发送消息

    由于我发现了一些较旧的帖子 表明 Whatsapp 不支持此功能 我想知道是否发生了变化 以及是否有办法打开与我通过意图发送的号码进行 Whatsapp 聊天 UPDATE请参阅https faq whatsapp com en andro
  • 自定义选择器活动:SecurityException UID n 无权 content:// uri

    我正在构建一个选择器应用程序来替换本机 Android 共享对话框 它工作正常 除非我尝试通过长按图像 gt 共享图像从 Chrome 共享图像 我发现 Google 没有捕获异常 它崩溃了 所以我可以通过 Logcat 查看它 在 Goo
  • 带操作按钮的颤动本地通知

    我在我的 flutter 项目中尝试了 flutter 本地通知插件 它在简单通知上工作正常 但我需要带有操作按钮的通知功能 请帮助我或建议我实现此功能 不幸的是 flutter local notifications 插件尚不支持操作按钮
  • 如何在React Native Android中获取响应头?

    您好 我想在获取 POST 请求后获取响应标头 我尝试调试看看里面有什么response with console log response 我可以从以下位置获取响应机构responseData但我不知道如何获取标题 我想同时获得标题和正文
  • android EditText 输入类型用于 StreetNumber 字段

    我试图在地址对话框的 streetNumber 字段中选择正确的 inputType 我想先显示数字键盘 然后让用户输入字母字符 对于一些非常特殊的情况 更接近这个的是 inputType datetime 但这不允许输入字母字符 那么如何
  • 如何在手机缓存中保存用户名和密码

    我有一个用户登录应用程序 它需要用户的电子邮件和密码 我想将电子邮件和密码保存在手机缓存中 以便用户不必再次输入 有什么办法可以将数据保存在Android缓存中吗 我认为你需要使用SharedPreference用于在设备中使用应用程序时保
  • Android onChange 事件未在 android 5 (Lollipop) 上的 chrome 历史记录的 contentObserver 中触发

    我注意到我的 chrome 历史记录和书签的 contentObservers 在 android lolipop 上不再触发 该代码在旧版本的 android 上完美运行 无论 chrome 版本如何 但在 Lollipop 上它不再运行
  • Android 应用程序中的 Eszett (ß)

    我的 res layout activity 文件中的德语 字符在我的应用程序中自动转换为 ss 即使我将语言和键盘设置为德语 它仍然不会显示 Android 中可以显示 吗 edit
  • 使用 SQLITE 按最近的纬度和经度坐标排序

    我必须获得一个 SQLite SQL 语句 以便在给定初始位置的情况下按最近的纬度和经度坐标进行排序 这是我在 sqlite 数据库中的表的例句 SELECT id name lat lng FROM items EXAMPLE RESUL
  • 如何在 Viewpager 中禁用预加载下一页? [复制]

    这个问题在这里已经有答案了 如何在 Viewpager 中禁用页面预加载 I tried viewPager setOffscreenPageLimit 0 但它不起作用 用这个viewPager setOffscreenPageLimit
  • 哪些 Flutter 插件或功能可以利用外部 iOS/Android 显示器来显示与主显示器不同的内容

    我正在构建一个跨平台应用程序 需要在外部显示器上显示不同的视图 通常通过连接到 LCD 投影仪的 HDMI 适配器电缆连接 Flutter 是否能够在内置的外部显示器上显示不同的屏幕 在现有的 Flutter 插件中还是使用现有的 Flut
  • 如何在android asynctask中使用inputstream作为参数?

    我正在制作一个 Android 应用程序来跟踪股票详细信息 我将通过 csv 雅虎财经 检索数据 据我所知 在android 4 0中 网络连接无法在主线程上完成 因此 我将使用 asynctask 来建立连接 但是 我在参数方面遇到了一些
  • Android:RecyclerView 不显示片段中的列表项

    有人可以帮我尝试让我的 RecyclerView 出现吗 如果我不在片段中实现它 就会出现这种情况 然而 当我尝试将其实现到片段中时 CarFront 中的其他 XML 代码与 RecyclerView 分开显示 我的日志中收到此错误 E
  • 如何在基本活动中使用 ViewBinding 的抽象?

    我正在创建一个基类 以便子级的所有绑定都将设置在基类中 我已经做到了这一点 abstract class BaseActivity2 b AppCompatActivity private var viewBinding B null pr
  • 尝试将 SQLite DB 从数据复制到 SD 卡

    我正在使用以下代码 该代码发布在 Stack Overflow 上的某个位置 并根据我的目的进行了修改 try File sd Environment getExternalStorageDirectory File data Enviro
  • 单元测试时 Android Studio 2.0 中测试状态终止且没有任何失败消息

    Issue 我昨天在 Ubuntu 上从 1 5 升级到了 Android Studio 2 0 当我在 Android Studio 2 0 中进行单元测试时 即使所有测试都已通过 它也会显示 终止测试 状态 有时它只显示部分测试通过 我

随机推荐

  • map[string]*type“无效的内存地址或零指针取消引用”

    当我尝试访问结构字段时出现错误 无效的内存地址或 nil 指针取消引用 gdreport main go 30 0x1e6 我不知道这个错误 这是我的代码 var strPtr string var findingId string str
  • 根据rtl或ltr语言自动设置方向和文本对齐

    我们可以设置direction财产为body指示方向的标签rtl to ltr 同样我们可以设置text align各个元素的属性 有没有什么方法可以最小化或集中编码工作来设计一个可以同时支持这两种功能的应用程序LTR 英语 和RTL 阿拉
  • Drive API - 下载/上传 sql 数据库

    我目前正在下载我使用驱动 API 上传的 SQL 数据库 肯定有一个备份 但是当我尝试打开该文件时 我收到一条错误消息 指出该文件无法打开 EDIT 我解决了上面的问题 现在我想最终上传和下载sql数据库 我在互联网上找到了可以下载和上传的
  • 一种在Python中从数据对创建簇的算法

    我正在寻找一种智能算法或Pythonic 方法来从数据对创建集群 输入数据的结构如下 productA ProductB productB ProductC productC ProductD productA ProductD produ
  • Bokeh DataTable 在触发(“更改”)后不会更新,无需单击标题

    散景版本 0 10 蟒蛇 3 4 木星 4 x 目标 创建一个仅显示从散点图中选择的数据的表 问题 DataTable 仅在单击后才刷新 尽管 s2 trigger change 在 Bokeh 网站的其他示例中 一 绘图将使用此技术更新另
  • justify-content:第一个和最后一个项目之间的间距也相同[重复]

    这个问题在这里已经有答案了 我想使用 flexbox 来设置一个简单的弹性 网格 container display flex flex wrap wrap justify content space between but 我希望外边距等
  • .xcconfig?如何设置环境变量

    我是 Xcode 新手 在过去的两天里 我试图弄清楚如何在访问网络服务的 iPhone 上测试我的应用程序 在模拟器上 我可以使用硬编码的 localhost 变量 但我不想硬编码所有配置设置 我正在使用 Swift Xcode 6 但我认
  • 数组初始化之间的差异

    请参阅以下声明 char a 5 jgkl let s call this Statement A char b jhdfjnfnsfnnkjdf let s call this Statement B and yes i know thi
  • 基于相似单词序列的字符串聚类

    我正在寻找一种有效的方法 根据相似单词序列的出现将大约 1000 万个字符串聚类成簇 考虑一个字符串列表 例如 the fruit hut number one the ice cre am shop number one jim s ta
  • JPEG: YCrCb <-> RGB 转换精度

    我已经使用 JPEG 转换公式实现了 rgb gt ycrcb 和 ycrcb gt rgb 转换 http www w3 org Graphics JPEG jfif3 pdf 同样在 http en wikipedia org wiki
  • webview 未在 javafx 中打开弹出窗口

    我正在尝试使用 javafx 在 webview 中打开网页 单击超链接时 此网页将打开一个新的弹出窗口 我如何打开新的弹出窗口 当尝试在默认网络浏览器 如 chrome IE 中打开相同的网页时 它们会打开弹出窗口 为了创建弹出窗口 我使
  • PHP:将接口作为参数传递

    在 NET 中 我将接口作为类方法中的参数传递 我想知道PHP可以实现吗 我的场景是我有一个处理 mqin 系统功能的类 现在我想将通知系统与其集成 我想将通知系统分开 因为它不是系统的主要部分 而且我可以在其他地方使用它 如果我有以下结构
  • ORA-00913 值太多

    我有这个查询 INSERT INTO hist museum SELECT from of owner museum al JOIN SELECT vd city data id FROM of owner city data vd WHE
  • 如何在鼠标移动窗口时接收通知?

    I tried setFrame display and windowDidMove 但移动窗口时不会发送它们 如果你想追踪NSWindow现场搬家 默认情况下是不可能的 您必须自己完成 可以在以下情况下收到通知NSWindow开始拖动 移
  • 全屏显示图像

    我正在研究Windows Phone 8 app并在 XAML 中有一个像这样的图像视图
  • Redis 缓存与直接使用内存

    我还没有使用过Redis 但我听说过它并计划尝试使用它来缓存数据 我听说Redis使用内存作为缓存存储数据库 既然我可以使用对象或字典来存储数据 那么 Redis 的意义何在 像这样 var cache key key 使用Redis有什么
  • IE8 和 jQuery 空指针

    我正在构建一个带有一些动画翻转的网站 我在其中对背景图像进行动画处理以提供颜色淡入淡出效果 它在 FF3 Safari chrome 中工作正常 但 IE8 会抛出 未定义为 null 或不是对象 错误 全文 Message undefin
  • CListCtrl 中的垂直滚动条

    我在图标视图中使用 CListCtrl 但它水平滚动 1 3 5 7 gt 2 4 6 8 gt 我宁愿它水平滚动 1 2 3 4 5 6 V V 有没有办法做到这一点 将设计器中的对齐方式从左更改为上
  • Drupal 到 Drupal 迁移

    我正在尝试迁移主机 但在从一个 Drupal 实例迁移到另一个实例时遇到问题 我有一个多站点安装 我正在尝试维护文件 代码以及数据库 我已将 Drupal 实例中的文件从旧服务器传输到新服务器 我已经通过 phpmyadmin 导出了数据库
  • 如何在没有 root 权限的情况下以编程方式截取其他应用程序的屏幕截图,例如 Screenshot UX Trial?

    如何在没有 root 权限的情况下以编程方式截取其他应用程序的屏幕截图 例如 Screenshot UX Trial 我知道我可以在我的应用程序中捕获根视图的位图 但是当我的应用程序在后台运行时 我无法获取其他应用程序的根视图 bitmap