Timeout dei servizi in primo piano

Se un'app ha come target Android 15 o versioni successive, il sistema applica limitazioni alla durata di esecuzione di determinati servizi in primo piano mentre l'app è in background. Al momento, questa limitazione si applica solo ai servizi in primo piano dataSync e mediaProcessing foreground service type. Esistono limiti più restrittivi per il tipo di servizio in primo piano shortService, che vengono discussi nella documentazione di quel tipo di servizio.

Comportamento di timeout

Il sistema consente l'esecuzione dei servizi in primo piano dataSync e mediaProcessing per un totale di 6 ore in un periodo di 24 ore, dopodiché chiama il metodo Service.onTimeout(int, int) del servizio in esecuzione (introdotto in Android 15). (Il tipo di servizio in primo piano mediaProcessing è stato aggiunto in Android 15.) Il limite di sei ore viene monitorato separatamente per i servizi dataSync e mediaProcessing. Ad esempio, se un servizio dataSync è stato eseguito per un'ora, l'app avrà a disposizione solo cinque ore per i servizi in primo piano dataSync, ma avrà a disposizione sei ore intere per i servizi mediaProcessing.

Quando un servizio in primo piano raggiunge il limite di sei ore, ha a disposizione alcuni secondi per chiamare Service.stopSelf(). Quando il sistema chiama Service.onTimeout(), il servizio non è più considerato un servizio in primo piano. Se il servizio non chiama Service.stopSelf(), il sistema genera un'eccezione interna. L'eccezione viene registrata in Logcat con il seguente messaggio:

Fatal Exception: android.app.RemoteServiceException: "A foreground service of
type [service type] did not stop within its timeout: [component name]"

Per evitare problemi con questa modifica del comportamento, puoi procedere in uno o più dei seguenti modi:

  1. Fai in modo che il tuo servizio implementi il nuovo metodo Service.onTimeout(int, int). Quando la tua app riceve il callback, assicurati di chiamare stopSelf() entro pochi secondi. Se non interrompi l'app immediatamente, il sistema genera un errore.
  2. Assicurati che i servizi dataSync e mediaProcessing della tua app non vengano eseguiti per più di un totale di 6 ore in un periodo di 24 ore (a meno che l'utente non interagisca con l'app, reimpostando il timer).
  3. Avvia i servizi in primo piano dataSync o mediaProcessing solo come risultato di un'interazione diretta dell'utente. Poiché la tua app è in primo piano quando il servizio viene avviato, il servizio ha a disposizione tutte le sei ore dopo che l'app passa in background.
  4. Anziché utilizzare questi servizi in primo piano, utilizza un'API alternativa, come WorkManager. In particolare, anziché utilizzare un servizio in primo piano dataSync, valuta la possibilità di utilizzare un'API alternativa.

Se i servizi in primo piano dataSync della tua app sono stati eseguiti per 6 ore nelle ultime 24, non puoi avviare un altro servizio in primo piano dataSync a meno che l'utente non abbia portato l'app in primo piano (operazione che reimposta il timer). Se provi ad avviare un altro servizio in primo piano dataSync, il sistema genera ForegroundServiceStartNotAllowedException con un messaggio di errore simile a "Limite di tempo già esaurito per il tipo di servizio in primo piano dataSync".

Test

Per testare il comportamento della tua app, puoi attivare i timeout della sincronizzazione dei dati anche se l'app non ha come target Android 15 (purché l'app sia in esecuzione su un dispositivo Android 15). Per abilitare i timeout, esegui questo comando adb:

adb shell am compat enable FGS_INTRODUCE_TIME_LIMITS your-package-name

Puoi anche modificare il periodo di timeout per semplificare il test del comportamento dell'app quando viene raggiunto il limite. Per impostare un nuovo periodo di timeout per i servizi in primo piano dataSync, esegui il seguente comando adb:

adb shell device_config put activity_manager data_sync_fgs_timeout_duration duration-in-milliseconds

Per impostare un nuovo periodo di timeout per i servizi in primo piano mediaProcessing, esegui questo comando:

adb shell device_config put activity_manager media_processing_fgs_timeout_duration duration-in-milliseconds