Dienste im Vordergrund führen Vorgänge aus, die für den Nutzer sichtbar sind.
Dienste im Vordergrund werden durch eine Benachrichtigung in der Statusleiste angezeigt, um Nutzer darauf hinzuweisen, dass Ihre App eine Aufgabe im Vordergrund ausführt und Systemressourcen verbraucht.
Beispiele für Apps, die Dienste im Vordergrund verwenden:
- Eine Musik-Player-App, die Musik in einem Dienst im Vordergrund abspielt. In der Benachrichtigung wird möglicherweise der gerade wiedergegebene Titel angezeigt.
- Eine Fitness-App, die das Training eines Nutzers in einem Dienst im Vordergrund aufzeichnet, nachdem sie die Berechtigung vom Nutzer erhalten hat. Die Benachrichtigung kann die zurückgelegte Strecke während der aktuellen Fitnesseinheit enthalten.
Verwenden Sie einen Dienst im Vordergrund nur, wenn Ihre App eine Aufgabe ausführen muss, die für den Nutzer sichtbar ist, auch wenn er nicht direkt mit der App interagiert. Wenn die Aktion so unwichtig ist, dass Sie eine Benachrichtigung mit niedriger Priorität verwenden möchten, erstellen Sie stattdessen eine Hintergrundaufgabe.
In diesem Dokument wird die erforderliche Berechtigung für die Verwendung von Diensten im Vordergrund beschrieben. Außerdem wird erläutert, wie Sie einen Dienst im Vordergrund starten und aus dem Hintergrund entfernen. Außerdem wird beschrieben, wie Sie bestimmte Anwendungsfälle mit Typen von Diensten im Vordergrund verknüpfen und welche Zugriffsbeschränkungen gelten, wenn Sie einen Dienst im Vordergrund von einer App starten, die im Hintergrund ausgeführt wird.
Nutzer können Benachrichtigungen standardmäßig schließen
Ab Android 13 (API-Ebene 33) können Nutzer die Benachrichtigung, die mit einem Dienst im Vordergrund verknüpft ist, standardmäßig schließen. Dazu wischen Nutzer über die Benachrichtigung. Normalerweise wird die Benachrichtigung erst geschlossen, wenn der Dienst im Vordergrund entweder angehalten oder aus dem Vordergrund entfernt wird.
Wenn die Benachrichtigung nicht vom Nutzer geschlossen werden soll, übergeben Sie true
an die Methode setOngoing()
, wenn Sie die Benachrichtigung mit Notification.Builder
erstellen.
Dienste, die sofort eine Benachrichtigung anzeigen
Wenn ein Dienst im Vordergrund mindestens eine der folgenden Eigenschaften hat, zeigt das System die zugehörige Benachrichtigung sofort nach dem Start des Dienstes an, auch auf Geräten mit Android 12 oder höher:
- Der Dienst ist mit einer Benachrichtigung verknüpft, die Aktionsschaltflächen enthält.
- Der Dienst hat eine
foregroundServiceType
vonmediaPlayback
,mediaProjection
oderphoneCall
. - Der Dienst bietet einen Anwendungsfall im Zusammenhang mit Telefonanrufen, Navigation oder Medienwiedergabe, wie im Attribut „Kategorie“ der Benachrichtigung definiert.
- Der Dienst hat die Verhaltensänderung deaktiviert, indem er beim Einrichten der Benachrichtigung
FOREGROUND_SERVICE_IMMEDIATE
ansetForegroundServiceBehavior()
übergeben hat.
Wenn der Nutzer unter Android 13 (API-Level 33) oder höher die Berechtigung zur Benachrichtigung ablehnt, sieht er weiterhin Benachrichtigungen zu Diensten im Vordergrund im Task-Manager, aber nicht im Benachrichtigungs-Pull-down-Menü.
Dienste im Vordergrund in Ihrem Manifest deklarieren
Deklarieren Sie im Manifest Ihrer App alle Dienste im Vordergrund mit einem <service>
-Element. Verwenden Sie für jeden Dienst ein android:foregroundServiceType
-Attribut, um anzugeben, welche Art von Arbeit der Dienst ausführt.
Wenn Ihre App beispielsweise einen Dienst im Vordergrund erstellt, der Musik abspielt, können Sie den Dienst so deklarieren:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<application ...>
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="false">
</service>
</application>
</manifest>
Wenn mehrere Typen für Ihren Dienst gelten, trennen Sie sie mit dem Operator |
. Ein Dienst, der die Kamera und das Mikrofon verwendet, würde beispielsweise so deklariert:
android:foregroundServiceType="camera|microphone"
Berechtigungen für Dienste im Vordergrund anfordern
Apps, die auf Android 9 (API-Level 28) oder höher ausgerichtet sind und Dienste im Vordergrund verwenden, müssen die FOREGROUND_SERVICE
im App-Manifest anfordern, wie im folgenden Codeausschnitt dargestellt. Da es sich um eine normale Berechtigung handelt, wird sie der anfragenden App automatisch gewährt.
Wenn die App auf API-Level 34 oder höher ausgerichtet ist, muss außerdem der entsprechende Berechtigungstyp für die Art der Arbeit angefordert werden, die der Dienst im Vordergrund ausführen wird. Jeder Typ von Dienst im Vordergrund hat einen entsprechenden Berechtigungstyp. Wenn eine App beispielsweise einen Dienst im Vordergrund startet, der die Kamera verwendet, müssen Sie sowohl die Berechtigung FOREGROUND_SERVICE
als auch FOREGROUND_SERVICE_CAMERA
anfordern. Da es sich um normale Berechtigungen handelt, werden sie vom System automatisch gewährt, wenn sie im Manifest aufgeführt sind.
<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>
Voraussetzungen für Dienste im Vordergrund
Ab Android 14 (API-Level 34) prüft das System beim Starten eines Dienstes im Vordergrund je nach Diensttyp bestimmte Voraussetzungen. Wenn Sie beispielsweise versuchen, einen Dienst vom Typ location
im Vordergrund zu starten, prüft das System, ob Ihre App bereits die Berechtigung ACCESS_COARSE_LOCATION
oder ACCESS_FINE_LOCATION
hat. Andernfalls wird SecurityException
ausgegeben.
Aus diesem Grund müssen Sie prüfen, ob die erforderlichen Voraussetzungen erfüllt sind, bevor Sie einen Dienst im Vordergrund starten. In der Dokumentation zum Typ des Diensts im Vordergrund sind die erforderlichen Voraussetzungen für jeden Typ aufgeführt.
Dienst im Vordergrund starten
Bevor Sie das System auffordern, einen Dienst als Dienst im Vordergrund auszuführen, starten Sie den Dienst selbst:
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);
Innerhalb des Dienstes, in der Regel in onStartCommand()
, können Sie angeben, dass Ihr Dienst im Vordergrund ausgeführt werden soll. Rufen Sie dazu ServiceCompat.startForeground()
auf (verfügbar in androidx-core 1.12 und höher). Diese Methode verwendet die folgenden Parameter:
- Der Dienst
- Eine positive Ganzzahl, die die Benachrichtigung in der Statusleiste eindeutig identifiziert
- Das
Notification
-Objekt selbst - Die Typen von Diensten im Vordergrund, die die vom Dienst ausgeführte Arbeit angeben
Diese Typen können je nach Anwendungsfall eine Teilmenge der im Manifest deklarierten Typen sein. Wenn Sie weitere Diensttypen hinzufügen möchten, können Sie startForeground()
noch einmal aufrufen.
Angenommen, eine Fitness-App verwendet einen Lauf-Tracker-Dienst, für den immer location
-Informationen benötigt werden, aber möglicherweise keine Medien abgespielt werden müssen. Sie müssen sowohl location
als auch mediaPlayback
im Manifest deklarieren. Wenn ein Nutzer einen Lauf startet und nur seinen Standort erfassen lassen möchte, sollte Ihre App startForeground()
aufrufen und nur die Berechtigung ACCESS_FINE_LOCATION
übergeben. Wenn der Nutzer dann die Audiowiedergabe starten möchte, rufen Sie startForeground()
noch einmal auf und übergeben Sie die binäre Kombination aller Typen von Diensten im Vordergrund (in diesem Fall ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK
).
Hier ein Beispiel für das Starten eines Kamera-Dienstes im Vordergrund:
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) } // ... } } //... }
Dienst aus dem Vordergrund entfernen
Wenn Sie den Dienst aus dem Vordergrund entfernen möchten, rufen Sie stopForeground()
auf.
Diese Methode nimmt einen booleschen Wert an, der angibt, ob auch die Benachrichtigung in der Statusleiste entfernt werden soll. Der Dienst wird weiterhin ausgeführt.
Wenn Sie den Dienst anhalten, während er im Vordergrund ausgeführt wird, wird die zugehörige Benachrichtigung entfernt.
Vom Nutzer initiiertes Beenden von Apps mit Diensten im Vordergrund verarbeiten
Ab Android 13 (API-Level 33) können Nutzer über die Benachrichtigungsleiste einen Workflow ausführen, um eine App mit laufenden Diensten im Vordergrund anzuhalten, unabhängig von der Ziel-SDK-Version der App. Diese Aufforderung, der Task-Manager, enthält eine Liste der Apps, in denen derzeit ein Dienst im Vordergrund ausgeführt wird.
Diese Liste trägt die Bezeichnung Aktive Apps. Neben jeder App befindet sich die Schaltfläche Beenden. Abbildung 1 zeigt den Workflow des Task-Managers auf einem Gerät mit Android 13.
Wenn der Nutzer im Task-Manager neben Ihrer App auf die Schaltfläche Anhalten klickt, geschieht Folgendes:
- Die App wird vom System aus dem Arbeitsspeicher entfernt. Daher wird die gesamte App angehalten, nicht nur der laufende Dienst im Vordergrund.
- Das System entfernt den Aktivitätsrückstapel Ihrer App.
- Die Medienwiedergabe wird beendet.
- Die Benachrichtigung, die mit dem Dienst im Vordergrund verknüpft ist, wird entfernt.
- Ihre App bleibt im Verlauf.
- Geplante Jobs werden zum geplanten Zeitpunkt ausgeführt.
- Wecker klingeln zum geplanten Zeitpunkt oder innerhalb des geplanten Zeitraums.
Wenn Sie testen möchten, ob sich Ihre App während und nach dem Beenden durch einen Nutzer wie erwartet verhält, führen Sie in einem Terminalfenster den folgenden ADB-Befehl aus:
adb shell cmd activity stop-app PACKAGE_NAME
Ausnahmen
Das System bietet mehrere Befreiungsstufen für bestimmte Arten von Apps, die in den folgenden Abschnitten beschrieben werden.
Ausnahmen gelten pro App, nicht pro Prozess. Wenn das System einen Prozess in einer App ausnimmt, sind auch alle anderen Prozesse in dieser App ausgenommen.
Ausnahmen, die nicht im Task-Manager angezeigt werden
Die folgenden Apps können einen Dienst im Vordergrund ausführen und werden im Task-Manager nicht angezeigt:
- Apps auf Systemebene
- Sicherheits-Apps, d. h. Apps mit der Rolle
ROLE_EMERGENCY
- Geräte, die sich im Demomodus befinden
Ausnahmen von der Möglichkeit, dass Nutzer die Datenerhebung beenden können
Wenn die folgenden Arten von Apps einen Dienst im Vordergrund ausführen, werden sie im Task-Manager angezeigt. Neben dem Namen der App ist jedoch keine Schaltfläche Beenden zu sehen, auf die Nutzer tippen können:
- Apps vom Geräteeigentümer
- Profilinhaber Apps
- Persistente Apps
- Apps mit der Rolle
ROLE_DIALER
Spezielle APIs anstelle von Diensten im Vordergrund verwenden
Für viele Anwendungsfälle gibt es Plattform- oder Jetpack APIs, mit denen Sie Aufgaben erledigen können, für die Sie sonst einen Dienst im Vordergrund verwenden würden. Wenn es eine geeignete API gibt, sollten Sie diese fast immer anstelle eines Dienstes im Vordergrund verwenden. Speziell entwickelte APIs bieten oft zusätzliche nutzungsspezifische Funktionen, die Sie sonst selbst entwickeln müssten. Die Bubbles API verarbeitet beispielsweise die komplexe UI-Logik für Messaging-Apps, in denen Chatblasen-Funktionen implementiert werden müssen.
In der Dokumentation zu den Typen von Diensten im Vordergrund finden Sie gute Alternativen zu Diensten im Vordergrund.
Einschränkungen beim Starten eines Dienstes im Vordergrund aus dem Hintergrund
Bei Apps, die auf Android 12 oder höher ausgerichtet sind, können Dienste im Vordergrund nicht gestartet werden, während die App im Hintergrund ausgeführt wird, mit wenigen Ausnahmen. Wenn eine App versucht, einen Dienst im Vordergrund zu starten, während sie im Hintergrund ausgeführt wird, und der Dienst im Vordergrund keinen der Ausnahmefälle erfüllt, löst das System eine ForegroundServiceStartNotAllowedException
aus.
Wenn eine App außerdem einen Dienst im Vordergrund starten möchte, für den Berechtigungen für die Nutzung erforderlich sind (z. B. für Körpersensoren, Kamera, Mikrofon oder Standort), kann der Dienst nicht erstellt werden, während die App im Hintergrund ausgeführt wird. Das gilt auch, wenn die App eine der Ausnahmen von den Einschränkungen für den Start im Hintergrund erfüllt. Der Grund dafür wird im Abschnitt Einschränkungen beim Starten von Diensten im Vordergrund, für die Berechtigungen für die Nutzung erforderlich sind erläutert.
Ausnahmen von Einschränkungen beim Start im Hintergrund
In den folgenden Fällen kann Ihre App Dienste im Vordergrund starten, auch wenn sie im Hintergrund ausgeführt wird:
- Ihre App wechselt von einem für Nutzer sichtbaren Status, z. B. einer Aktivität.
- Ihre App kann eine Aktivität aus dem Hintergrund starten, es sei denn, die App hat eine Aktivität im Backstack einer vorhandenen Aufgabe.
Ihre App empfängt eine Nachricht mit hoher Priorität über Firebase Cloud Messaging.
Der Nutzer führt eine Aktion auf einem UI-Element aus, das sich auf Ihre App bezieht. Er kann beispielsweise mit einer Bubble, einer Benachrichtigung, einem Widget oder einer Aktivität interagieren.
Ihre App ruft einen genauen Wecker auf, um eine vom Nutzer angeforderte Aktion auszuführen.
Ihre App ist die aktuelle Eingabemethode des Geräts.
Ihre App empfängt ein Ereignis, das sich auf Geofencing oder den Übergang bei der Aktivitätserkennung bezieht.
Nachdem das Gerät neu gestartet wurde und die Intent-Aktion
ACTION_BOOT_COMPLETED
,ACTION_LOCKED_BOOT_COMPLETED
oderACTION_MY_PACKAGE_REPLACED
in einem Broadcast-Empfänger empfangen hat.Ihre App empfängt die Intent-Aktion
ACTION_TIMEZONE_CHANGED
,ACTION_TIME_CHANGED
oderACTION_LOCALE_CHANGED
in einem Broadcast-Empfänger.Ihre App empfängt das Ereignis
ACTION_TRANSACTION_DETECTED
vonNfcService
.Apps mit bestimmten Systemrollen oder Berechtigungen, z. B. Geräteeigentümer und Profilinhaber.
Ihre App verwendet den Companion Device Manager und deklariert die Berechtigung
REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
oder die BerechtigungREQUEST_COMPANION_RUN_IN_BACKGROUND
. Verwenden Sie nach MöglichkeitREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
.Der Nutzer deaktiviert die Akkuoptimierung für Ihre App.
Ihre App hat die Berechtigung
SYSTEM_ALERT_WINDOW
. Hinweis: Wenn Ihre App auf Android 15 oder höher ausgerichtet ist, muss sie die BerechtigungSYSTEM_ALERT_WINDOW
haben und es muss derzeit ein sichtbares Overlay-Fenster vorhanden sein.
Einschränkungen beim Starten von Diensten im Vordergrund, für die Berechtigungen für die Nutzung erforderlich sind
Unter Android 14 (API-Level 34) oder höher gibt es besondere Situationen, die Sie beachten sollten, wenn Sie einen Dienst im Vordergrund starten, für den Berechtigungen für die Nutzung erforderlich sind.
Wenn Ihre App auf Android 14 oder höher ausgerichtet ist, prüft das Betriebssystem beim Erstellen eines Dienstes im Vordergrund, ob Ihre App alle erforderlichen Berechtigungen für diesen Diensttyp hat. Wenn Sie beispielsweise einen Dienst im Vordergrund vom Typ Mikrofon erstellen, prüft das Betriebssystem, ob Ihre App derzeit die Berechtigung RECORD_AUDIO
hat. Wenn Sie diese Berechtigung nicht haben, gibt das System die Fehlermeldung SecurityException
aus.
Bei Berechtigungen, die nur während der Nutzung gelten, kann dies zu Problemen führen. Wenn Ihre App eine Berechtigung vom Typ „Während der Nutzung“ hat, hat sie diese Berechtigung nur während sie im Vordergrund ausgeführt wird. Wenn Ihre App also im Hintergrund ausgeführt wird und versucht, einen Dienst im Vordergrund vom Typ „Kamera“, „Standort“ oder „Mikrofon“ zu erstellen, erkennt das System, dass Ihre App aktuell nicht die erforderlichen Berechtigungen hat, und löst eine SecurityException
aus.
Wenn Ihre App sich im Hintergrund befindet und einen Gesundheitsdienst erstellt, für den die Berechtigung BODY_SENSORS
erforderlich ist, hat die App diese Berechtigung derzeit nicht und das System löst eine Ausnahme aus.
Dies gilt nicht für Gesundheitsdienste, für die andere Berechtigungen erforderlich sind, z. B. ACTIVITY_RECOGNITION
. Das Aufrufen von PermissionChecker.checkSelfPermission()
verhindert dieses Problem nicht. Wenn Ihre App eine Berechtigung für die Nutzung während der Verwendung hat und checkSelfPermission()
aufruft, um zu prüfen, ob sie diese Berechtigung hat, gibt die Methode PERMISSION_GRANTED
zurück, auch wenn die App im Hintergrund ausgeführt wird. Wenn die Methode PERMISSION_GRANTED
zurückgibt, bedeutet das: „Ihre App hat diese Berechtigung während der Nutzung der App.“
Wenn Ihr Dienst im Vordergrund eine Berechtigung vom Typ „Während der Nutzung“ benötigt, müssen Sie Context.startForegroundService()
oder Context.bindService()
aufrufen, während in Ihrer App eine sichtbare Aktivität ausgeführt wird, es sei denn, der Dienst fällt unter eine der definierten Ausnahmen.
Ausnahmen von Einschränkungen für Berechtigungen, die während der Nutzung aktiv sind
In einigen Fällen kann ein Dienst im Vordergrund auch dann auf Standort-, Kamera- und Mikrofoninformationen zugreifen, wenn die App im Hintergrund ausgeführt wird, während die App im Vordergrund ausgeführt wird („bei Verwendung“).
In diesen Fällen kann der Dienst, wenn er einen Typ des Diensts im Vordergrund von location
deklariert und von einer App gestartet wird, die die Berechtigung ACCESS_BACKGROUND_LOCATION
hat, jederzeit auf Standortinformationen zugreifen, auch wenn die App im Hintergrund ausgeführt wird.
Die folgende Liste enthält diese Situationen:
- Eine Systemkomponente startet den Dienst.
- Der Dienst beginnt mit der Interaktion mit App-Widgets.
- Der Dienst beginnt mit der Interaktion mit einer Benachrichtigung.
- Der Dienst beginnt als
PendingIntent
, die von einer anderen sichtbaren App gesendet wird. - Der Dienst wird von einer App gestartet, die ein Device Policy Controller ist und im Modus „Geräteinhaber“ ausgeführt wird.
- Der Dienst wird von einer App gestartet, die die
VoiceInteractionService
bereitstellt. - Der Dienst wird von einer App gestartet, die die Berechtigung
START_ACTIVITIES_FROM_BACKGROUND
hat.
Ermitteln, welche Dienste in Ihrer App betroffen sind
Starten Sie beim Testen Ihrer App die Dienste im Vordergrund. Wenn ein gestarteter Dienst den Zugriff auf Standort, Mikrofon und Kamera eingeschränkt hat, wird in Logcat die folgende Meldung angezeigt:
Foreground service started from background can not have \ location/camera/microphone access: service SERVICE_NAME