应用可以录制其他应用正在播放的视频或音频。此类应用必须正确处理 MediaProjection 令牌。本页面介绍了具体的操作方法。此外,还展示了设备管理员如何停用录制任何屏幕快照的功能,以及音频应用如何阻止其他应用录制其播放的内容。
如何处理 MediaProjection 令牌
MediaProjection API 允许应用获取 MediaProjection 令牌,从而获得一次性访问权限来捕获屏幕内容或音频。Android OS 会先征求用户同意,然后再向您的应用授予令牌。
操作系统会在“快捷设置”界面中显示有效的 MediaProjection 令牌,并允许用户随时撤消对令牌的访问权限。发生这种情况时,与会话关联的虚拟显示屏或音频串流会停止接收媒体串流。您的应用必须做出适当响应,否则它将继续录制无声的音频或黑屏视频流。
如需处理令牌丢失的情况,请使用 registerCallback 方法在 MediaProjection 实例上注册回调,并在调用 onStop 方法时停止录制。
如需了解详情,请参阅媒体投影。
拍摄视频
您可以使用 DevicePolicyManager 阻止屏幕录制。对于企业账号 (Android for Work),管理员可以使用 setScreenCaptureDisabled 方法停用工作资料的助理数据收集功能。
在不使用应用的情况下管理 Android 设备 Codelab 介绍了如何禁止截屏。
录制音频播放内容
AudioPlaybackCapture API 是在 Android 10 中引入的。此 API 使应用能够复制其他应用正在播放的音频。此功能类似于屏幕截图,但针对的是音频。主要应用场景是让在线影音应用能够捕获游戏当前播放的音频。
请注意,AudioPlaybackCapture API 不会影响其音频正在由其他应用捕获的应用的延迟时间。
构建捕获应用
出于安全和隐私方面的考虑,回放捕获功能存在一些限制。 为了能够捕获音频,应用必须满足以下要求:
- 应用必须具有
RECORD_AUDIO权限。 - 应用必须调出
MediaProjectionManager.createScreenCaptureIntent()显示的提示,并且用户必须批准该提示。 - 捕获音频的应用和播放音频的应用必须使用同一用户个人资料。
如需从其他应用捕获音频,您的应用必须构建 AudioRecord 对象并向其添加 AudioPlaybackCaptureConfiguration。下载步骤如下:
- 调用
AudioPlaybackCaptureConfiguration.Builder.build()以构建AudioPlaybackCaptureConfiguration。 - 通过调用
setAudioPlaybackCaptureConfig将配置传递给AudioRecord。
控制音频捕获
您的应用可以控制其可录制的内容类型,以及哪些其他类型的应用可以录制其自己的播放内容。
按音频内容限制捕获
应用可以使用以下方法来限制其可以捕获的音频:
- 将
AUDIO_USAGE传递给 AudioPlaybackCaptureConfiguration.Builder.addMatchingUsage(),以允许捕获特定用途。多次调用该方法可指定多个用法。 - 将
AUDIO_USAGE传递给 AudioPlaybackCaptureConfiguration.excludeUsage(),以禁止捕获该用途。多次调用该方法可指定多个用法。 - 将 UID 传递给 AudioPlaybackCaptureConfiguration.addMatchingUid(),以便仅捕获具有特定 UID 的应用。多次调用该方法可指定多个 UID。
- 将 UID 传递给 AudioPlaybackCaptureConfiguration.excludeUid(),以禁止捕获该 UID。多次调用该方法可指定多个 UID。
请注意,您不能同时使用 addMatchingUsage() 和 excludeUsage() 方法。您必须选择其中之一。同样,您不能同时使用 addMatchingUid() 和 excludeUid()。
限制其他应用进行捕获
您可以配置应用,以防止其他应用捕获其音频。 只有在应用满足以下要求时,系统才能捕获来自该应用的音频:
用法
生成音频的播放器必须将其用途设置为 USAGE_MEDIA、USAGE_GAME 或 USAGE_UNKNOWN。
捕获政策
播放器的捕获政策必须为 AudioAttributes.ALLOW_CAPTURE_BY_ALL,这样其他应用才能捕获播放内容。此操作可以通过一些方法完成:
- 如需为所有播放器启用捕获功能,请在应用的
manifest.xml文件中添加android:allowAudioPlaybackCapture="true"。 - 您还可以通过调用
AudioManager.setAllowedCapturePolicy(AudioAttributes.ALLOW_CAPTURE_BY_ALL)为所有播放器启用捕获功能。 - 您可以在使用
AudioAttributes.Builder.setAllowedCapturePolicy(AudioAttributes.ALLOW_CAPTURE_BY_ALL)构建播放器时,为单个播放器设置该政策。(如果您使用的是AAudio,请调用AAudioStreamBuilder_setAllowedCapturePolicy(AAUDIO_ALLOW_CAPTURE_BY_ALL)。)
如果满足这些前提条件,应用就可以捕获播放器生成的任何音频。
停用系统捕获
上述允许捕获的保护措施仅适用于应用。默认情况下,Android 系统组件可以捕获播放内容。
其中许多组件由 Android 供应商自定义,并支持无障碍功能和字幕等功能。因此,建议应用允许系统捕获其播放内容。在极少数情况下,如果您不希望系统捕获应用的播放内容,请将捕获政策设置为 ALLOW_CAPTURE_BY_NONE。
在运行时设置政策
您可以在应用运行时调用 AudioManager.setAllowedCapturePolicy() 来更改捕获政策。如果您在调用该方法时 MediaPlayer 或 AudioTrack 正在播放,则音频不会受到影响。您必须关闭并重新打开播放器或轨道,政策更改才会生效。
政策 = 清单 + AudioManager + AudioAttributes
由于可以在多个位置指定捕获政策,因此请务必了解如何确定有效政策。系统始终会应用限制性最强的捕获政策。例如,如果应用的清单包含 setAllowedCapturePolicy="false",则即使 AudioManager#setAllowedCapturePolicy 设置为 ALLOW_CAPTURE_BY_ALL,该应用也绝不允许非系统应用捕获其音频。同样,如果 AudioManager#setAllowedCapturePolicy 设置为 ALLOW_CAPTURE_BY_ALL,清单设置了 setAllowedCapturePolicy="true",但媒体播放器的 AudioAttributes 是使用 AudioAttributes.Builder#setAllowedCapturePolicy(ALLOW_CAPTURE_BY_SYSTEM) 构建的,则非系统应用将无法捕获此媒体播放器。
下表总结了清单属性和有效政策的效果:
| allowAudioPlaybackCapture | ALLOW_CAPTURE_BY_ALL | ALLOW_CAPTURE_BY_SYSTEM | ALLOW_CAPTURE_BY_NONE |
|---|---|---|---|
| true | 任何应用 | 仅限系统 | 无法捕获 |
| false | 仅限系统 | 仅限系统 | 无法捕获 |