L'input audio solitamente proviene dal microfono integrato, da un microfono esterno o a interfaccia audio collegata al dispositivo. L'input audio può provenire anche durante 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 essere "registrazione", come un semplice registratore vocale, mentre altre app potrebbero ascoltare musica come l'Assistente Google o un servizio di accessibilità che rispondere ai comandi vocali.
In entrambi i casi, queste app vogliono ricevere input audio. In questa pagina utilizziamo il termine "acquisizione" indipendentemente dal fatto che che l'app sta registrando o soltanto ascoltando.
Se due o più app vogliono acquisire audio contemporaneamente, può esserci un problema inviare a tutti il segnale audio proveniente dalla stessa sorgente. In questa pagina vengono descritti Il modo in cui 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 una sola app alla volta.
nel tempo. Se un'app stava già registrando o ascoltando audio, la tua app potrebbe
crea un oggetto AudioRecord
, ma viene restituito un errore quando chiami
AudioRecord.startRecording()
e la registrazione non viene avviata.
Un'eccezione a questa regola era quando un'app con privilegi (come l'Assistente Google o un
di accessibilità di Google) disponeva dell'autorizzazione
android.permission.CAPTURE_AUDIO_HOTWORD
e ha usato 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.
È stata aggiunta un'altra modifica in Android 9: soltanto le app in esecuzione in primo piano (oppure un servizio in primo piano) potrebbero acquisire l'input audio. Quando un'app senza servizio in primo piano o componente UI in primo piano avviato per acquisire l'app ha continuato a funzionare, ma ha ricevuto silenzio, anche se era l'unica acquisizione dell'app audio in tempo reale.
Comportamento di Android 10
Il comportamento precedente ad Android 10 è "first come, first served". Una volta che un'app inizia ad acquisire l'audio, nessun'altra app può accedere ai input audio fino all'interruzione dell'app che sta acquisendo l'audio.
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 di acquisizione precedente continua a essere eseguita, ma riceve silenzio. In alcuni nei casi in cui il sistema può continuare a inviare audio a entrambe le app. Le varie scenari di condivisione illustrati di seguito.
Questo schema è simile al modo in cui lo stato attivo dell'audio gestisce più app in competizione per l'uso dell'output audio. Tuttavia, il focus audio è gestito richieste programmatiche per acquisire e rilasciare l'attenzione, mentre il cambio di input qui descritto si basa su un criterio di prioritizzazione applicato automaticamente ogni volta che una nuova app inizia ad acquisire audio.
Per acquisire l'audio, Android distingue due tipi di app:
- "Ordinario" le app installate dall'utente.
- "Con privilegi" sono preinstallate sul dispositivo. Sono inclusi l'Assistente Google e tutti i servizi di accessibilità.
Inoltre, un'app viene trattata in modo diverso
se utilizza un modello di attribuzione sorgente audio:
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 normali.
- 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 tiene al rispetto della privacy hanno una priorità maggiore rispetto a quelle che non lo sono.
- Due app normali non sono mai in grado di acquisire l'audio contemporaneamente.
- In alcune situazioni, un'app con privilegi può condividere l'input audio con un'altra app.
- Se due app in background con la stessa priorità acquisiscono audio, l'ultima che è stata avviata ha la priorità più alta.
Scenari di condivisione
Quando due app tentano di acquisire audio, entrambi potrebbero essere in grado di ricevere il segnale di ingresso oppure uno di loro potrebbe ricevere silenzio.
Esistono quattro scenari principali:
- Assistente + app comune
- Servizio di accessibilità + app normale
- Due app comuni
- Chiamata vocale + normale applicazione
Assistente + app comune
L'assistente è un'app con privilegi perché è preinstallata e contiene
il ruolo RoleManager.ROLE_ASSISTANT
.
Tutte le altre app preinstallate con questo ruolo vengono trattate in modo simile.
Android condivide l'audio di input in base a queste regole:
L'assistente può ricevere audio (anche in primo piano o in background) a meno che un'altra app che usa una sorgente audio sensibile alla privacy stia già registrando.
L'app riceve audio a meno che l'assistente non abbia una UI visibile nella parte superiore dello schermo.
Tieni presente che entrambe le app ricevono audio solo quando l'assistente è in background. e che l'altra app non acquisisca i dati da una sorgente audio sensibile alla privacy.
Servizio di accessibilità + app normale
Un AccessibilityService
richiede una dichiarazione rigorosa.
Android condivide l'audio di input in base a queste regole:
Se l'UI del servizio si trova in alto, sia il servizio sia l'app ricevono l'input audio. Questo comportamento offre funzionalità quali il controllo di una chiamata vocale o di un video acquisire usando i comandi vocali.
Se il servizio non è il primo, questa richiesta viene trattata come la normale richiesta in due app riportata di seguito.
Due app comuni
Quando due app acquisiscono contemporaneamente, solo un'app riceve l'audio e l'altra viene silenziata.
Android condivide l'audio di input in base a queste regole:
- Se nessuna delle due app è sensibile alla privacy, l'app con una UI nella parte superiore riceve l'audio. Se nessuna delle due app ha una UI, quella da cui è stata avviata l'acquisizione più recente riceve l'audio.
- Se una delle app è sensibile alla privacy, riceve audio e un'altra app riceve silenzio anche se ha un'UI in alto o se ha avviato l'acquisizione più di recente.
- Se entrambe le app sono sensibili alla privacy, l'app che ha iniziato ad acquisire la maggior parte di recente riceve audio e l'altro silenzia.
Chiamata vocale + normale applicazione
Una chiamata vocale è attiva se la modalità audio è stata restituita da
AudioManager.getMode()
è
MODE_IN_CALL
oppure
MODE_IN_COMMUNICATION
Android condivide l'audio di input in base a queste regole:
- La chiamata riceve sempre l'audio.
- L'app può acquisire l'audio se si tratta di un servizio di accessibilità.
L'app può acquisire la chiamata vocale se si tratta di un app (preinstallata) autorizzata
CAPTURE_AUDIO_OUTPUT
Per acquisire l'uplink (TX), il downlink (RX) o entrambi della chiamata vocale, l'app deve specificare le sorgenti audio
MediaRecorder.AudioSource.VOICE_UPLINK
oppureMediaRecorder.AudioSource.VOICE_DOWNLINK
, e/o il dispositivoAudioDeviceInfo.TYPE_TELEPHONY
.
Comportamento di Android 11
Android 11 (livello API 30) osserva lo schema di priorità di Android 10
descritti sopra. Offre inoltre nuovi metodi in AudioRecord
, MediaRecorder
e
AAudioStream
che attivano e disattivano la possibilità di acquisire audio contemporaneamente,
a prescindere dal caso d'uso selezionato.
I nuovi metodi sono:
AudioRecord.Builder.setPrivacySensitive()
AudioRecord.isPrivacySensitive()
MediaRecorder.setPrivacySensitive()
MediaRecorder.isPrivacySensitive()
AAudioStreamBuilder_setPrivacySensitive()
AAudioStream_isPrivacySensitive()
Se setPrivacySensitive()
è true
, il caso d'uso di acquisizione è privato e uniforme
un assistente con privilegi non può acquisire contemporaneamente. Questa impostazione sostituisce
un comportamento predefinito che dipende dalla sorgente audio. Ad esempio,
VOICE_COMMUNICATION
è privato per impostazione predefinita, al contrario di UNPROCESSED
.
Modifiche alla configurazione
Quando più app acquisiscono audio contemporaneamente, solo una o due "attivo" (ricezione audio); le altre hanno il microfono disattivato (ricevendo 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, da microfono integrato a cuffie Bluetooth collegate).
- La pre-elaborazione associata all'app attiva con la massima priorità è abilitata. Tutti le altre pre-elaborazioni vengono ignorate.
Poiché un'app attiva potrebbe essere silenziata quando un'app con priorità più alta diventa attiva,
puoi registrare
AudioManager.AudioRecordingCallback
il AudioRecord
oppure MediaRecorder
ricevere una notifica quando la configurazione cambia.
Le possibili modifiche potrebbero essere:
- Acquisizione con audio silenziato o non silenziato
- Dispositivo modificato
- Pre-elaborazione modificata
- Proprietà dello stream modificate (frequenza di campionamento, maschera del canale, formato di esempio)
Devi chiamare
AudioRecord.registerAudioRecordingCallback()
prima dell'inizio dell'acquisizione.
Il callback viene eseguito soltanto quando l'app riceve audio e si verifica una modifica.
Il metodo onRecordingConfigChanged()
restituisce un valore AudioRecordingConfiguration
contenente lo stato di acquisizione dell'audio corrente. Utilizza quanto segue
per scoprire di più sul cambiamento:
isClientSilenced()
- restituisce true se l'audio restituito al client è attualmente silenziato a causa della norma di acquisizione.
getAudioDevice()
- Restituisci il dispositivo audio attivo.
getEffects()
- Restituisci l'effetto di pre-elaborazione attiva. 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ù elevata. getFormat()
- Restituisci le proprietà dello stream. Tieni presente che i dati audio effettivi ricevuti dal cliente rispettano sempre il formato richiesto restituito da
getClientFormat()
. Il framework esegue automaticamente la conversione del ricampionamento, del canale e del formato necessari dal formato utilizzato nell'interfaccia hardware a quello specificato dal client. AudioRecord.getActiveRecordingConfiguration()
.- Restituisci la configurazione della registrazione attiva.
Puoi ottenere una visione generale di tutte le registrazioni attive sul dispositivo chiamando
AudioManager.getActiveRecordingConfigurations()