Risolvere i problemi relativi ai servizi in primo piano

Questa pagina illustra alcuni motivi comuni per cui i servizi in primo piano possono non funzionare e ti aiuta a identificare la causa del problema.

Questo documento illustra i seguenti problemi:

Prima di procedere alla risoluzione dei problemi

Controlla le modifiche recenti ai servizi in primo piano

Se i servizi in primo piano vengono utilizzati in modo improprio, possono avere effetti negativi sulle prestazioni del dispositivo e sulla durata della batteria. Per questo motivo, le release della piattaforma Android spesso apportano modifiche al comportamento dei servizi in primo piano per limitare questi effetti negativi.

Se hai problemi con i servizi in primo piano, consulta la documentazione relativa alle modifiche ai servizi in primo piano e verifica se sono state apportate modifiche recenti che potrebbero spiegare i problemi. È particolarmente importante verificare la presenza di modifiche in queste circostanze:

  • Il codice del servizio in primo piano che funzionava in precedenza ora non funziona più
  • Hai appena iniziato i test su una nuova release della piattaforma o hai modificato il livello API scelto come target dalla tua app

Inoltre, se stai testando il tuo dispositivo su un'Anteprima per gli sviluppatori della piattaforma, assicurati di controllare la versione più recente della documentazione dell'Anteprima per gli sviluppatori.

