Dienste im Vordergrund

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

Dienste im Vordergrund zeigen eine Benachrichtigung in der Statusleiste an, 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, sind:

  • Eine Musikplayer-App, die Musik in einem Dienst im Vordergrund abspielt. In der Benachrichtigung wird möglicherweise der aktuell abgespielte Song angezeigt.
  • Eine Fitness-App, die nach Erhalt der Berechtigung des Nutzers die Ausführung eines Nutzers in einem Dienst im Vordergrund aufzeichnet. 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 sichtbar ist, auch wenn der Nutzer nicht direkt mit der App interagiert. Wenn die Aktion so wichtig ist, dass Sie eine Benachrichtigung mit Mindestpriorität verwenden möchten, erstellen Sie stattdessen eine Hintergrundaufgabe.

In diesem Dokument wird beschrieben, welche Berechtigung für die Verwendung von Diensten im Vordergrund erforderlich ist und 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 wirksam werden, wenn Sie einen Dienst im Vordergrund über eine im Hintergrund ausgeführte App starten.

Der Nutzer kann 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 Nutzende eine Wischgeste über die Benachrichtigung durch. In der Regel wird die Benachrichtigung nur dann geschlossen, wenn der Dienst im Vordergrund angehalten oder aus dem Vordergrund entfernt wird.

Wenn Sie möchten, dass die Benachrichtigung vom Nutzer nicht geschlossen werden kann, übergeben Sie true in 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 Benachrichtigungsberechtigung ablehnt, werden im Task-Manager weiterhin Hinweise zu Diensten im Vordergrund angezeigt. In der Benachrichtigungsleiste werden diese jedoch nicht angezeigt.

Dienste im Vordergrund in deinem Manifest deklarieren

Deklariere im Manifest deiner App die einzelnen Dienste im Vordergrund deiner App mit einem <service>-Element. Verwenden Sie für jeden Dienst ein android:foregroundServiceType-Attribut, um zu deklarieren, welche Art von Arbeit der Dienst ausführt.

Wenn Ihre App beispielsweise einen Dienst im Vordergrund erstellt, über den Musik wiedergegeben wird, können Sie diesen 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 für Ihren Dienst mehrere Typen gelten, trennen Sie sie durch den Operator |. Ein Dienst, der Kamera und Mikrofon verwendet, würde dies beispielsweise 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 FOREGROUND_SERVICE im App-Manifest anfordern, wie im folgenden Code-Snippet gezeigt. Da es sich hierbei um eine normale Berechtigung handelt, wird sie vom System der anfragenden App automatisch zugewiesen.

Wenn die App auf API-Level 34 oder höher ausgerichtet ist, muss sie außerdem den entsprechenden Berechtigungstyp für die Art der Arbeit anfordern, die der Dienst im Vordergrund ausführt. Jeder Typ von Diensten im Vordergrund hat 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. Dabei handelt es sich alles um 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

