应用可以录制从其他应用播放的视频或音频。此类应用必须正确处理MediaProjection
令牌。此页面介绍了如何操作。它还展示了设备管理员如何禁用录制任何屏幕快照的功能,以及音频应用如何阻止其他应用录制其播放的内容。
如何处理MediaProjection
令牌
MediaProjection
API 允许应用获取MediaProjection
令牌,该令牌使它们可以一次性访问捕获屏幕内容或音频。Android 操作系统会在向您的应用授予令牌之前征求用户的许可。
操作系统在快速设置 UI 中显示活动的MediaProjection
令牌,并允许用户随时撤回对令牌的访问权限。发生这种情况时,与会话关联的虚拟显示或音频流将停止接收媒体流。您的应用必须做出相应的响应,否则它将继续录制音频静音或黑色视频流。
要处理令牌丢失,请使用registerCallback
方法在MediaProjection
实例上注册回调,并在调用onStop
方法时停止录制。
有关更多信息,请参阅媒体投射。
捕获视频
请参阅ScreenCapture 示例应用,了解如何使用媒体投射 API 实时捕获设备屏幕并在 SurfaceView 上显示。
您可以使用DevicePolicyManager
来阻止屏幕录制。对于企业帐户(Android for Work),管理员可以使用setScreenCaptureDisabled 方法禁用工作配置文件的助理数据收集。
代码实验室无需应用即可管理 Android 设备展示了如何禁止屏幕截图。
捕获音频播放
Android 10 中引入了AudioPlaybackCapture API。此 API 使应用能够复制其他应用正在播放的音频。此功能类似于屏幕捕获,但适用于音频。主要用例是希望捕获游戏正在播放的音频的流媒体应用。
请注意,AudioPlaybackCapture API 不会影响音频被捕获的应用的延迟。
构建捕获应用
出于安全和隐私考虑,播放捕获施加了一些限制。为了能够捕获音频,应用必须满足以下要求
- 应用必须具有
RECORD_AUDIO
权限。 - 应用必须显示
MediaProjectionManager.createScreenCaptureIntent()
显示的提示,并且用户必须批准它。 - 捕获和播放应用必须位于同一用户配置文件中。
要捕获另一个应用的音频,您的应用必须构建一个AudioRecord
对象并在其中添加一个AudioPlaybackCaptureConfiguration
。请按照以下步骤操作
- 调用
AudioPlaybackCaptureConfiguration.Builder.build()
以构建AudioPlaybackCaptureConfiguration
。 - 通过调用
setAudioPlaybackCaptureConfig
将配置传递给AudioRecord
。
控制音频捕获
您的应用可以控制其可以录制的内容类型以及其他类型的应用可以录制其自己的播放内容。
通过音频内容限制捕获
应用可以通过使用以下方法限制其可以捕获的音频
- 将
AUDIO_USAGE
传递给AudioPlaybackCaptureConfiguration.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 | 仅限系统 | 仅限系统 | 不捕获 |