Rafforzamento dell'audio in background

A partire da Android 17, il framework audio applica restrizioni alle interazioni audio in background, tra cui riproduzione audio, richieste di focus audio e API di modifica del volume, per garantire che queste modifiche vengano avviate intenzionalmente dall'utente.

Tutte le app in esecuzione su Android 17 che hanno queste interazioni audio in background devono avere un'attività visibile o devono eseguire un servizio in primo piano di tipo diverso da SHORT_SERVICE. Ciò vale indipendentemente dal fatto che l'app abbia come target il livello API 37.

Se un'app ha come target Android 17 (livello API 37), è presente un'ulteriore limitazione. Se l'app è in esecuzione in background, deve eseguire un servizio in primo piano con funzionalità durante l'uso. (A un servizio in primo piano vengono concesse funzionalità WIU se viene avviato in risposta a un'operazione avviata dall'utente o mentre l'app è visibile all'utente.) Tuttavia, il requisito per le funzionalità WIU non è necessario se all'app è stata concessa l'autorizzazione sveglia esatta e sta apportando modifiche ai flussi audio che hanno l'attributo USAGE_ALARM.

Se l'app tenta di chiamare le API audio mentre non si trova in un ciclo di vita valido, le API di riproduzione audio e modifica del volume non vanno a buon fine senza generare un'eccezione o fornire un messaggio di errore. L'API Audio Focus non funziona e restituisce il codice risultato AUDIOFOCUS_REQUEST_FAILED.

Perché stiamo apportando questa modifica

L'intenzione di introdurre queste limitazioni è quella di ridurre le esperienze buggy di audio in background non intenzionali. Ecco alcuni esempi:

  • Le app che riproducono audio senza un servizio in primo piano possono essere bloccate. Quando l'app viene scongelata, la riproduzione audio riprende in modo imprevisto, potenzialmente ore dopo.
  • Le app che riproducono audio senza un servizio in primo piano hanno dovuto affrontare varie limitazioni di esecuzione che hanno comportato prestazioni audio instabili.
  • Riproduzione separata dal ciclo di vita dell'attività, che potrebbe comportare una sessione di riproduzione o eventi di messa a fuoco trapelati che continuano senza che l'utente possa interrompere la riproduzione.

Invitiamo gli sviluppatori a testare le proprie app e a fornire feedback sulla modifica del comportamento se sono presenti casi d'uso audio intenzionali interessati negativamente. Segnala eventuali problemi utilizzando questo strumento di monitoraggio dei problemi di compatibilità delle app con Android 17.

Identificare i casi d'uso dell'audio in background interessati

Controlla l'implementazione della riproduzione audio e verifica se la tua app intende fornire funzionalità di interazione audio in background anche in circostanze condizionali.

Se la tua app intende riprodurre solo audio o utilizzare API audio mentre mostra un'attività visibile all'utente, incluso l'utilizzo della modalità Picture in Picture (PIP), non è interessata da nessuna di queste modifiche.

Se la tua app fornisce funzionalità VOIP, incluse le app di videochiamata, deve già soddisfare i requisiti introdotti per la riproduzione (in genere utilizzando le API telecom consigliate) per registrare correttamente l'audio, pertanto è improbabile che venga interessata.

Se la tua app intende continuare la riproduzione audio con lo schermo spento o mentre la tua attività non è visibile, come avviene più comunemente nelle app di streaming musicale o podcast, la tua app è considerata fornire funzionalità audio in background e deve soddisfare i nuovi requisiti.

Scenari audio in background che potrebbero essere interessati

Se la tua app non segue il modello di continuazione di un'interazione audio iniziata mentre l'app era aperta o in risposta a un trigger utente esplicito, è probabile che la funzionalità dell'app venga eliminata in modo silenzioso.

Ad esempio, se la tua app avvia un servizio in primo piano in risposta a BOOT_COMPLETE e tenta di interagire con l'audio, verrà soppressa.

