Una app puede grabar el video o el audio que se reproduce desde otra app. Estas apps deben controlar el token MediaProjection
correctamente. En esta página, se explica cómo hacerlo. También se muestra cómo un administrador de dispositivos puede inhabilitar la capacidad de grabar instantáneas de pantalla y cómo una app de audio puede evitar que otras apps graben el contenido que reproducen.
Cómo controlar un token MediaProjection
La API de MediaProjection
permite que las apps adquieran un token MediaProjection
que les brinda acceso único para capturar contenido de pantalla o audio. El SO Android le solicita permiso al usuario antes de otorgar el token a tu app.
El SO muestra los tokens MediaProjection
activos en la IU de Configuración rápida y permite que los usuarios retiren el acceso a un token en cualquier momento. Cuando esto sucede, las pantallas virtuales o las transmisiones de audio asociadas con la sesión dejan de recibir transmisiones multimedia. Tu app debe responder de forma adecuada; de lo contrario, seguirá grabando silencio de audio o una transmisión de video en negro.
Para controlar la pérdida de un token, registra una devolución de llamada en la instancia MediaProjection
con el método registerCallback
y detén la grabación cuando se llame al método onStop
.
Para obtener más información, consulta Proyección de contenido multimedia.
Capturar video
Consulta la app de ejemplo ScreenCapture para aprender a usar la API de Media Projection y capturar la pantalla de un dispositivo en tiempo real y mostrarla en una SurfaceView.
Puedes usar DevicePolicyManager
para evitar la grabación de pantalla. En el caso de las cuentas empresariales (Android for Work), el administrador puede inhabilitar la recopilación de datos del Asistente en el perfil de trabajo con el método setScreenCaptureDisabled.
En el codelab Cómo administrar dispositivos Android sin una app, se muestra cómo prohibir las capturas de pantalla.
Cómo capturar la reproducción de audio
La API de AudioPlaybackCapture se introdujo en Android 10. Esta API otorga a las apps la capacidad de copiar el audio que reproducen otras apps. Esta función es análoga a la captura de pantalla, pero para audio. El caso de uso principal es para las apps de transmisión que desean capturar el audio que reproducen los juegos.
Ten en cuenta que la API de AudioPlaybackCapture no afecta la latencia de la app cuyo audio se está capturando.
Cómo compilar una app de captura
Por cuestiones de seguridad y privacidad, la captura de reproducción impone algunas limitaciones. Para poder capturar audio, una app debe cumplir con estos requisitos:
- La app debe tener el permiso
RECORD_AUDIO
. - La app debe mostrar la solicitud que muestra
MediaProjectionManager.createScreenCaptureIntent()
, y el usuario debe aprobarla. - Las apps de captura y reproducción deben estar en el mismo perfil de usuario.
Para capturar audio de otra app, la app debe crear un objeto AudioRecord
y agregarle un elemento AudioPlaybackCaptureConfiguration
. Sigue estos pasos:
- Llama a
AudioPlaybackCaptureConfiguration.Builder.build()
para compilar unAudioPlaybackCaptureConfiguration
. - Llama a
setAudioPlaybackCaptureConfig
para pasar la configuración aAudioRecord
.
Cómo controlar la captura de audio
Tu app puede controlar qué tipos de contenido puede grabar y qué otros tipos de apps pueden grabar su propia reproducción.
Cómo restringir la captura por contenido de audio
Una app puede limitar el audio que puede capturar mediante estos métodos:
- Inclusión de un
AUDIO_USAGE
en AudioPlaybackCaptureConfiguration.addMatchingUsage() para permitir la captura de un uso específico. Para especificar más de un uso, debes llamar al método varias veces. - Inclusión de un
AUDIO_USAGE
en AudioPlaybackCaptureConfiguration.excludeUsage() para prohibir la captura de ese uso. Para especificar más de un uso, debes llamar al método varias veces. - Inclusión de un UID en AudioPlaybackCaptureConfiguration.addMatchingUid() para capturar solamente las apps con un UID específico. Llama al método varias veces para especificar más de un UID.
- Inclusión de un UID en AudioPlaybackCaptureConfiguration.excludeUid() para prohibir la captura de ese UID. Para especificar más de un UID, debes llamar al método varias veces.
Ten en cuenta que no puedes usar los métodos addMatchingUsage()
y excludeUsage()
juntos. Debes elegir uno u otro. Del mismo modo, no puedes usar addMatchingUid()
y excludeUid()
al mismo tiempo.
Cómo restringir la captura por parte de otras apps
Puedes configurar una app para evitar que otras apps capturen su audio. El audio proveniente de una app solo puede capturarse si la app cumple con los siguientes requisitos:
Uso
El reproductor que produce el audio debe configurar su uso en USAGE_MEDIA
, USAGE_GAME
o USAGE_UNKNOWN
.
Política de captura
La política de captura del reproductor debe ser AudioAttributes.ALLOW_CAPTURE_BY_ALL
, lo que permite que otras apps capturen la reproducción. Esto se puede realizar de diversas maneras:
- Para habilitar la captura en todos los reproductores, incluye
android:allowAudioPlaybackCapture="true"
en el archivomanifest.xml
de la app. - También puedes habilitar la captura en todos los jugadores llamando a
AudioManager.setAllowedCapturePolicy(AudioAttributes.ALLOW_CAPTURE_BY_ALL)
. - Puedes establecer la política en un reproductor individual durante su creación mediante
AudioAttributes.Builder.setAllowedCapturePolicy(AudioAttributes.ALLOW_CAPTURE_BY_ALL)
. (Si usasAAudio
, llama aAAudioStreamBuilder_setAllowedCapturePolicy(AAUDIO_ALLOW_CAPTURE_BY_ALL)
).
Si se cumplen estos requisitos previos, se puede capturar cualquier audio que genere el reproductor.
Cómo inhabilitar la captura del sistema
Las protecciones descritas anteriormente que permiten la captura solo se aplican a apps. Los componentes del sistema Android pueden capturar la reproducción de forma predeterminada.
Muchos de estos componentes son personalizados por proveedores de Android y admiten funciones como la accesibilidad y la generación de subtítulos. Por este motivo, se recomienda que las apps permitan que el sistema capture su reproducción. En el caso excepcional de que no quieras que el sistema capture la reproducción de tu app, establece la política de captura en ALLOW_CAPTURE_BY_NONE
.
Cómo configurar la política en el tiempo de ejecución
Puedes llamar a AudioManager.setAllowedCapturePolicy()
para cambiar la política de captura mientras se ejecuta una app. Si MediaPlayer o AudioTrack se encuentran en reproducción al llamar al método, el audio no se ve afectado. Debes cerrar y volver a abrir el reproductor o la pista para que se implemente el cambio de política.
Política = Manifiesto + AudioManager + AudioAttributes
Como la política de captura puede especificarse en varios lugares, es importante comprender cómo se determina la política vigente.
Siempre se aplica la política de captura más restrictiva. Por ejemplo, una app cuyo manifiesto incluya setAllowedCapturePolicy="false"
nunca permitirá que apps externas al sistema capturen su audio, aunque AudioManager#setAllowedCapturePolicy
se establezca en ALLOW_CAPTURE_BY_ALL
. De forma similar, si se establece AudioManager#setAllowedCapturePolicy
en ALLOW_CAPTURE_BY_ALL
y el manifiesto contiene setAllowedCapturePolicy="true"
, pero el AudioAttributes
del reproductor multimedia se creó con AudioAttributes.Builder#setAllowedCapturePolicy(ALLOW_CAPTURE_BY_SYSTEM)
, las apps externas al sistema no podrán capturar este reproductor multimedia.
En la siguiente tabla, se resumen los efectos del atributo del manifiesto y la política vigente:
allowAudioPlaybackCapture | ALLOW_CAPTURE_BY_ALL | ALLOW_CAPTURE_BY_SYSTEM | ALLOW_CAPTURE_BY_NONE |
---|---|---|---|
true | cualquier app | apps del sistema únicamente | ninguna captura |
false | apps del sistema únicamente | apps del sistema únicamente | ninguna captura |