Dienste im Vordergrund

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:

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:

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

Unten im Benachrichtigungs-Schieberegler sehen Sie eine Schaltfläche, auf der die Anzahl der Apps angezeigt wird, die derzeit im Hintergrund ausgeführt werden. Wenn Sie diese Schaltfläche drücken, wird ein Dialogfeld mit den Namen verschiedener Apps angezeigt. Die Schaltfläche „Beenden“ 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 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:

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:

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