I servizi in primo piano eseguono operazioni visibili all'utente.
I servizi in primo piano mostrano una barra di stato di notifica, per informare gli utenti che L'app esegue un'attività in primo piano e consuma risorse di sistema.
Ecco alcuni esempi di app che utilizzano i servizi in primo piano:
- Un'app di lettore musicale che riproduce musica in un servizio in primo piano. La notifica potrebbe mostrare il brano attualmente in riproduzione.
- Un'app per l'attività fisica che registra l'esecuzione di un utente in un servizio in primo piano, dopo ricevere l'autorizzazione dall'utente. La notifica potrebbe mostrare la distanza percorso dall'utente durante la sessione di fitness corrente.
Usa un servizio in primo piano solo quando la tua app deve eseguire un'attività che sia evidente dall'utente, anche quando non interagisce direttamente con l'app. Se l'azione è di scarsa importanza da voler utilizzare un priorità minima, creare uno sfondo un'attività.
Questo documento descrive l'autorizzazione richiesta per utilizzare i servizi in primo piano. e come avviare un servizio in primo piano e rimuoverlo dallo sfondo. Inoltre, descrive come associare determinati casi d'uso ai tipi di servizi in primo piano e Le limitazioni dell'accesso che vengono applicate all'avvio di un servizio in primo piano. da un'app in esecuzione in background.
L'utente può ignorare la notifica per impostazione predefinita
A partire da Android 13 (livello API 33), gli utenti possono ignorare la notifica associati a un servizio in primo piano per impostazione predefinita. Per farlo, gli utenti devono scorrere gesto sulla notifica. Tradizionalmente, la notifica non viene ignorato a meno che il servizio in primo piano non venga interrotto o rimosso in primo piano.
Se vuoi che la notifica non possa essere ignorata dall'utente, supera
true
in setOngoing()
quando crei la notifica utilizzando Notification.Builder
.
Servizi che mostrano immediatamente una notifica
Se un servizio in primo piano presenta almeno una delle seguenti caratteristiche, mostra la notifica associata subito dopo l'avvio del servizio anche sui dispositivi con Android 12 o versioni successive:
- Il servizio è associato a una notifica che include azione pulsanti.
- Il servizio include
foregroundServiceType
dimediaPlayback
,mediaProjection
oppurephoneCall
. - Il servizio fornisce un caso d'uso relativo alle telefonate, alla navigazione o ai contenuti multimediali riproduzione, come definito nella categoria della notifica .
- Il servizio ha disattivato la modifica del comportamento trasmettendolo
FOREGROUND_SERVICE_IMMEDIATE
insetForegroundServiceBehavior()
durante la configurazione della notifica.
Su Android 13 (livello API 33) o versioni successive, se l'utente nega il autorizzazione alle notifiche, continuerà a ricevere notifiche relative ai servizi in primo piano Task Manager ma non nel riquadro a scomparsa delle notifiche.
Dichiara i servizi in primo piano nel tuo file manifest
Nel file manifest dell'app, dichiara ciascuno dei servizi in primo piano dell'app
con una <service>
. Per ogni servizio, utilizza un'etichetta
Attributo android:foregroundServiceType
per dichiarare il tipo di lavoro svolto dal servizio.
Ad esempio, se la tua app crea un servizio in primo piano per riprodurre musica, potrebbe dichiarare il servizio nel seguente modo:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<application ...>
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="false">
</service>
</application>
</manifest>
Se i vari tipi si applicano al servizio, separali con il |
operatore. Ad esempio, un servizio che utilizza fotocamera e microfono
lo dichiarerebbe nel seguente modo:
android:foregroundServiceType="camera|microphone"
Richiedi le autorizzazioni per i servizi in primo piano
App destinate ad Android 9 (livello API 28) o versioni successive che utilizzano servizi in primo piano
devi richiedere
FOREGROUND_SERVICE
nel file manifest dell'app, come mostrato nello snippet di codice riportato di seguito. È un comportamento normale
autorizzazione, in modo che il sistema
la concede automaticamente all'app richiedente.
Inoltre, se l'app ha come target il livello API 34 o un livello superiore, deve richiedere
il tipo di autorizzazione appropriato per il tipo di lavoro che verrà eseguito dal servizio in primo piano
facendo. Ogni tipo di servizio in primo piano
è associato a un tipo di autorizzazione. Ad esempio, se un'app avvia una
servizio in primo piano che utilizza la fotocamera, devi richiedere sia il servizio
FOREGROUND_SERVICE
e FOREGROUND_SERVICE_CAMERA
autorizzazioni aggiuntive. Queste sono tutte autorizzazioni normali, quindi il sistema le concede
automaticamente se sono elencate nel file manifest.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA"/>
<application ...>
...
</application>
</manifest>
Prerequisiti per i servizi in primo piano
A partire da Android 14 (livello API 34), quando avvii un servizio in primo piano:
il sistema verifica la presenza di prerequisiti specifici in base al tipo di servizio. Ad esempio:
se provi ad avviare un servizio in primo piano di tipo location
, il sistema controlla
per assicurarti che la tua app abbia già ACCESS_COARSE_LOCATION
Autorizzazione ACCESS_FINE_LOCATION
. In caso contrario, il sistema genera
SecurityException
Per questo motivo, devi confermare che i prerequisiti richiesti siano soddisfatti prima di avviare un servizio in primo piano. Il servizio in primo piano documentazione elenca i prerequisiti richiesti per ogni tipo di servizio in primo piano.
Avviare un servizio in primo piano
Prima di richiedere al sistema di eseguire un servizio come servizio in primo piano, avvia il servizio stesso:
Kotlin
val intent = Intent(...) // Build the intent for the service context.startForegroundService(intent)
Java
Context context = getApplicationContext(); Intent intent = new Intent(...); // Build the intent for the service context.startForegroundService(intent);
All'interno del servizio, solitamente a onStartCommand()
, puoi richiedere
che il tuo servizio viene eseguito in primo piano. A questo scopo, chiama
ServiceCompat.startForeground()
(disponibile in Androidx-core 1.12 e successivi). Questo metodo prevede le seguenti
parametri:
- Il servizio
- Un numero intero positivo che identifica in modo univoco la notifica nella barra di stato
- L'oggetto
Notification
stesso - I tipi di servizi in primo piano identificando il lavoro svolto dal servizio
Questi tipi potrebbero essere un sottoinsieme dei tipi dichiarati nel file manifest,
a seconda del caso d'uso specifico. Se poi devi aggiungere altri tipi di servizi,
puoi chiamare di nuovo startForeground()
.
Ad esempio, supponiamo che un'app per l'attività fisica esegua un servizio di tracker della corsa che
ha bisogno di informazioni su location
, ma potrebbe o meno avere bisogno di riprodurre contenuti multimediali. Tu
devono dichiarare sia location
sia mediaPlayback
nel file manifest. Se
l'utente avvia una corsa e vuole solo che la propria posizione venga monitorata, l'app deve chiamare
startForeground()
e trasmetti solo l'autorizzazione ACCESS_FINE_LOCATION
. Poi,
se l'utente vuole iniziare a riprodurre l'audio, chiama di nuovo startForeground()
e
passare la combinazione di bit a bit di tutti i tipi di servizi in primo piano (in questo caso,
ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK
).
Ecco un esempio che avvia un servizio in primo piano della fotocamera:
Kotlin
class MyCameraService: Service() { private fun startForeground() { // Before starting the service as foreground check that the app has the // appropriate runtime permissions. In this case, verify that the user has // granted the CAMERA permission. val cameraPermission = PermissionChecker.checkSelfPermission(this, Manifest.permission.CAMERA) if (cameraPermission != PermissionChecker.PERMISSION_GRANTED) { // Without camera permissions the service cannot run in the foreground // Consider informing user or updating your app UI if visible. stopSelf() return } try { val notification = NotificationCompat.Builder(this, "CHANNEL_ID") // Create the notification to display while the service is running .build() ServiceCompat.startForeground( /* service = */ this, /* id = */ 100, // Cannot be 0 /* notification = */ notification, /* foregroundServiceType = */ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA } else { 0 }, ) } catch (e: Exception) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e is ForegroundServiceStartNotAllowedException) { // App not in a valid state to start foreground service // (e.g. started from bg) } // ... } } }
Java
public class MyCameraService extends Service { private void startForeground() { // Before starting the service as foreground check that the app has the // appropriate runtime permissions. In this case, verify that the user // has granted the CAMERA permission. int cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA); if (cameraPermission == PackageManager.PERMISSION_DENIED) { // Without camera permissions the service cannot run in the // foreground. Consider informing user or updating your app UI if // visible. stopSelf(); return; } try { Notification notification = new NotificationCompat.Builder(this, "CHANNEL_ID") // Create the notification to display while the service // is running .build(); int type = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { type = ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; } ServiceCompat.startForeground( /* service = */ this, /* id = */ 100, // Cannot be 0 /* notification = */ notification, /* foregroundServiceType = */ type ); } catch (Exception e) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e instanceof ForegroundServiceStartNotAllowedException ) { // App not in a valid state to start foreground service // (e.g started from bg) } // ... } } //... }
Rimuovere un servizio dal primo piano
Per rimuovere il servizio dal primo piano, chiama
stopForeground()
Questo metodo utilizza un valore booleano che indica se rimuovere la barra di stato
notifica. Tieni presente che il servizio continua a essere eseguito.
Se interrompi il servizio mentre viene eseguito in primo piano, la relativa notifica viene rimosso.
Gestire l'interruzione avviata dall'utente delle app che eseguono servizi in primo piano
A partire da Android 13 (livello API 33), gli utenti possono completare un flusso di lavoro dalla riquadro delle notifiche a scomparsa per interrompere un'app con servizi in primo piano in esecuzione, a prescindere dal versione SDK target. Questo invito, chiamato Task Manager mostra un elenco di app è attualmente in esecuzione un servizio in primo piano.
Questo elenco è denominato App attive. Accanto a ogni app c'è un pulsante Interrompi. La Figura 1 illustra la Flusso di lavoro di Task Manager su un dispositivo in esecuzione Android 13.
Quando l'utente preme il pulsante Interrompi accanto alla tua app nella schermata Task Manager, verranno eseguite le seguenti azioni:
- Il sistema rimuove l'app dalla memoria. Pertanto, l'intera app si interrompe del servizio in primo piano in esecuzione.
- Il sistema rimuove lo stack di attività dell'app.
- La riproduzione dei contenuti multimediali si interrompe.
- La notifica associata al servizio in primo piano viene rimossa.
- L'app rimane nella cronologia.
- I job pianificati vengono eseguiti all'orario pianificato.
- Le sveglie suonano nell'orario o nella finestra temporale programmata.
Per verificare che l'app si comporti come previsto durante e dopo che l'utente ha interrotto esegui questo comando ADB in una finestra del terminale:
adb shell cmd activity stop-app PACKAGE_NAME
Esenzioni
Il sistema prevede diversi livelli di esenzioni per alcuni tipi di app, descritti nelle sezioni seguenti.
Le esenzioni si intendono per app, non per processo. Se il sistema esclude un processo in una , anche tutti gli altri processi in quell'app sono esenti.
Esenzioni dalla visualizzazione in Task Manager
Le seguenti app possono eseguire un servizio in primo piano e non vengono visualizzate nella Task Manager:
- App a livello di sistema
- App per la sicurezza; ovvero le app con
Ruolo
ROLE_EMERGENCY
- I dispositivi che si trovano in modalità demo
Esenzioni dovute all'interruzione dell'accesso da parte degli utenti
Quando i seguenti tipi di app eseguono un servizio in primo piano, vengono visualizzati nella Task Manager, ma non è presente un pulsante Interrompi accanto nome dell'app che l'utente deve toccare:
- App del proprietario del dispositivo
- Proprietario del profilo app
- App permanenti
- Le app con
Ruolo
ROLE_DIALER
Usa API create ad hoc anziché servizi in primo piano
Per molti casi d'uso, esistono API Jetpack o piattaforme che è possibile usare per lavorare altrimenti utilizzeresti un servizio in primo piano. Se è disponibile un'API mirata, dovresti usarla quasi sempre anziché un'API in primo piano completamente gestito di Google Cloud. Le API dedicate spesso forniscono ulteriori casi d'uso specifici che altrimenti dovreste sviluppare in autonomia. Ad esempio: l' API Bubbles gestisce la logica UI complessa per app di messaggistica che devono implementare funzionalità di fumetti di chat.
La documentazione per gli elenchi dei tipi di servizi in primo piano valide alternative da utilizzare al posto dei servizi in primo piano.
Limitazioni relative all'avvio di un servizio in primo piano in background
Le app destinate ad Android 12 o versioni successive non possono essere avviate in primo piano
quando l'app è in esecuzione in background, ad eccezione di alcuni servizi speciali
di assistenza. Se un'app tenta di avviare
servizio in primo piano mentre l'app viene eseguita in background e
di servizio non soddisfa uno dei casi eccezionali, il sistema genera un
ForegroundServiceStartNotAllowedException
Inoltre, se un'app vuole avviare un servizio in primo piano che deve Autorizzazioni durante l'uso (ad esempio, sensore del corpo, fotocamera, microfono o posizione autorizzazioni), non può creare il servizio mentre l'app è in background, anche se l'app rientra in una delle esenzioni dall'avvio in background limitazioni. Il motivo è spiegato nella sezione Restrizioni relative alla avvio di servizi in primo piano che richiedono in uso autorizzazioni.
Esenzioni dalle limitazioni relative all'avvio in background
Nelle seguenti situazioni, la tua app può avviare servizi in primo piano anche mentre la tua app viene eseguita in background:
- La transizione dell'app da uno stato visibile all'utente, ad esempio un attività.
- L'app può avviare un'attività dal sfondo, ad eccezione del caso, in cui l'app ha un'attività nello stack posteriore di un'attività esistente.
La tua app riceve un messaggio ad alta priorità utilizzando Firebase Cloud Messaggi.
L'utente esegue un'azione su un elemento UI relativo alla tua app. Ad esempio: potrebbero interagire con una bolla, notifica, widget o attività.
La tua app attiva una sveglia esatta per completare un'azione richiesta dall'utente.
La tua app è l'input attuale del dispositivo .
La tua app riceve un evento correlato a geofencing o attività di riconoscimento facciale.
Dopo che il dispositivo si riavvia e ha ricevuto il
ACTION_BOOT_COMPLETED
,ACTION_LOCKED_BOOT_COMPLETED
, oppureACTION_MY_PACKAGE_REPLACED
un'azione intent in un ricevitore di trasmissione.La tua app riceve
ACTION_TIMEZONE_CHANGED
,ACTION_TIME_CHANGED
, oACTION_LOCALE_CHANGED
un'azione intent in un broadcast receiver.La tua app riceve
ACTION_TRANSACTION_DETECTED
evento daNfcService
.App con determinati ruoli di sistema o autorizzazioni, ad esempio dispositivo proprietari e profilo proprietari.
La tua app utilizza Gestione dispositivi companion e dichiara i
REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
: o l'autorizzazioneREQUEST_COMPANION_RUN_IN_BACKGROUND
autorizzazione. Se possibile, utilizzaREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
.La tua app contiene
SYSTEM_ALERT_WINDOW
autorizzazione.L'utente disattiva le ottimizzazioni della batteria per la tua app.
Limitazioni relative all'avvio di servizi in primo piano che richiedono autorizzazioni durante l'uso
Su Android 14 (livello API 34) o versioni successive, devi tenere presente situazioni speciali o se si sta avviando un servizio in primo piano che ha bisogno di autorizzazioni durante l'uso.
Se la tua app ha come target Android 14 o versioni successive, il sistema operativo
verifica quando crei un servizio in primo piano per assicurarti che l'app abbia tutti
le autorizzazioni appropriate
per quel tipo di servizio. Ad esempio, quando crei un'immagine
servizio in primo piano di tipo
microfono, il sistema
di sistema verifica che l'app abbia
RECORD_AUDIO
:
autorizzazione. Se non disponi di questa autorizzazione, il sistema genera un
SecurityException
Per quanto riguarda le autorizzazioni durante l'uso, è possibile che si verifichino problemi. Se la tua app include
l'autorizzazione durante l'uso, ha quell'autorizzazione solo mentre si trova
in primo piano. Ciò significa che se la tua app è in background e prova a creare
a un servizio in primo piano di tipo fotocamera, posizione o microfono, il sistema rileva
che la tua app non dispone attualmente delle autorizzazioni necessarie e viene generato un
SecurityException
.
Analogamente, se l'app è in background e crea un
servizio sanitario che richiede l'autorizzazione BODY_SENSORS_BACKGROUND
, l'app
al momento non dispone di questa autorizzazione e il sistema genera un'eccezione.
Questo non vale se si tratta di un servizio sanitario che richiede autorizzazioni diverse,
come ACTIVITY_RECOGNITION
.) La chiamata
PermissionChecker.checkSelfPermission()
non evita questo problema. Se la tua app ha un'autorizzazione "Durante l'uso"
chiama checkSelfPermission()
per verificare se dispone di quell'autorizzazione, il metodo
restituisce PERMISSION_GRANTED
anche se l'app è in background. Quando
restituisce PERMISSION_GRANTED
, significa che la tua app ha questa autorizzazione
mentre l'app è in uso".
Per questo motivo, se il servizio in primo piano ha bisogno di un'autorizzazione durante l'uso,
deve chiamare Context.startForegroundService()
o Context.bindService()
mentre
la tua app ha un'attività visibile, a meno che il servizio non rientri in una delle
esenzioni definite.
Esenzioni dalle limitazioni relative alle autorizzazioni durante l'uso
In alcune situazioni, anche se un servizio in primo piano viene avviato mentre l'app esecuzioni in background, può comunque accedere alla posizione, Informazioni sulla fotocamera e sul microfono quando l'app è in esecuzione in primo piano ("durante l'uso").
In queste stesse situazioni, se il servizio dichiara un
tipo di servizio in primo piano di location
e viene avviato da un'app che
ha
ACCESS_BACKGROUND_LOCATION
l'autorizzazione, questo servizio può accedere sempre ai dati sulla posizione, anche quando
l'app viene eseguita in background.
Il seguente elenco contiene le seguenti situazioni:
- Un componente di sistema avvia il servizio.
- Il servizio inizia interagendo con l'app widget.
- Il servizio inizia interagendo con una notifica.
- Il servizio inizia come
PendingIntent
inviata da un un'altra app visibile. - Il servizio viene avviato da un'app che è un criterio relativo ai dispositivi un controller in modalità proprietario del dispositivo.
- Il servizio viene avviato da un'app che fornisce l'
VoiceInteractionService
. - Il servizio viene avviato da un'app che ha
Autorizzazione con privilegi
START_ACTIVITIES_FROM_BACKGROUND
.
Determina quali servizi sono interessati nella tua app
Quando testi la tua app, avvia i relativi servizi in primo piano. Se un servizio avviato ha accesso limitato a posizione, microfono e fotocamera, il seguente messaggio viene visualizzato in Logcat:
Foreground service started from background can not have \ location/camera/microphone access: service SERVICE_NAME