Errori ANR (L'applicazione non risponde)

In determinate circostanze, un'app deve arrestare il proprio servizio in primo piano. Se l'app non interrompe il servizio, il sistema lo interrompe e attiva un errore L'applicazione non risponde (ANR).

Un servizio breve viene eseguito troppo a lungo, causando un ANR

I servizi in primo piano che utilizzano il tipo shortService devono essere completati rapidamente, entro circa tre minuti. Allo scadere del tempo, il sistema chiama il metodo Service.onTimeout(int,int) del servizio. Il servizio ha alcuni secondi per chiamare stopSelf(). Se il servizio non si interrompe, il sistema attiva un errore "L'applicazione non risponde".

Diagnostica:

Se l'ANR è stato causato da un servizio in primo piano che non è riuscito ad arrestarsi, il sistema genera un'eccezione interna. Puoi verificare che il problema sia questo controllando i report ANR. Se questo è il problema, il report includerà il seguente messaggio:

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

Correzione:

Assicurati che tutti i servizi in primo piano con limite di tempo completino il loro lavoro e chiamino stopForeground(int) entro il limite di tempo del sistema.

Fai in modo che i tuoi servizi in primo piano implementino Service.onTimeout(int,int). Assicurati che l'implementazione di questo metodo chiami immediatamente stopSelf().

Eccezioni per i servizi in primo piano

Questa sezione descrive diversi problemi relativi ai servizi in primo piano che possono causare la generazione di un'eccezione da parte del sistema. Se l'app non rileva l'eccezione, l'utente visualizza una finestra di dialogo che lo informa che l'app è stata interrotta.

In alcuni casi, il sistema genera un'eccezione interna. In questi casi, puoi scoprire qual è stata l'eccezione esaminando l'analisi dello stack e puoi controllare Logcat per informazioni più dettagliate sull'errore.

Eccezione interna: timeout superato

Il sistema impone un limite al tempo di esecuzione dei servizi in primo piano di sincronizzazione dei dati e di elaborazione dei contenuti multimediali mentre l'app è in background. Se il servizio supera questo limite, il sistema chiama il metodo Service.onTimeout(int,int) del servizio. Il servizio ha alcuni secondi per chiamare stopSelf(). Se il servizio non si interrompe, il sistema genera un RemoteServiceException interno che causa l'arresto anomalo dell'app.

Diagnostica:

Puoi scoprire qual è stata l'eccezione esaminando l'analisi dello stack e puoi controllare Logcat per informazioni più dettagliate sull'errore. In questo caso, Logcat mostra il seguente messaggio di errore:

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

Correzione:

Assicurati che tutti i servizi in primo piano con limite di tempo completino il loro lavoro e chiamino stopForeground(int) entro il limite di tempo del sistema.

Fai in modo che i tuoi servizi in primo piano implementino Service.onTimeout(int,int). Assicurati che l'implementazione di questo metodo chiami immediatamente stopSelf().

Eccezione interna: ForegroundServiceDidNotStartInTimeException

Quando avvii un servizio chiamando context.startForegroundService(), il servizio ha alcuni secondi per essere promosso a servizio in primo piano chiamando ServiceCompat.startForeground(). Se il servizio non lo fa, viene generato un errore interno ForegroundServiceDidNotStartInTimeException.

Diagnostica:

Puoi scoprire qual è stata l'eccezione esaminando l'analisi dello stack e puoi controllare Logcat per informazioni più dettagliate sull'errore. In questo caso, Logcat mostra il seguente messaggio di errore:

android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException:
Context.startForegroundService() did not then call Service.startForeground()

Correzione:

Assicurati che tutti i servizi in primo piano appena creati chiamino ServiceCompat.startForeground() entro pochi secondi.

WorkManager:

Potresti visualizzare questa eccezione anche con i worker WorkManager che eseguono un servizio in primo piano (chiamata setForegound o setForegroundAsync). Quando il ciclo di vita di due worker in primo piano si sovrappone, mentre un worker tenta di avviare un servizio in primo piano e un servizio in primo piano precedentemente in esecuzione tenta di arrestarsi, questo arresto anomalo sarà accompagnato dal seguente log:

Re-initializing SystemForegroundService after a request to shut-down

Una correzione di questo arresto anomalo è stata introdotta in WorkManager versione 2.10.5.

Se la tua app riscontra questa eccezione, esegui l'aggiornamento alla versione più recente di WorkManager e segnala eventuali problemi persistenti nell'Issue Tracker di WorkManager.

ForegroundServiceStartNotAllowedException

Errore:

Il sistema genera ForegroundServiceStartNotAllowedException.

Causa:

In genere, questo accade se l'app avvia un servizio in primo piano dal background quando non esiste un'esenzione valida.

A partire da Android 12 (livello API 31), le app non possono avviare servizi in primo piano mentre sono in esecuzione in background, con alcune esenzioni specifiche. Se provi ad avviare un servizio in primo piano dal background e non soddisfi i requisiti di una delle esenzioni, il sistema genera un'eccezione ForegroundServiceStartNotAllowedException. Il sistema esegue questa operazione anche se non soddisfi i requisiti dell'esenzione.

Ad esempio, un'app potrebbe avere un pulsante su cui l'utente può fare clic, che attiva l'elaborazione da parte dell'app e l'avvio di un servizio in primo piano. In questo caso, esiste il rischio che l'utente faccia clic sul pulsante e poi metta immediatamente l'app in background. L'app tenta quindi di avviare il servizio in background. Se l'app non soddisfa una delle esenzioni specificate, il sistema genera un errore ForegroundServiceStartNotAllowedException.

Inoltre, alcune esenzioni hanno un limite di tempo breve. Ad esempio, esiste una breve esenzione se la tua app avvia un servizio in primo piano in risposta a un messaggio FCM ad alta priorità. Se non avvii il servizio abbastanza rapidamente, ricevi un errore ForegroundServiceStartNotAllowedException.

A volte, con le nuove release di Android, le esenzioni specifiche diventano più restrittive. Se hai modificato la versione di Android scelta come target per la tua app, consulta la documentazione relativa alle modifiche ai servizi in primo piano e verifica che la tua app soddisfi ancora una delle esenzioni consentite.

Correzione:

Modifica il workflow della tua app in modo che non debba avviare servizi in primo piano mentre l'app è in background oppure verifica che la tua app soddisfi una delle esenzioni.

Puoi utilizzare i componenti sensibili al ciclo di vita per gestire il ciclo di vita della tua app, in modo da non provare inavvertitamente ad avviare un servizio in primo piano dal background.

SecurityException

Errore:

Il sistema genera un'eccezione SecurityException.

Causa:

La tua app ha tentato di avviare un servizio in primo piano senza disporre delle autorizzazioni necessarie.

  • Se un'app ha come target Android 9 (livello API 28) o versioni successive, deve disporre dell'autorizzazione FOREGROUND_SERVICE per avviare un servizio in primo piano.
  • Se un'app ha come target Android 14 (livello API 34) o versioni successive, deve soddisfare tutti i prerequisiti per il tipo di servizio in primo piano. Questi prerequisiti sono descritti dettagliatamente nella documentazione relativa ai tipi di servizi in primo piano. In particolare, tieni presente i seguenti requisiti:
    • Diversi tipi di servizi in primo piano richiedono autorizzazioni di runtime specifiche. Ad esempio, un servizio in primo piano di messaggistica remota deve disporre dell'autorizzazione FOREGROUND_SERVICE_REMOTE_MESSAGING.
  • In diversi casi, esistono ulteriori limitazioni per l'utilizzo durante l'uso delle autorizzazioni necessarie per alcuni tipi di servizi in primo piano. Queste autorizzazioni vengono concesse all'app solo quando è in primo piano (con alcune eccezioni specifiche). Ciò significa che, anche se la tua app ha richiesto e ottenuto una di queste autorizzazioni, se l'app tenta di avviare il servizio in primo piano mentre è in background, il sistema genera un'eccezione SecurityException anche se l'app ha un'esenzione per avviare un servizio in primo piano dal background. Per saperne di più, consulta Limitazioni all'avvio di servizi in primo piano che richiedono autorizzazioni per l'utilizzo.
    • Potresti ricevere un SecurityException se hai richiesto le autorizzazioni necessarie, ma avvii il servizio in primo piano prima di confermare che le autorizzazioni richieste sono state concesse.

Correzione:

Prima di avviare il servizio in primo piano, richiedi tutte le autorizzazioni appropriate per il servizio in primo piano e verifica di aver soddisfatto tutti gli altri prerequisiti di runtime.