Ab Android 14 (API-Level 34) prüft das System, wenn Sie einen Dienst im Vordergrund starten, 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. Ist dies nicht der Fall, gibt das System SecurityException aus.

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 zu Typen von Diensten im Vordergrund werden 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 anfordern, dass Ihr Dienst im Vordergrund ausgeführt wird. Rufen Sie dazu ServiceCompat.startForeground() auf (verfügbar unter 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 dann weitere Diensttypen hinzufügen müssen, können Sie noch einmal startForeground() aufrufen.

Angenommen, eine Fitness-App führt einen Lauf-Tracker-Dienst aus, der immer location-Informationen benötigt, aber möglicherweise Medien abspielen muss oder nicht. Du musst sowohl location als auch mediaPlayback im Manifest deklarieren. Wenn ein Nutzer eine Ausführung 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 anschließend mit der Audiowiedergabe beginnen 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, wie ein Kamera- Vordergrunddienst 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 =
            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

Rufen Sie stopForeground() auf, um den Dienst aus dem Vordergrund zu entfernen. Diese Methode verwendet einen booleschen Wert, der angibt, ob auch die Benachrichtigung in der Statusleiste entfernt werden soll. Beachten Sie, dass der Dienst weiterhin ausgeführt wird.

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

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

Unten in der Benachrichtigungsleiste befindet sich eine Schaltfläche, die die Anzahl der Apps anzeigt, die derzeit im Hintergrund ausgeführt werden. Wenn Sie auf diese Schaltfläche klicken, wird ein Dialogfeld mit den Namen der verschiedenen Apps angezeigt. Die Schaltfläche „Stopp“ befindet sich rechts neben der jeweiligen 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 zu beenden, für die Dienste im Vordergrund ausgeführt werden. Die SDK-Zielversion dieser App spielt dabei keine Rolle. Diese Option wird als Task-Manager bezeichnet und enthält eine Liste von Anwendungen, die derzeit einen Dienst im Vordergrund ausführen.

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

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

  • Ihre App wird vom System aus dem Arbeitsspeicher entfernt. Daher wird die gesamte Anwendung angehalten, 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.
  • Deine App bleibt im Verlauf.
  • Geplante Jobs werden zum geplanten Zeitpunkt ausgeführt.
  • Der Wecker wird zur festgelegten Zeit oder im festgelegten Zeitfenster gestellt.

Führen Sie den folgenden ADB-Befehl in einem Terminalfenster aus, um zu testen, ob sich Ihre Anwendung wie erwartet verhält, während und nachdem ein Nutzer sie beendet hat:

adb shell cmd activity stop-app PACKAGE_NAME

Ausnahmen

Für bestimmte Arten von Apps gibt es mehrere Ausnahmestufen, die in den folgenden Abschnitten beschrieben werden.

Ausnahmen gelten pro Anwendung, nicht pro Prozess. Wenn das System einen Prozess in einer Anwendung ausschließt, sind auch alle anderen Prozesse in dieser Anwendung ausgenommen.

Ausnahmen von der Anzeige im Task-Manager

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

Ausnahmen, die nicht von Nutzern aufgehalten werden können

Wenn die folgenden App-Typen einen Dienst im Vordergrund ausführen, werden sie im Task-Manager angezeigt. Der Nutzer kann jedoch neben dem Namen der App auf die Schaltfläche Beenden nicht tippen:

Speziell entwickelte 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, zweckorientierte API gibt, sollten Sie diese so gut wie immer anstelle eines Diensts im Vordergrund verwenden. Maßgeschneiderte 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 Messaging-Apps, die Chat-Bubble-Funktionen implementieren müssen.

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

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

Apps, die auf Android 12 oder höher ausgerichtet sind, können Dienste im Vordergrund nicht starten, während sie im Hintergrund ausgeführt wird. Hiervon ausgenommen sind einige Sonderfälle. 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, gibt das System den Fehler ForegroundServiceStartNotAllowedException aus.

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

Ausnahmen von Einschränkungen beim Starten des Hintergrunds

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, für die Berechtigungen während der Nutzung erforderlich sind

Unter Android 14 (API-Level 34) oder höher müssen Sie besondere Situationen berücksichtigen, wenn Sie einen Dienst im Vordergrund starten, für den während der Verwendung Berechtigungen 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 entsprechenden Berechtigungen für diesen Diensttyp hat. Wenn Sie beispielsweise einen Dienst vom Typ microphone erstellen, überprüft das Betriebssystem, ob Ihre App derzeit die Berechtigung RECORD_AUDIO hat. Wenn Sie diese Berechtigung nicht haben, gibt das System eine SecurityException aus.

Bei Berechtigungen, die gerade verwendet werden, verursacht dies ein potenzielles Problem. Hat Ihre App eine Berechtigung, während sie verwendet wird, gilt diese nur, solange sie sich im Vordergrund befindet. Wenn deine 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 deine App derzeit nicht die erforderlichen Berechtigungen hat, und gibt den Fehler SecurityException aus.

Wenn sich Ihre Anwendung im Hintergrund befindet und einen Systemdiagnosedienst erstellt, der die Berechtigung BODY_SENSORS_BACKGROUND benötigt, hat die Anwendung diese Berechtigung derzeit nicht und das System gibt eine Ausnahme aus. Dies gilt nicht, wenn es sich um einen Gesundheitsdienst handelt, der andere Berechtigungen wie ACTIVITY_RECOGNITION benötigt. Durch den Aufruf von PermissionChecker.checkSelfPermission() wird dieses Problem nicht verhindert. Wenn Ihre App während der Nutzung eine Berechtigung hat und checkSelfPermission() aufruft, um zu prüfen, ob sie diese Berechtigung hat, gibt die Methode PERMISSION_GRANTED zurück, auch wenn sich die App im Hintergrund befindet. Wenn die Methode PERMISSION_GRANTED zurückgibt, bedeutet das, dass Ihre App diese Berechtigung hat, während die App verwendet wird.

Wenn für Ihren Dienst im Vordergrund eine Berechtigung während der Nutzung erforderlich ist, müssen Sie daher Context.startForegroundService() oder Context.bindService() aufrufen, während Ihre App eine sichtbare Aktivität hat, es sei denn, der Dienst fällt unter eine der definierten Ausnahmen.

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

Selbst wenn ein Dienst im Vordergrund gestartet wird, während die App im Hintergrund ausgeführt wird, kann er in einigen Fällen trotzdem auf Standort-, Kamera- und Mikrofoninformationen zugreifen, während die App im Vordergrund ausgeführt wird („während der Nutzung“).

Wenn für den Dienst in diesen Situationen ein Dienst im Vordergrund deklariert ist und der Dienst von einer App mit der Berechtigung ACCESS_BACKGROUND_LOCATION gestartet wird, kann dieser Dienst jederzeit auf Standortdaten zugreifen, auch wenn die App im Hintergrund ausgeführt wird.location

Diese Situationen sind in der folgenden Liste aufgeführt:

  • Eine Systemkomponente startet den Dienst.
  • Der Dienst interagiert zunächst mit App-Widgets.
  • Der Dienst beginnt mit einer Benachrichtigung.
  • Der Dienst beginnt als PendingIntent, der von einer anderen, sichtbaren Anwendung gesendet wird.
  • Der Dienst beginnt mit einer App, die ein Device Policy Controller ist und im Modus „Geräteinhaber“ ausgeführt wird.
  • Der Dienst beginnt von einer App, die die VoiceInteractionService bereitstellt.
  • Der Dienst startet von einer App mit der privilegierten Berechtigung START_ACTIVITIES_FROM_BACKGROUND.
Ermitteln, welche Dienste in Ihrer Anwendung 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