Condivisione di input audio

In genere l'ingresso audio proviene dal microfono integrato, da un microfono esterno o da un'interfaccia audio collegata al dispositivo. L'input audio può anche provenire da una conversazione telefonica.

A volte due o più app potrebbero voler acquisire lo stesso input audio. Potrebbero svolgere attività diverse. Ad esempio, alcune app che ricevono audio potrebbero "registrare", come un semplice registratore vocale, mentre altre app potrebbero "per l'ascolto", come l'Assistente Google o un servizio di accessibilità che risponde ai comandi vocali.

In entrambi i casi, queste app vogliono ricevere input audio. In questa pagina utilizziamo il termine "acquisizione", a prescindere dal fatto che un'app sia in registrazione o semplicemente in ascolto.

Se due o più app vogliono acquisire audio contemporaneamente, potrebbe esserci un problema durante la trasmissione del segnale audio dalla stessa sorgente a tutte. In questa pagina viene descritto in che modo il sistema Android condivide l'input audio tra più app che acquisiscono l'audio.

Comportamento precedente ad Android 10

Prima di Android 10, lo stream audio di input poteva essere acquisito da un'unica app alla volta. Se un'app stesse già registrando o ascoltando audio, l'app potrebbe creare un oggetto AudioRecord, ma verrà restituito un errore quando chiami AudioRecord.startRecording() e la registrazione non viene avviata.

