Das Starten eines Vordergrunddienstes über Ihre App erfolgt in zwei Schritten. Zuerst müssen Sie den Dienst durch Aufrufen von context.startForegroundService()
starten. Lassen Sie den Dienst dann ServiceCompat.startForeground()
aufrufen, um ihn in einen Vordergrunddienst zu befördern.
Voraussetzungen
Je nachdem, auf welche API-Ebene Ihre App ausgerichtet ist, gelten einige Einschränkungen dafür, wann eine App einen Dienst im Vordergrund starten kann.
Apps, die auf Android 12 (API‑Level 31) oder höher ausgerichtet sind, dürfen keinen Dienst im Vordergrund starten, während die App im Hintergrund ausgeführt wird. Es gibt jedoch einige spezifische Ausnahmen. Weitere Informationen und Informationen zu den Ausnahmen von dieser Regel finden Sie unter Einschränkungen beim Starten eines Vordergrunddienstes im Hintergrund.
Apps, die auf Android 14 (API‑Level 34) oder höher ausgerichtet sind, müssen die entsprechenden Berechtigungen für den Typ des Dienstes im Vordergrund anfordern. Wenn die App versucht, einen Dienst in den Vordergrund zu verschieben, prüft das System, ob die entsprechenden Berechtigungen vorhanden sind, und löst
SecurityException
aus, wenn der App Berechtigungen fehlen. Wenn Sie beispielsweise versuchen, einen Dienst vom Typlocation
im Vordergrund zu starten, prüft das System, ob Ihre App bereits die BerechtigungACCESS_COARSE_LOCATION
oderACCESS_FINE_LOCATION
hat. In der Dokumentation zu Typen von Diensten im Vordergrund sind die erforderlichen Voraussetzungen für jeden Typ aufgeführt.
Dienst starten
Wenn Sie einen Dienst im Vordergrund starten möchten, müssen Sie ihn zuerst als normalen (nicht im Vordergrund ausgeführten) Dienst starten:
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);
Wichtige Punkte zum Code
- Mit dem Code-Snippet wird ein Dienst gestartet. Der Dienst wird jedoch noch nicht im Vordergrund ausgeführt. Im Dienst selbst müssen Sie
ServiceCompat.startForeground()
aufrufen, um den Dienst zu einem Dienst im Vordergrund zu machen.
Dienst in den Vordergrund rücken
Sobald ein Dienst ausgeführt wird, müssen Sie ServiceCompat.startForeground()
aufrufen, um anzufordern, dass der Dienst im Vordergrund ausgeführt wird. Normalerweise würden Sie diese Methode in der onStartCommand()
-Methode des Dienstes aufrufen.
ServiceCompat.startForeground()
verwendet die folgenden Parameter:
- Der Dienst.
- Eine positive Ganzzahl, die die Benachrichtigung des Dienstes in der Statusleiste eindeutig identifiziert.
- Das
Notification
-Objekt selbst. - Der Vordergrunddiensttyp oder die Vordergrunddiensttypen, die die vom Dienst ausgeführten Aufgaben angeben
Die Typen von Diensten im Vordergrund, die Sie an startForeground()
übergeben, müssen je nach Anwendungsfall im Manifest deklarierte Typen sein. Wenn Sie weitere Diensttypen hinzufügen müssen, 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 keine Medien abspielen muss. Sie müssen sowohl location
als auch mediaPlayback
im Manifest deklarieren. Wenn ein Nutzer einen Lauf startet und nur seinen Standort erfassen möchte, sollte Ihre App startForeground()
aufrufen und nur die Berechtigung ACCESS_FINE_LOCATION
übergeben. Wenn der Nutzer dann Audio abspielen möchte, rufen Sie startForeground()
noch einmal auf und übergeben Sie die bitweise Kombination aller Arten von Diensten im Vordergrund (in diesem Fall ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK
).
Das folgende Beispiel zeigt den Code, den ein Kameradienst verwenden würde, um sich selbst zu einem Dienst im Vordergrund zu machen:
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) } // ... } } //... }
Wichtige Punkte zum Code
- In der Manifestdatei der App wurde bereits deklariert, dass die Berechtigung
CAMERA
erforderlich ist. Die App muss jedoch auch zur Laufzeit prüfen, ob der Nutzer diese Berechtigung erteilt hat. Wenn die App nicht die richtigen Berechtigungen hat, sollte sie den Nutzer über das Problem informieren. - Mit verschiedenen Versionen der Android-Plattform wurden verschiedene Arten von Vordergrunddiensten eingeführt. Dieser Code prüft, welche Android-Version verwendet wird, und fordert die entsprechenden Berechtigungen an.
- Der Code prüft auf
ForegroundServiceStartNotAllowedException
, falls versucht wird, einen Dienst im Vordergrund in einer Situation zu starten, die nicht zulässig ist (z. B. wenn versucht wird, den Dienst in den Vordergrund zu verschieben, während die App im Hintergrund ausgeführt wird).