Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Cómo compartir entradas de audio

Las entradas de audio suelen provenir del micrófono integrado, un micrófono externo o una interfaz de audio conectada al dispositivo. La entrada de audio también puede provenir de una conversación telefónica.

En ocasiones, es posible que dos o más apps quieran "capturar" la misma entrada de audio. Incluso para diferentes tareas. Por ejemplo, algunas apps que reciben audio pueden estar "grabando", como una simple grabadora de voz, mientras que otras pueden estar "escuchando", como el Asistente de Google o un servicio de accesibilidad que responde a comandos por voz.

En cualquier caso, esas apps quieren recibir entradas de audio. En esta página, utilizamos el término "captura" independientemente de si una app está grabando o simplemente escuchando.

Cuando dos o más apps desean capturar audio al mismo tiempo, puede generarse un problema si se entrega la señal de audio de la misma fuente a todas ellas. En esta página, se describe cómo el sistema Android comparte la entrada de audio entre varias apps que capturan audio.

Comportamiento previo a Android 10

Antes de Android 10, solo una app por vez podía capturar el flujo de audio de entrada. Si alguna otra app ya estaba grabando o escuchando audio, tu app podía crear un objeto AudioRecord, pero se mostraba un error cuando se llamaba a AudioRecord.startRecording(), y no se iniciaba la grabación.

Se producía una excepción a esta regla cuando una app privilegiada (como el Asistente de Google o un servicio de accesibilidad) tenía el permiso android.permission.CAPTURE_AUDIO_HOTWORD y utilizaba una fuente de audio de tipo HOTWORD. En ese caso, otra app podía empezar a grabar. Cuando eso sucedía, finalizaba la app privilegiada y la nueva capturaba la entrada.

Se agregó un cambio más en Android 9: solo las apps que se ejecutan en primer plano (o un servicio en primer plano) pueden capturar la entrada de audio. Cuando una app sin un servicio o componente de IU en primer plano empezaba a capturar, la app seguía funcionando, pero recibía silencio, incluso si era la única app que estaba capturando audio en ese momento.

Nuevo comportamiento

El comportamiento anterior era "por orden de llegada". Cuando una app capturaba audio, todas las demás no tenían forma de acceder a la entrada de audio hasta que se detenía la app que estaba capturando.

Android 10 (nivel de API 29) y versiones posteriores impone un esquema de prioridad que puede cambiar el flujo de audio de entrada entre apps mientras se están ejecutando. En la mayoría de los casos, si una nueva app adquiere la entrada de audio, la app que anteriormente estaba capturando seguirá funcionando, pero recibirá silencio. En algunos casos, el sistema puede continuar entregando audio a ambas apps. A continuación, se explican las diferentes situaciones de uso compartido.

Este esquema es similar a la forma en que el foco de audio maneja varias apps que compiten por el uso de la salida de audio. Sin embargo, el foco de audio se administra mediante solicitudes programáticas para obtener y liberar el foco, mientras que el esquema de cambio de entrada aquí descrito se basa en una política de priorización que se aplica automáticamente cada vez que una nueva app comienza a capturar audio.

Para la captura de audio, Android distingue dos tipos de apps:

  • Las apps "comunes", que son las que instala el usuario.
  • Las apps "privilegiadas", que vienen preinstaladas en el dispositivo. Entre estas, se incluyen el Asistente de Google y todos los servicios de accesibilidad.

Además, una app recibe un trato diferente si utiliza una fuente de audio "sensible a la privacidad": CAMCORDER o VOICE_COMMUNICATION.

Las reglas de priorización para usar y compartir la entrada de audio son las siguientes:

  • Las apps privilegiadas tienen mayor prioridad que las comunes.
  • Las apps que tienen IU visibles en primer plano tienen mayor prioridad que las que están en segundo plano.
  • Las apps que capturan audio de una fuente sensible a la privacidad tienen mayor prioridad que las que no lo hacen.
  • Dos apps comunes no pueden capturar audio al mismo tiempo.
  • En algunas situaciones, una app privilegiada puede compartir la entrada de audio con otra app.
  • Si dos apps en segundo plano de la misma prioridad están capturando audio, la última que se inició tiene mayor prioridad.

Situaciones de uso compartido

Cuando dos apps intentan capturar audio, ambas pueden recibir la señal de entrada, o una de ellas puede recibir silencio.

Hay cuatro situaciones principales:

  • Asistente y app común
  • Servicio de accesibilidad y app común
  • Dos apps comunes
  • Llamada de voz y app común

Asistente y app común

