Dienste im Vordergrund

Dienste im Vordergrund führen Vorgänge aus, die für den Nutzer sichtbar sind.

Für Dienste im Vordergrund wird 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 Musikplayer-App, die Musik in einem Dienst im Vordergrund abspielt. In der Benachrichtigung wird möglicherweise der aktuell abgespielte Titel angezeigt.
  • Eine Fitness-App, die den Betrieb eines Nutzers in einem Dienst im Vordergrund aufzeichnet, nachdem er die Berechtigung vom Nutzer erhalten hat. Die Benachrichtigung kann die Strecke anzeigen, die der Nutzer während der aktuellen Fitnesssitzung zurückgelegt hat.

Verwenden Sie einen Dienst im Vordergrund nur dann, wenn Ihre App eine Aufgabe ausführen muss, die für den Nutzer erkennbar ist, auch wenn er nicht direkt mit der App interagiert. Wenn die Aktion von zu wenig Wichtigkeit ist, sodass Sie eine Benachrichtigung mit minimaler Priorität verwenden möchten, erstellen Sie stattdessen eine Hintergrundaufgabe.

In diesem Dokument wird die erforderliche Berechtigung zum Verwenden von Diensten im Vordergrund beschrieben. Außerdem wird beschrieben, wie Sie einen Dienst im Vordergrund starten und aus dem Hintergrund entfernen. Außerdem wird beschrieben, wie bestimmte Anwendungsfälle mit Typen von Diensten im Vordergrund verknüpft werden und welche Zugriffsbeschränkungen gelten, wenn Sie einen Dienst im Vordergrund über eine App starten, die im Hintergrund ausgeführt wird.

Der Nutzer darf Benachrichtigungen standardmäßig schließen

Ab Android 13 (API-Level 33) können Nutzer die mit einem Dienst im Vordergrund verknüpfte Benachrichtigung standardmäßig schließen. Dazu führen sie eine Wischgeste in der Benachrichtigung aus. Üblicherweise wird die Benachrichtigung nur dann geschlossen, wenn der Dienst im Vordergrund entweder angehalten oder aus dem Vordergrund entfernt wird.

Wenn Sie möchten, dass der Nutzer die Benachrichtigung nicht schließen kann, übergeben Sie true an die Methode setOngoing(), wenn Sie die Benachrichtigung mit Notification.Builder erstellen.

Dienste, bei denen sofort eine Benachrichtigung angezeigt wird

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:

Wenn der Nutzer unter Android 13 (API-Level 33) oder höher die Berechtigung für Benachrichtigungen ablehnt, sieht er weiterhin Hinweise zu Diensten im Vordergrund im Task-Manager, die jedoch nicht auf der Benachrichtigungsleiste angezeigt werden.

Dienste im Vordergrund im Manifest deklarieren

Deklarieren Sie im Manifest Ihrer App jeden Dienst im Vordergrund Ihrer App mit einem <service>-Element. Verwenden Sie für jeden Dienst ein android:foregroundServiceType-Attribut, um zu deklarieren, welche Art von Arbeit der Dienst übernimmt.

Wenn Ihre App beispielsweise einen Dienst im Vordergrund erstellt, über den Musik wiedergegeben wird, können Sie diesen Dienst wie folgt 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 auf Ihren Dienst zutreffen, trennen Sie sie durch den Operator |. Ein Dienst, der Kamera und Mikrofon verwendet, würde dies zum Beispiel so deklarieren:

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 im App-Manifest FOREGROUND_SERVICE anfordern, wie im folgenden Code-Snippet gezeigt. Dies ist eine normale Berechtigung, die vom System der anfragenden App automatisch erteilt wird.

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ührt. Für jeden Typ von Diensten im Vordergrund gibt es einen entsprechenden Berechtigungstyp. Wenn eine App beispielsweise einen Dienst im Vordergrund startet, der die Kamera verwendet, müssen Sie die Berechtigungen FOREGROUND_SERVICE und FOREGROUND_SERVICE_CAMERA anfordern. Das sind alles normale Berechtigungen, die vom System automatisch gewährt werden, 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