Best practice per l'audio in background per ridurre l'impatto

  • Utilizza il componente MediaSessionService della libreria Jetpack media3 per gestire la riproduzione audio in background.

    In questo caso, è improbabile che la tua app sia interessata dall'hardening in background perché la libreria aiuta a gestire il ciclo di vita della riproduzione.

  • Se non utilizzi la libreria media3, dovrai avviare manualmente un mediaPlayback FGS. Avvia sempre un servizio in primo piano mentre l'app è in primo piano se è possibile che si verifichi l'audio in background.

    Ad esempio, se la tua app è un'app di streaming video che in genere è solo in primo piano, ma contiene un'agevolazione per l'utente per continuare la riproduzione mentre lo schermo è spento, quando si verifica il trigger di riproduzione avviato dall'utente, la tua app deve comunque avviare un servizio in primo piano.

    In questo modo, il servizio in primo piano viene avviato con le funzionalità WIU.

  • Mantieni attivo il mediaPlayback FGS durante gli errori temporanei di durata inferiore a 10 minuti.

    Se la tua app presenta un errore temporaneo, ad esempio un problema di buffering dovuto all'attività di rete, o se si verifica un'interruzione temporanea prevista, ad esempio AUDIOFOCUS_LOSS_TRANSIENT, l'intent di riproduzione deve continuare. Pertanto, il tuo FGS deve rimanere attivo.

  • Interrompi il servizio in primo piano al termine della riproduzione e riavviala solo se l'utente riprende esplicitamente la riproduzione.

    In caso di segnale permanente per terminare la riproduzione (ad esempio, contenuti completi senza riproduzione automatica, un AUDIOFOCUS_LOSS, un evento di pausa dall'UMO o un evento chiave multimediale) o di errore non recuperabile, l'app deve interrompere l'interazione audio, arrestare il servizio in primo piano e terminare la sessione multimediale. Tutto questo corrisponde alla concezione dell'utente di "completamento" dell'interazione audio in background desiderata. Dopo averlo fatto, la tua app non ha più funzionalità di interazione audio in background.

    Successivamente, se l'utente riprende esplicitamente la riproduzione, ad esempio tramite l'interfaccia utente della tua app o tramite il pulsante di riproduzione dell'oggetto multimediale universale, l'intent per avviare la riproduzione audio deve essere restituito, con conseguente avvio di un nuovo servizio in primo piano.

  • Testa il comportamento di riproduzione audio con i comandi adb shell.

Test delle modifiche in corso…

Puoi testare la conformità della tua app sulle app che eseguono Android 17 o versioni successive (a partire dalla beta 3) eseguendo il seguente comando ADB:

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

Questo comando ha le seguenti opzioni:

  • enable: attiva tutte le restrizioni di protezione audio per tutte le app. Il requisito per i servizi in primo piano WIU viene applicato indipendentemente dal fatto che un'app abbia come target Android 17 (livello API 37). Inoltre, il requisito viene applicato anche se l'app sta apportando modifiche ai flussi di sveglie e dispone dell'autorizzazione esatta per le sveglie.

  • disable: disattiva tutte le restrizioni di protezione dell'audio.

  • throw: attiva tutte le restrizioni di protezione audio per tutte le app, ad esempio enable. Inoltre, questo flag attiva errori gravi, generando IllegalStateException per le interazioni con il volume e la messa a fuoco. Per la riproduzione audio, il metodo di scrittura restituisce in modo permanente un codice di errore. Per le modalità di riproduzione senza scritture esplicite, l'app va in crash.

Utilizza adb dumpsys audio o logcat per identificare se l'app ha riscontrato errori silenziosi a causa dell'applicazione della protezione audio. In tal caso, vedrai una voce con il prefisso AudioHardening e il nome del pacchetto. Se il messaggio contiene level: full, la tua app esegue un servizio in primo piano, ma il servizio non ha la funzionalità "durante l'uso". Se il messaggio contiene level: partial, la tua app non esegue alcun servizio in primo piano.

Informazioni sul servizio di geolocalizzazione con funzionalità di utilizzo

In genere, i servizi in primo piano (FGS) devono essere avviati mentre un'app è in primo piano per estendere le operazioni avviate dall'utente. In alcuni casi specifici, le app possono avviare un servizio in primo piano mentre l'app è in background. Tuttavia, a questi servizi in primo piano di solito non vengono concesse le funzionalità "durante l'uso".

WIU funge da barriera di sicurezza: impedisce agli FGS avviati in background di intraprendere determinati comportamenti sensibili quando l'utente potrebbe non essere a conoscenza dell'attività dell'app. Impedisce all'app di accedere a dati sensibili come posizione, fotocamera o microfono e, a partire da Android 17, blocca anche le API audio che in genere richiedono un contesto UI visibile.

Ecco un riferimento utile:

  • FGS standard: i servizi avviati mentre l'app è visibile o è stata concessa la funzionalità di avvio dell'attività in background hanno accesso a WIU.
  • Servizio in primo piano avviato in background (BFSL): la maggior parte non concede l'accesso a WIU. Le eccezioni principali che concedono l'intento di utilizzo sono le interazioni che coinvolgono l'intento esplicito dell'utente, ad esempio clic sulle notifiche, interazioni con i widget o eventi dei tasti multimediali da un dispositivo esterno.
  • Il sistema ha avviato FGS: ai servizi in primo piano viene concesso l'accesso WIU se vengono avviati dalla delega system-server (ad esempio, dalla libreria Telecom jetpack) o da binding di sistema che rappresentano uno stato di primo piano elevato per eseguire funzionalità dedicate (ad esempio per un VoiceInteractionService).

Scopri di più in Limitazioni all'avvio di un servizio in primo piano dallo sfondo.

Elenco completo delle API audio interessate

Funzione audio

Risultato

API interessate

Riproduzione audio

La riproduzione è silenziata

Nessuna eccezione, nessun messaggio di errore fornito da alcuna API

AudioTrack.write()

(NDK) AAudioStream_write

OpenSL ES per Android

Potrebbero essere interessate anche le librerie multimediali lato client che gestiscono la riproduzione, come media3, ExoPlayer e Oboe.

Richiesta di focus audio

Restituisce AUDIOFOCUS_REQUEST_FAILED

Nessun effetto sulla riproduzione audio di altre app, nessun focus acquisito

AudioManager.requestAudioFocus()

API per il volume e la modalità suoneria

Nessun effetto sulla modalità Suoneria o sul volume (la chiamata al metodo viene ignorata in modo silenzioso)

Nessuna eccezione, nessun messaggio di errore fornito da alcuna API

AudioManager.setStreamVolume()

AudioManager.setStreamMute()

AudioManager.adjustStreamVolume()

AudioManager.adjustVolume()

AudioManager.adjustSuggestedStreamVolume()

AudioManager.setRingerMode()