Protección de audio en segundo plano

A partir de Android 17, el framework de audio aplica restricciones a las interacciones de audio en segundo plano, incluidas la reproducción de audio, las solicitudes de foco de audio y las APIs de cambio de volumen para garantizar que el usuario inicie estos cambios de forma intencional.

Todas las apps que se ejecutan en Android 17 y que tienen estas interacciones de audio en segundo plano deben tener una actividad visible o deben ejecutar un servicio en primer plano que no sea del tipo SHORT_SERVICE. Esto se aplica independientemente de si la app se orienta al nivel de API 37 o no.

Si una app se orienta a Android 17 (nivel de API 37), hay una restricción adicional. Si la app se ejecuta en segundo plano, debe ejecutar un servicio en primer plano que tenga capacidades de mientras está en uso (WIU). (Se otorgan capacidades de WIU a un servicio en primer plano si se inicia en respuesta a una operación iniciada por el usuario o mientras la app está visible para el usuario). Sin embargo, se exime el requisito de las capacidades de WIU si se otorgó a la app el permiso de alarma exacta y esta realiza cambios en las transmisiones de audio que tienen el atributo USAGE_ALARM.

Si la app intenta llamar a las APIs de audio mientras no se encuentra en un ciclo de vida válido, las APIs de reproducción de audio y cambio de volumen fallan de forma silenciosa sin arrojar una excepción ni proporcionar un mensaje de error. La API de foco de audio falla con el código de resultado AUDIOFOCUS_REQUEST_FAILED.

Por qué realizamos este cambio

El objetivo de introducir estas restricciones es reducir las experiencias de audio en segundo plano con errores no intencionales. Aquí encontrarás algunos ejemplos:

  • Las apps que reproducen audio sin un servicio en primer plano se pueden congelar. Cuando la app se descongela, reanuda inesperadamente la reproducción de audio, posiblemente horas más tarde.
  • Las apps que reproducen audio sin un servicio en primer plano enfrentaban varias restricciones de ejecución, lo que generaba un rendimiento de audio entrecortado.
  • La reproducción se desvincula del ciclo de vida de la actividad, lo que podría provocar una filtración de la sesión de reproducción o de los eventos de enfoque que continúan sin que el usuario pueda detener la reproducción.

Recomendamos a los desarrolladores que prueben sus apps y proporcionen comentarios sobre el cambio de comportamiento si hay casos de uso de audio intencionales que se ven afectados de forma negativa. Informa cualquier problema con esta herramienta de seguimiento de errores de compatibilidad de apps de Android 17.

Identifica los casos de uso de audio en segundo plano afectados

Audita la implementación de la reproducción de audio y determina si tu app tiene la intención de proporcionar una funcionalidad de interacción de audio en segundo plano, incluso en circunstancias condicionales.

Si tu app solo pretende reproducir audio o utilizar APIs de audio mientras muestra una actividad visible para el usuario, incluido el uso del modo de pantalla en pantalla (PIP), no se verá afectada por ninguno de estos cambios.

Si tu app proporciona funcionalidad de VOIP, incluidas las apps de videollamadas, ya debe cumplir con los requisitos que se presentan para la reproducción (por lo general, a través del uso de las APIs de telecomunicaciones recomendadas) para grabar audio correctamente y, por lo tanto, es poco probable que se vea afectada.

Si tu app tiene la intención de continuar con la reproducción de audio mientras la pantalla está apagada o mientras la actividad no está visible, lo que se ve con mayor frecuencia en las apps de transmisión de música o de podcasts, se considera que tu app proporciona la funcionalidad de audio en segundo plano y debe cumplir con los nuevos requisitos.

Situaciones de audio en segundo plano que probablemente se verán afectadas

Si tu app no sigue el modelo de continuar una interacción de audio iniciada mientras estaba abierta o en respuesta a un activador explícito del usuario, es probable que se suprima su funcionalidad de forma silenciosa.

Por ejemplo, si tu app inicia un servicio en primer plano en respuesta a BOOT_COMPLETE y, luego, intenta interactuar con el audio, se suprimirá.

Prácticas recomendadas para el audio en segundo plano para mitigar el impacto

  • Usa el componente MediaSessionService de la biblioteca de Jetpack media3 para administrar la reproducción de audio en segundo plano.

    Si lo haces, es probable que tu app no se vea afectada por el endurecimiento en segundo plano, ya que la biblioteca ayuda a administrar el ciclo de vida de la reproducción.

  • Si no aprovechas la biblioteca de media3, deberás iniciar manualmente un FGS de mediaPlayback. Inicia siempre un servicio en primer plano mientras la app está en primer plano si es posible que se reproduzca audio en segundo plano.

    Por ejemplo, si tu app es una app de transmisión de video, que suele ser solo en primer plano, pero contiene una indicación visual del usuario para seguir reproduciendo contenido mientras la pantalla está apagada, cuando se produzca el activador de reproducción iniciado por el usuario, tu app debería iniciar un servicio en primer plano.

    De esta manera, se garantiza que el servicio en primer plano se inicie con las capacidades de WIU.

  • Mantén el FGS de mediaPlayback activo durante las fallas transitorias de menos de 10 minutos.

    Si tu app tiene una falla transitoria, como un problema con el almacenamiento en búfer debido a la actividad de red, o si hay una interrupción transitoria esperada, como AUDIOFOCUS_LOSS_TRANSIENT, el intent de reproducción debería continuar. Por lo tanto, tu FGS debería permanecer activo.

  • Detén el servicio en primer plano al final de la reproducción y reiníciala solo si el usuario la reanuda de forma explícita.

    En el caso de una señal permanente para finalizar la reproducción (por ejemplo, el contenido se completa sin reproducción automática, un AUDIOFOCUS_LOSS, un evento de pausa de la UMO o un evento de tecla multimedia) o una falla irrecuperable, tu app debe detener la interacción de audio, detener el servicio en primer plano y finalizar la sesión multimedia. Todo esto corresponde a la concepción del usuario de "finalizar" la interacción de audio en segundo plano deseada. Después de hacer esto, tu app ya no tendrá capacidades de interacción de audio en segundo plano.

    Posteriormente, si el usuario reanuda la reproducción de forma explícita, por ejemplo, a través de la IU de tu app o del botón de reproducción del objeto multimedia universal, debería volver el intent para iniciar la reproducción de audio, lo que generará un FGS recién iniciado.

  • Prueba el comportamiento de la reproducción de audio con los comandos de adb shell.