Wenn Sie einen Dienst im Vordergrund starten, sucht das System ab Android 14 (API-Level 34) je nach Diensttyp nach bestimmten Voraussetzungen. Wenn Sie beispielsweise versuchen, einen Dienst im Vordergrund vom Typ location zu starten, prüft das System, ob Ihre App bereits die Berechtigung ACCESS_COARSE_LOCATION oder ACCESS_FINE_LOCATION hat. Andernfalls gibt das System SecurityException aus.

Aus diesem Grund müssen Sie bevor Sie einen Dienst im Vordergrund starten, um zu prüfen, ob die erforderlichen Voraussetzungen erfüllt sind. In der Dokumentation zu Arten von Diensten im Vordergrund sind die erforderlichen Voraussetzungen für jeden Typ von Diensten im Vordergrund 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 können Sie normalerweise in onStartCommand() anfordern, dass Ihr Dienst im Vordergrund ausgeführt wird. Rufen Sie dazu ServiceCompat.startForeground() auf (verfügbar in androidx-core 1.12 und höher). Diese Methode verwendet folgende 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 geleistete Arbeit identifizieren

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 führt einen Lauf-Tracker-Dienst aus, der immer location-Informationen benötigt, aber möglicherweise nicht Medien wiedergeben muss. Du musst im Manifest sowohl location als auch mediaPlayback deklarieren. Wenn ein Nutzer einen Lauf startet und nur möchte, dass sein Standort erfasst wird, sollte deine App startForeground() aufrufen und nur die Berechtigung ACCESS_FINE_LOCATION übergeben. Wenn der Nutzer dann die Audiowiedergabe starten möchte, rufen Sie noch einmal startForeground() auf und übergeben Sie die bitweise Kombination aller Typen von Diensten im Vordergrund (in diesem Fall ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK).

