应用可以录制从其他应用播放的视频或音频。此类应用必须正确处理 MediaProjection 令牌。本页将介绍具体的操作方法。该文档还介绍了设备管理员如何停用录制任何屏幕快照的功能,以及音频应用如何阻止其他应用录制其播放的内容。
如何处理 MediaProjection 令牌
借助 MediaProjection API,应用可以获取 MediaProjection 令牌,从而获得一次性访问权限来捕获屏幕内容或音频。Android OS 会在向您的应用授予令牌之前征求用户的许可。
操作系统会在“快捷设置”界面中显示有效的 MediaProjection 令牌,并允许用户随时撤消对令牌的访问权限。发生这种情况时,与会话关联的虚拟显示屏或音频流会停止接收媒体流。您的应用必须做出适当的响应,否则会继续录制无声音频或黑色视频流。
如需处理令牌丢失的情况,请使用 registerCallback 方法在 MediaProjection 实例上注册回调,并在调用 onStop 方法时停止录制。
如需了解详情,请参阅媒体投屏。
拍摄视频
您可以使用 DevicePolicyManager 防止录制屏幕。对于企业账号 (Android for Work),管理员可以使用 setScreenCaptureDisabled 方法停用工作资料的助理数据收集功能。
Codelab 在不使用应用的情况下管理 Android 设备介绍了如何禁止截屏。
录制音频播放内容
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 | 仅限系统 | 仅限系统 | 无法捕获 |