El Asistente es una app privilegiada porque se incluye preinstalada y tiene la función RoleManager.ROLE_ASSISTANT. Se trata de forma similar a cualquier otra app preinstalada con esta función.

Android comparte el audio de entrada según estas reglas:

  • El Asistente puede recibir audio (sin importar si está en primer o segundo plano), a menos que ya esté capturando contenido otra app que utilice una fuente de audio sensible a la privacidad.

  • La app recibirá audio, a menos que el Asistente tenga un componente de IU visible en la parte superior de la pantalla.

Ten en cuenta que ambas apps reciben audio solamente cuando el Asistente está en segundo plano y la otra app no está capturando audio desde una fuente sensible a la privacidad.

Servicio de accesibilidad y app común

Un objeto AccessibilityService requiere una declaración estricta.

Android comparte el audio de entrada según estas reglas:

  • Si la IU del servicio está en la parte superior, tanto el servicio como la app reciben la entrada de audio. Este comportamiento ofrece funcionalidades como el control de una llamada de voz o la captura de video con comandos por voz.

  • Si el servicio no está en la parte superior, este caso se trata como el de dos apps comunes, que se explica a continuación.

Dos apps comunes

Cuando dos apps capturan contenido simultáneamente, solo una recibe audio, y la otra recibe silencio.

Android comparte el audio de entrada según estas reglas:

  • Si ninguna de las dos apps es sensible a la privacidad, la que tenga una IU en la parte superior recibirá audio. Si ninguna tiene una IU, la que haya iniciado la captura más reciente recibirá audio.
  • Si una de las apps es sensible a la privacidad, recibirá audio, y la otra recibirá silencio, incluso si tiene una IU en la parte superior o si ha empezado a capturar contenido más recientemente.
  • Si ambas apps son sensibles a la privacidad, la que haya comenzado a capturar más recientemente recibirá audio, y la otra recibirá silencio.

Llamada de voz y app común

Una llamada de voz está activa si el modo de audio que muestra AudioManager.getMode() es MODE_IN_CALL o MODE_IN_COMMUNICATION.

Android comparte el audio de entrada según estas reglas:

Cambios de configuración

Cuando varias apps capturan audio simultáneamente, solo una o dos están "activas" (recibiendo audio); las otras están silenciadas (recibiendo silencio). Cuando cambian las apps activas, el marco de trabajo de audio puede reconfigurar las rutas de audio según estas reglas:

  • El dispositivo de entrada de audio correspondiente a cada app activa puede cambiar (por ejemplo, de un micrófono integrado a un auricular Bluetooth conectado).
  • El preprocesamiento asociado a la app activa de mayor prioridad está habilitado. Se ignoran todos los demás preprocesos.

Dado que se puede silenciar una app activa cuando se habilita una de mayor prioridad, puedes registrar un elemento AudioManager.AudioRecordingCallback en el objeto AudioRecord o MediaRecorder para que se te notifique cuando cambie la configuración. Los posibles cambios podrían ser los siguientes:

  • Se silenció o dejó de silenciar la captura.
  • Cambió el dispositivo.
  • Cambió el preprocesamiento.
  • Cambiaron las propiedades de transmisión (tasa de muestreo, máscara de canal y formato de muestreo).

Debes llamar a AudioRecord.registerAudioRecordingCallback() antes de que se inicie la captura. La devolución de llamada se ejecuta solo cuando la app está recibiendo audio y se produce un cambio.

El método onRecordingConfigChanged() muestra un AudioRecordingConfiguration que contiene el estado de captura de audio actual. Usa los siguientes métodos para obtener información sobre el cambio:

isClientSilenced()
Muestra un valor verdadero si se está silenciando el audio que se muestra al cliente debido a la política de captura.
getAudioDevice()
Muestra el dispositivo de audio activo.
getEffects()
Muestra el efecto de preprocesamiento activo. Ten en cuenta que el efecto activo puede no ser el mismo que los que muestra getClientEffects() si el cliente no es la app activa de mayor prioridad.
getFormat()
Muestra las propiedades de la transmisión. Ten en cuenta que los datos de audio reales que recibe el cliente siempre respetan el formato requerido que muestra getClientFormat(). El marco de trabajo procesa automáticamente el remuestreo, el canal y la conversión de formato necesarios, desde el formato utilizado en la interfaz de hardware hasta el formato especificado por el cliente.
AudioRecord.getActiveRecordingConfiguration().
Muestra la configuración de grabación activa.

Puedes obtener una vista general de todas las grabaciones activas en el dispositivo llamando a AudioManager.getActiveRecordingConfigurations().