Prueba los cambios

Puedes probar el cumplimiento de tu app en dispositivos que ejecuten Android 17 o versiones posteriores (a partir de la versión beta 3) con el siguiente comando de ADB:

adb shell cmd audio set-enable-hardening <enable|disable|throw>

Este comando tiene las siguientes opciones:

  • enable: Habilita todas las restricciones de endurecimiento de audio para todas las apps. El requisito para los servicios en primer plano de WIU se aplica independientemente de si una app se orienta a Android 17 (nivel de API 37). Además, el requisito se aplica incluso si la app realiza cambios en los flujos de alarmas y tiene el permiso de alarma exacta.

  • disable: Inhabilita todas las restricciones de endurecimiento de audio.

  • throw: Habilita todas las restricciones de endurecimiento de audio para todas las apps, como enable. Además, este parámetro habilita las fallas ruidosas, lo que arroja IllegalStateException para las interacciones de volumen y enfoque. Para la reproducción de audio, el método de escritura devuelve de forma persistente un código de error. En los modos de reproducción sin escrituras explícitas, la app falla.

Usa adb dumpsys audio o logcat para identificar si la app encontró fallas silenciosas debido a la aplicación de medidas de endurecimiento de audio. Si es así, habrá una entrada con el prefijo AudioHardening y el nombre de tu paquete. Si el mensaje contiene level: full, significa que tu app está ejecutando un servicio en primer plano, pero el servicio no tiene la capacidad de uso en primer plano. Si el mensaje contiene level: partial, tu app no está ejecutando un servicio en primer plano.

Información sobre los FGS con la capacidad de mientras está en uso

Por lo general, los servicios en primer plano (FGS) se deben iniciar mientras una app está en primer plano para extender las operaciones iniciadas por el usuario. En algunos casos específicos, se permite que las apps inicien un servicio en primer plano mientras se ejecutan en segundo plano. Sin embargo, por lo general, a estos servicios en primer plano no se les otorgan capacidades de mientras está en uso (WIU).

La WIU actúa como una puerta de seguridad: evita que los FGS iniciados en segundo plano participen en ciertos comportamientos sensibles cuando el usuario podría no estar al tanto de la actividad de la app. Impide que la app acceda a datos sensibles, como la ubicación, la cámara o el micrófono, y, a partir de Android 17, también bloquea las APIs de audio que suelen requerir un contexto de IU visible.

Aquí tienes una referencia útil:

  • FGS estándar: Los servicios que se inician mientras la app está visible o se le otorga la capacidad de iniciar actividades en segundo plano reciben acceso de WIU.
  • FGS iniciados en segundo plano (BFSL): La mayoría no otorga acceso de WIU. Las excepciones principales que otorgan WIU son las interacciones que implican una intención explícita del usuario, por ejemplo, los clics en notificaciones, las interacciones con widgets o los eventos de teclas multimedia desde un dispositivo externo.
  • FGS iniciado por el sistema: Se otorga acceso de WIU a los servicios en primer plano si se inician por delegación del servidor del sistema (por ejemplo, desde la biblioteca de Jetpack de Telecom) o por vinculaciones del sistema que representan un estado elevado en primer plano para realizar una funcionalidad dedicada (como para un VoiceInteractionService).

Obtén más información en Restricciones para iniciar un servicio en primer plano desde el segundo plano.

Lista completa de las APIs de audio afectadas

Función de audio

Resultado

APIs afectadas

Reproducción de audio

La reproducción se silencia.

No hay excepciones ni mensajes de error proporcionados por ninguna API.

AudioTrack.write()

(NDK) AAudioStream_write

OpenSL ES para Android

Cualquier biblioteca de contenido multimedia del cliente que administre la reproducción, como media3, Exoplayer y Oboe, también podría verse afectada.

Solicitud de foco de audio

Se muestra AUDIOFOCUS_REQUEST_FAILED

No tiene efecto en la reproducción de audio de otras apps, no se adquiere el foco

AudioManager.requestAudioFocus()

APIs de volumen y modo de timbre

No tiene efecto en el modo de timbre ni en el volumen (la llamada de método se ignora de forma silenciosa).

No hay excepciones ni mensajes de error proporcionados por ninguna API.

AudioManager.setStreamVolume()

AudioManager.setStreamMute()

AudioManager.adjustStreamVolume()

AudioManager.adjustVolume()

AudioManager.adjustSuggestedStreamVolume()

AudioManager.setRingerMode()