如何通过后台服务随时截取设备屏幕?现有代码仅能捕获当前Activity截图
后台服务获取设备全局截图实现方案
你当前使用的DrawingCache方案仅能捕获当前应用自身Activity的视图,受安卓沙箱机制限制,普通应用无法直接跨进程读取其他App或系统界面的渲染内容,以下是不同场景下的可行实现方案:
方案1:非Root设备通用方案(安卓5.0+,官方合规)
使用系统提供的MediaProjection屏幕投射API,这是目前普通第三方应用实现全局截图的唯一合规路径:
- 首次使用必须向用户发起授权请求,调用
MediaProjectionManager.createScreenCaptureIntent()拉起系统授权弹窗,用户手动同意屏幕录制权限后,后续后台服务可随时触发截图,无需重复授权 - 核心实现逻辑:
- 前台页面拿到用户授权返回的
resultCode和resultData后,传递给后台运行的Service - 服务中通过
MediaProjectionManager.getMediaProjection(resultCode, resultData)获取MediaProjection实例 - 创建对应屏幕分辨率的
ImageReader实例,将其Surface传入MediaProjection.createVirtualDisplay()创建虚拟显示通道,屏幕内容会自动渲染到ImageReader中 - 需要截图时直接从ImageReader中获取最新的
Image对象,转换为Bitmap即可得到全屏截图
- 前台页面拿到用户授权返回的
- 注意事项:
- 安卓10及以上版本,调用该能力时服务必须是前台服务,否则系统会直接抛出权限异常
- 企业定制设备场景下,可将应用设置为设备所有者(Device Owner),无需用户手动授权即可直接调用屏幕捕获能力
- 用户可在系统设置中随时撤销屏幕录制授权,撤销后需要重新走授权流程
方案2:Root/系统签名应用方案
如果你的应用拥有Root权限,或者是持有系统签名、预装在系统分区的系统应用,可以绕过用户授权流程直接后台截图:
- 申请系统级
READ_FRAME_BUFFER权限后,可直接调用系统隐藏APISurfaceControl.screenshot(),传入目标屏幕的宽高参数即可直接获取全屏Bitmap,随时可在后台调用 - 安卓4.4及以下老旧版本,可通过直接读取帧缓冲设备节点
/dev/graphics/fb0获取屏幕原始像素数据,该方案在新版本安卓上受SELinux规则限制已完全失效
不可行方案说明
- 基于View缓存的截图逻辑:仅能访问当前应用进程内的视图对象,其他应用的窗口运行在独立进程中,无法通过该方式获取
- 无障碍服务:仅能获取当前界面的控件节点信息,无法读取屏幕实际渲染的像素数据,无法生成截图
- 无感知后台偷跑截图:安卓6.0之后系统已经封堵了所有未授权全局截图的漏洞,普通第三方应用不可能在用户完全不知情的情况下捕获屏幕内容,属于系统级隐私保护限制。
内容的提问来源于stack exchange,提问作者Domenico
相关产品推荐
相关产品推荐