Hier ist ein Beispiel, mit dem ein Dienst im Vordergrund gestartet wird:

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 =
            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 {
        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 verwendet einen booleschen Wert, der angibt, ob die Statusleistenbenachrichtigung ebenfalls entfernt werden soll. Der Dienst wird weiterhin ausgeführt.

Wenn Sie den Dienst beenden, während er im Vordergrund ausgeführt wird, wird die Benachrichtigung entfernt.

Vom Nutzer initiiertes Beenden von Apps verarbeiten, auf denen Dienste im Vordergrund ausgeführt werden

Unten auf der Benachrichtigungsleiste befindet sich eine Schaltfläche mit der Anzahl der Apps, die derzeit im Hintergrund ausgeführt werden. Wenn Sie auf diese Schaltfläche klicken, wird ein Dialogfeld mit den Namen verschiedener Apps angezeigt. Die Stopp-Schaltfläche befindet sich rechts neben jeder App.
Abbildung 1: Task-Manager-Workflow auf Geräten mit Android 13 oder höher.

Ab Android 13 (API-Level 33) können Nutzer über die Benachrichtigungsleiste einen Workflow ausführen, um eine App mit laufenden Diensten im Vordergrund zu beenden, unabhängig von der SDK-Zielversion der App. Dieses Angebot wird als Task-Manager bezeichnet und enthält eine Liste von Anwendungen, in denen derzeit ein Dienst im Vordergrund ausgeführt wird.

Diese Liste trägt die Bezeichnung Aktive Apps. Neben jeder App befindet sich eine Schaltfläche Beenden. Abbildung 1 zeigt den Task-Manager-Workflow auf einem Android 13-Gerät.

Wenn der Nutzer im Task-Manager neben Ihrer Anwendung auf die Schaltfläche Stopp drückt, werden folgende Aktionen ausgeführt:

  • Das System entfernt Ihre App aus dem Arbeitsspeicher. Daher wird Ihre gesamte Anwendung beendet, nicht nur der laufende Dienst im Vordergrund.
  • Das System entfernt den Aktivitäten-Back-Stack Ihrer App.
  • Die Medienwiedergabe wird beendet.
  • Die mit dem Dienst im Vordergrund verknüpfte Benachrichtigung wird entfernt.
  • Ihre App bleibt im Verlauf.
  • Geplante Jobs werden zum geplanten Zeitpunkt ausgeführt.
  • Alarme werden zur geplanten Zeit oder zu der geplanten Zeit ausgelöst.

Führen Sie den folgenden ADB-Befehl in einem Terminalfenster aus, um zu testen, ob sich Ihre Anwendung beim Beenden und nach dem Beenden einer Anwendung wie erwartet verhält:

adb shell cmd activity stop-app PACKAGE_NAME

Ausnahmen

Das System bietet mehrere Ausnahmen für bestimmte Arten von Anwendungen, die in den folgenden Abschnitten beschrieben werden.

Ausnahmen gelten pro App, nicht pro Prozess. Wenn das System einen Prozess in einer Anwendung ausnimmt, werden auch alle anderen Prozesse in dieser Anwendung davon ausgenommen.

Ausnahmen für die Anzeige im Task-Manager

Die folgenden Apps können einen Dienst im Vordergrund ausführen und werden nicht im Task-Manager angezeigt:

Ausnahmen von der Stoppfunktion für Nutzer

Wenn die folgenden Arten von Apps einen Dienst im Vordergrund ausführen, werden sie zwar im Task-Manager angezeigt, aber neben dem Namen der App befindet sich keine Schaltfläche Beenden, auf die der Nutzer tippen kann:

Zweckbestimmte APIs anstelle von Diensten im Vordergrund verwenden

Für viele Anwendungsfälle gibt es Plattform- oder Jetpack-APIs, die Sie für Aufgaben verwenden können, für die Sie andernfalls einen Dienst im Vordergrund verwenden würden. Wenn es eine geeignete zweckgebundene API gibt, sollten Sie diese fast immer anstelle eines Diensts im Vordergrund verwenden. Speziell entwickelte APIs bieten oft zusätzliche anwendungsfallspezifische Funktionen, die Sie andernfalls selbst erstellen müssten. Die Bubbles API verarbeitet beispielsweise die komplexe UI-Logik für Nachrichtenanwendungen, die Sprechblasenfunktionen implementieren müssen.

In der Dokumentation für die Typen von Diensten im Vordergrund finden Sie gute Alternativen, die Sie anstelle von Diensten im Vordergrund verwenden können.

Einschränkungen beim Starten eines Diensts im Vordergrund aus dem Hintergrund

Bei Apps, die auf Android 12 oder höher ausgerichtet sind, können abgesehen von einigen Sonderfällen keine Dienste im Vordergrund gestartet werden, während sie im Hintergrund ausgeführt werden. 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 Ausnahmen erfüllt, gibt das System ein ForegroundServiceStartNotAllowedException aus.

Wenn eine App einen Dienst im Vordergrund starten möchte, für den Berechtigungen für während der Nutzung erforderlich sind (z. B. Berechtigungen für Körpersensor, Kamera, Mikrofon oder Standort), kann sie den Dienst nicht erstellen, solange die App im Hintergrund ausgeführt wird. Das gilt auch dann, wenn die App unter eine der Ausnahmen von Einschränkungen beim Start im Hintergrund fällt. Der Grund dafür wird im Abschnitt Einschränkungen beim Starten von Diensten im Vordergrund, die während der Verwendung Berechtigungen benötigen erläutert.

Ausnahmen von Einschränkungen beim Starten im Hintergrund

In den folgenden Situationen kann Ihre App Dienste im Vordergrund starten, auch wenn sie im Hintergrund ausgeführt wird:

Einschränkungen beim Starten von Diensten im Vordergrund, die Berechtigungen während der Verwendung benötigen

Unter Android 14 (API-Level 34) und höher gibt es besondere Situationen, die du beachten solltest, wenn du einen Dienst im Vordergrund startest, der während der Verwendung Berechtigungen benötigt.

Wenn Ihre App auf Android 14 oder höher ausgerichtet ist, prüft das Betriebssystem beim Erstellen eines Diensts im Vordergrund, ob Ihre App alle erforderlichen Berechtigungen für diesen Diensttyp hat. Wenn Sie beispielsweise einen Dienst im Vordergrund vom Typ Mikrofon erstellen, überprüft das Betriebssystem, ob Ihre App derzeit die Berechtigung RECORD_AUDIO hat. Wenn Sie diese Berechtigung nicht haben, gibt das System einen SecurityException aus.

Bei Berechtigungen, die gerade verwendet werden, verursacht dies ein potenzielles Problem. Wenn Ihre App eine Berechtigung während der Nutzung hat, hat sie nur diese Berechtigung, während sie sich im Vordergrund befindet. Wenn Ihre App also im Hintergrund läuft 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 gibt eine SecurityException aus.

Wenn Ihre App im Hintergrund ausgeführt wird und einen Gesundheitsdienst erstellt, der die Berechtigung BODY_SENSORS_BACKGROUND benötigt, verfügt die App derzeit nicht über diese Berechtigung und das System gibt eine Ausnahme aus. (Dies gilt nicht, wenn es sich um einen Gesundheitsdienst handelt, der andere Berechtigungen benötigt, z. B. ACTIVITY_RECOGNITION.) Das Aufrufen von ContextCompat.checkSelfPermission() verhindert dieses Problem nicht. Wenn Ihre App eine Berechtigung während der Nutzung 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, wird angezeigt, dass Ihre App diese Berechtigung hat, während die App verwendet wird.

Wenn für Ihren Dienst im Vordergrund während der Verwendung eine Berechtigung benötigt wird, müssen Sie daher Context.startForegroundService() oder Context.bindService() aufrufen, solange Ihre App eine sichtbare Aktivität aufweist, es sei denn, der Dienst fällt unter eine der definierten Ausnahmen.

Ausnahmen von Einschränkungen für Berechtigungen während der Verwendung

In einigen Situationen kann ein Dienst im Vordergrund, während die App im Hintergrund ausgeführt wird, weiterhin auf Standort-, Kamera- und Mikrofoninformationen zugreifen, während die App im Vordergrund ausgeführt wird („während der Verwendung“).

Wenn der Dienst in den gleichen Situationen den Diensttyp im Vordergrund als location deklariert und von einer App mit der Berechtigung ACCESS_BACKGROUND_LOCATION gestartet wird, kann dieser Dienst jederzeit auf Standortinformationen zugreifen, auch wenn die App im Hintergrund ausgeführt wird.

In der folgenden Liste sind diese Situationen aufgeführt:

  • Der Dienst wird durch eine Systemkomponente gestartet.
  • Der Dienst beginnt mit der Interaktion mit App-Widgets.
  • Zuerst interagiert der Dienst mit einer Benachrichtigung.
  • Der Dienst startet als PendingIntent, das von einer anderen, sichtbaren Anwendung gesendet wird.
  • Der Dienst wird von einer App gestartet, die ein Device Policy Controller ist, der im Modus „Geräteeigentümer“ ausgeführt wird.
  • Der Dienst startet von einer App, die VoiceInteractionService bereitstellt.
  • Der Dienst wird von einer Anwendung gestartet, die die privilegierte Berechtigung START_ACTIVITIES_FROM_BACKGROUND hat.
Herausfinden, welche Dienste in der Anwendung betroffen sind

Starten Sie beim Testen der App die Dienste im Vordergrund. Wenn ein gestarteter Dienst eingeschränkten Zugriff auf Standort, Mikrofon und Kamera hat, wird die folgende Meldung in Logcat angezeigt:

Foreground service started from background can not have \
location/camera/microphone access: service SERVICE_NAME