Es gibt zwei Schritte, um einen Dienst im Vordergrund über Ihre App zu starten. Zuerst müssen Sie den Dienst mit
context.startForegroundService() starten. Dann muss der
Dienst ServiceCompat.startForeground() aufrufen, um sich selbst zu einem Dienst im Vordergrund zu machen.
Vorbereitung
Je nachdem, auf welches API-Level Ihre App ausgerichtet ist, gibt es einige Einschränkungen, 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 Ausnahmen. Weitere Informationen und Informationen zu den Ausnahmen von dieser Regel finden Sie unter Einschränkungen beim Starten eines Dienstes im Vordergrund aus dem 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
SecurityExceptionaus, wenn der App Berechtigungen fehlen. Wenn Sie beispielsweise versuchen, einen Dienst im Vordergrund vom Typlocationzu starten, prüft das System, ob Ihre App bereits die BerechtigungACCESS_COARSE_LOCATIONoderACCESS_FINE_LOCATIONhat. In der Dokumentation zu den Typen von Diensten im Vordergrund sind die erforderlichen Voraussetzungen für jeden Typ von Dienst im Vordergrund aufgeführt.
Dienst starten
Um einen Dienst im Vordergrund zu starten, müssen Sie ihn zuerst als normalen Dienst (nicht im Vordergrund) 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 Informationen zum Code
- Das Code-Snippet startet einen Dienst. 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 verschieben
Sobald ein Dienst ausgeführt wird, müssen Sie
ServiceCompat.startForeground() aufrufen, um anzufordern, dass der Dienst
im Vordergrund ausgeführt wird. Normalerweise rufen Sie diese Methode in der Methode des Dienstes auf.onStartCommand()
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 Typ oder die Typen des Dienstes im Vordergrund die die vom Dienst ausgeführte Arbeit identifizieren
Die Typen von Diensten im Vordergrund, die Sie an startForeground()
übergeben, müssen je nach spezifischem
Anwendungsfall im Manifest deklariert 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 sein Standort getrackt werden soll, 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 Typen von Diensten im Vordergrund (in diesem Fall ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK).
Im folgenden Beispiel wird der Code gezeigt, 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 Informationen zum Code
- Die App hat im Manifest bereits deklariert, dass sie die Berechtigung
CAMERAbenötigt. Die App muss jedoch auch zur Laufzeit prüfen, ob der Nutzer diese Berechtigung gewährt hat. Wenn die App nicht die richtigen Berechtigungen hat, sollte sie den Nutzer über das Problem informieren. - Verschiedene Typen von Diensten im Vordergrund wurden mit verschiedenen Versionen der Android-Plattform eingeführt. Dieser Code prüft, welche Android-Version ausgeführt wird, und fordert die entsprechenden Berechtigungen an.
- Der Code prüft auf
ForegroundServiceStartNotAllowedException, falls versucht wird, einen Dienst im Vordergrund in einer nicht zulässigen Situation zu starten (z. B. wenn versucht wird, den Dienst in den Vordergrund zu verschieben, während die App im Hintergrund ausgeführt wird).