Un'eccezione a questa regola è stata quando un'app con privilegi (come l'Assistente Google o un servizio di accessibilità) aveva l'autorizzazione android.permission.CAPTURE_AUDIO_HOTWORD e utilizzava una sorgente audio di tipo HOTWORD. In questo caso, un'altra app potrebbe iniziare a registrare. Quando è successo, l'app con privilegi è stata terminata e la nuova app ha acquisito l'input.

In Android 9 è stata aggiunta un'altra modifica: solo le app eseguite in primo piano (o un servizio in primo piano) potevano acquisire l'input audio. Quando un'app senza un servizio in primo piano o un componente della UI in primo piano ha iniziato ad acquisire, l'app ha continuato a essere eseguita, ma ha ricevuto silenzio, anche se era l'unica app ad acquisire audio in quel momento.

Comportamento di Android 10

Il comportamento precedente ad Android 10 è "primo arrivato, primo servito". Quando un'app inizia ad acquisire l'audio, nessun'altra app può accedere all'input audio finché l'app che acquisisce l'audio non si interrompe.

Android 10 impone uno schema di priorità che può cambiare lo stream audio di input tra le app mentre sono in esecuzione. Nella maggior parte dei casi, se una nuova app acquisisce l'input audio, l'app acquisita in precedenza continua a essere eseguita, ma riceve silenzio. In alcuni casi, il sistema può continuare a inviare l'audio a entrambe le app. Di seguito sono illustrati i vari scenari di condivisione.

Questo schema è simile al modo in cui lo stato attivo dell'audio gestisce più app che si contendono l'utilizzo dell'output audio. Tuttavia, l'attenzione relativa all'audio viene gestita dalle richieste di pubblicità programmatica per raggiungere e rilasciare l'attenzione, mentre lo schema di cambio di input descritto qui si basa su un criterio di priorità che viene applicato automaticamente ogni volta che una nuova app inizia ad acquisire audio.

Per acquisire l'audio, Android distingue due tipi di app:

  • Le app "ordinarie" vengono installate dall'utente.
  • Le app "con privilegi" sono preinstallate sul dispositivo. inclusi l'Assistente Google e tutti i servizi di accessibilità.

Inoltre, un'app viene trattata in modo diverso se utilizza una sorgente audio "sensibile alla privacy": CAMCORDER o VOICE_COMMUNICATION.

Le regole di priorità per l'utilizzo e la condivisione dell'input audio sono le seguenti:

  • Le app con privilegi hanno una priorità maggiore rispetto alle app ordinarie.
  • Le app con UI in primo piano visibili hanno una priorità maggiore rispetto alle app in background.
  • Le app che acquisiscono audio da una fonte che rispetta la privacy hanno una priorità maggiore rispetto alle app che non lo sono.
  • Due normali app non sono mai in grado di acquisire l'audio contemporaneamente.
  • In alcuni casi, un'app con privilegi può condividere l'input audio con un'altra app.
  • Se due app in background con la stessa priorità acquisiscono l'audio, l'ultima app avviata ha una priorità maggiore.

Scenari di condivisione

Quando due app cercano di acquisire audio, potrebbero essere in grado di ricevere il segnale di ingresso o una di loro potrebbe ricevere il silenzio.

Esistono quattro scenari principali:

  • Assistente + app normale
  • Servizio di accessibilità + app normale
  • Due app ordinarie
  • Chiamata vocale + app normale

Assistente + app normale

L'Assistente è un'app con privilegi perché è preinstallato e detiene il ruolo RoleManager.ROLE_ASSISTANT. Tutte le altre app preinstallate con questo ruolo vengono trattate in modo simile.

Android condivide l'audio in input in base alle seguenti regole:

  • L'assistente può ricevere audio (indipendentemente dal fatto che sia in primo piano o in background), a meno che non sia già in corso l'acquisizione di un'altra app che utilizza una sorgente audio sensibile alla privacy.

  • L'app riceve audio, a meno che l'assistente non abbia un componente UI visibile nella parte superiore dello schermo.

Tieni presente che entrambe le app ricevono audio solo quando l'assistente è in background e l'altra app non acquisisce audio da una sorgente audio sensibile alla privacy.

Servizio di accessibilità + app normale

Un AccessibilityService richiede una dichiarazione rigorosa.

Android condivide l'audio in input in base alle seguenti regole:

  • Se la UI del servizio è in alto, sia il servizio sia l'app ricevono input audio. Questo comportamento offre funzionalità come il controllo di una chiamata vocale o dell'acquisizione di video con comandi vocali.

  • Se il servizio non è in primo piano, questo caso viene trattato come la normale richiesta di due app riportata di seguito.

Due app ordinarie

Quando due app vengono acquisite contemporaneamente, solo un'app riceve audio e l'altra si disattiva.

Android condivide l'audio in input in base alle seguenti regole:

  • Se nessuna delle due app è sensibile alla privacy, l'app con una UI in alto riceve audio. Se nessuna delle app dispone di una UI, l'app che ha avviato l'acquisizione più di recente riceve audio.
  • Se una delle app è sensibile alla privacy, riceve audio e l'altra viene silenziata anche se ha una UI nella parte superiore o se ha iniziato l'acquisizione più di recente.
  • Se entrambe le app sono sensibili alla privacy, l'app che ha iniziato ad acquisire più di recente riceve audio e l'altra viene silenziata.

Chiamata vocale + app normale

Una chiamata vocale è attiva se la modalità audio restituita da AudioManager.getMode() è MODE_IN_CALL o MODE_IN_COMMUNICATION.

Android condivide l'audio in input in base alle seguenti regole:

Comportamento di Android 11

Android 11 (livello API 30) rispetta lo schema di priorità di Android 10 descritto sopra. Offre inoltre nuovi metodi in AudioRecord, MediaRecorder e AAudioStream che abilitano e disabilitano la possibilità di acquisire audio contemporaneamente, indipendentemente dal caso d'uso selezionato.

I nuovi metodi sono:

Se setPrivacySensitive() è true, il caso d'uso dell'acquisizione è privato e neanche un assistente con privilegi non può acquisire immagini contemporaneamente. Questa impostazione sostituisce il comportamento predefinito che dipende dalla sorgente audio. Ad esempio, VOICE_COMMUNICATION è privato per impostazione predefinita, mentre UNPROCESSED non lo è.

Modifiche alla configurazione

Quando più app acquisiscono l'audio contemporaneamente, solo una o due sono "attive" (ricezione audio), mentre l'audio delle altre viene disattivato (ricezione di silenzio). Quando le app attive cambiano, il framework audio potrebbe riconfigurare i percorsi audio in base a queste regole:

  • Il dispositivo di input audio di ogni app attiva potrebbe cambiare (ad esempio, dal microfono integrato alle cuffie Bluetooth collegate).
  • La pre-elaborazione associata all'app attiva con priorità più alta viene attivata. Tutte le altre pre-elaborazioni vengono ignorate.

Poiché un'app attiva potrebbe essere silenziata quando un'app con priorità più alta diventa attiva, puoi registrare un AudioManager.AudioRecordingCallback sull'oggetto AudioRecord o MediaRecorder per ricevere una notifica quando la configurazione cambia. Le possibili modifiche potrebbero essere:

  • Acquisisci elementi silenziati o non silenziati
  • Dispositivo modificato
  • Pre-elaborazione modificata
  • Proprietà dello stream modificate (frequenza di campionamento, maschera del canale, formato di esempio)

Devi chiamare AudioRecord.registerAudioRecordingCallback() prima di iniziare l'acquisizione. Il callback viene eseguito solo quando l'app riceve audio e si verifica una modifica.

Il metodo onRecordingConfigChanged() restituisce un AudioRecordingConfiguration contenente lo stato corrente dell'acquisizione dell'audio. Per ottenere informazioni sulla modifica, utilizza i seguenti metodi:

isClientSilenced()
Restituisce true se l'audio restituito al client viene attualmente silenziato a causa del criterio di acquisizione.
getAudioDevice()
Restituisci il dispositivo audio attivo.
getEffects()
Restituisci l'effetto di pre-elaborazione attivo. Tieni presente che l'effetto attivo potrebbe non essere uguale a quelli restituiti da getClientEffects() se il client non è l'app attiva con priorità più alta.
getFormat()
Restituisci le proprietà dello stream. Tieni presente che i dati audio effettivi ricevuti dal client rispettano sempre il formato richiesto restituito da getClientFormat(). Il framework esegue automaticamente la conversione necessaria per il ricampionamento, il canale e il formato dal formato utilizzato nell'interfaccia hardware al formato specificato dal client.
AudioRecord.getActiveRecordingConfiguration().
Restituisci la configurazione di registrazione attiva.

Puoi avere una visione generale di tutte le registrazioni attive sul dispositivo chiamando il numero AudioManager.getActiveRecordingConfigurations().