应用可以录制其他应用正在播放的视频或音频。此类应用必须正确处理 MediaProjection
令牌。本页面将介绍具体方法。此外,本页面还介绍了设备管理员如何禁用录制任何屏幕快照的功能,以及音频应用如何阻止其他应用录制其播放的内容。
如何处理 MediaProjection
令牌
MediaProjection
API 允许应用获取 MediaProjection
令牌,从而一次性访问屏幕内容或音频。Android 操作系统会在将令牌授予您的应用之前请求用户许可。
操作系统会在“快速设置”界面中显示活跃的 MediaProjection
令牌,并允许用户随时撤销对令牌的访问。发生这种情况时,与会话关联的虚拟显示屏或音频流将停止接收媒体流。您的应用必须做出适当响应,否则它将继续录制无声音频或黑屏视频流。
要处理令牌丢失,请使用 registerCallback
方法在 MediaProjection
实例上注册回调,并在调用 onStop
方法时停止录制。
如需了解详情,请参阅媒体投影。
捕获视频
请参阅 ScreenCapture 示例应用,了解如何使用 Media Projection API 实时捕获设备屏幕并在 SurfaceView 上显示。
您可以使用 DevicePolicyManager
来阻止屏幕录制。对于企业账号 (Android for Work),管理员可以使用 setScreenCaptureDisabled 方法为工作资料禁用助理数据收集。
Codelab 在没有应用的情况下管理 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 正在播放,则音频不受影响。您必须关闭并重新打开播放器或轨道,政策更改才能生效。
政策 = manifest + AudioManager + AudioAttributes
由于捕获政策可以在多个地方指定,因此了解有效政策是如何确定的非常重要。始终应用最严格的捕获政策。例如,如果应用的 manifest 中包含 setAllowedCapturePolicy="false"
,则即使 AudioManager#setAllowedCapturePolicy
设置为 ALLOW_CAPTURE_BY_ALL
,该应用也永远不会允许非系统应用捕获其音频。同样,如果 AudioManager#setAllowedCapturePolicy
设置为 ALLOW_CAPTURE_BY_ALL
,并且 manifest 设置了 setAllowedCapturePolicy="true"
,但媒体播放器的 AudioAttributes
是使用 AudioAttributes.Builder#setAllowedCapturePolicy(ALLOW_CAPTURE_BY_SYSTEM)
构建的,那么此媒体播放器将无法被非系统应用捕获。
下表总结了 manifest 属性和有效政策的影响
allowAudioPlaybackCapture | ALLOW_CAPTURE_BY_ALL | ALLOW_CAPTURE_BY_SYSTEM | ALLOW_CAPTURE_BY_NONE |
---|---|---|---|
true | 任何应用 | 仅限系统 | 无捕获 |
false | 仅限系统 | 仅限系统 | 无捕获 |