Le lancement d'un service de premier plan à partir de votre application s'effectue en deux étapes. Tout d'abord, vous
devez démarrer le service en appelant
context.startForegroundService(). Ensuite, demandez au
service d'appeler ServiceCompat.startForeground() pour se promouvoir
en service de premier plan.
Prérequis
Selon le niveau d'API ciblé par votre application, le lancement d'un service de premier plan peut être soumis à certaines restrictions.
Les applications ciblant Android 12 (niveau d'API 31) ou version ultérieure ne sont pas autorisées à démarrer un service de premier plan lorsqu'elles s'exécutent en arrière-plan, à quelques exceptions près. Pour en savoir plus et connaître les exceptions à cette règle, consultez Restrictions concernant le démarrage d'un service de premier plan en arrière-plan.
Les applications ciblant Android 14 (niveau d'API 34) ou version ultérieure doivent demander les autorisations appropriées pour le type de service de premier plan. Lorsque l'application tente de promouvoir un service au premier plan, le système vérifie si elle dispose des autorisations appropriées et génère une erreur
SecurityExceptionsi ce n'est pas le cas. Par exemple, si vous essayez de lancer un service de premier plan de typelocation, le système vérifie que votre application dispose déjà de l'autorisationACCESS_COARSE_LOCATIONouACCESS_FINE_LOCATION. La documentation sur les types de services de premier plan répertorie les prérequis pour chaque type de service de premier plan.
Lancer un service
Pour lancer un service de premier plan, vous devez d'abord le lancer en tant que service ordinaire (non de premier plan) :
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);
Points clés concernant le code
- L'extrait de code lance un service. Toutefois, le service n'est pas encore exécuté au premier plan. Dans le service lui-même, vous devez appeler
ServiceCompat.startForeground()pour le promouvoir en service de premier plan.
Promouvoir un service au premier plan
Une fois qu'un service est en cours d'exécution, vous devez appeler
ServiceCompat.startForeground() pour demander que le service
s'exécute au premier plan. En règle générale, vous appelez cette méthode dans la méthode
onStartCommand() du service.
ServiceCompat.startForeground() utilise les paramètres suivants :
- Le service.
- Un entier positif qui identifie de manière unique la notification du service dans la barre d'état.
- L'objet
Notificationlui-même. - Le ou les types de services de premier plan identifiant le travail effectué par le service
Les types de services de premier plan que vous transmettez à startForeground()
types déclarés dans le fichier manifeste, en fonction du cas d'utilisation spécifique. Ensuite, si vous devez ajouter d'autres types de services, vous pouvez appeler à nouveau startForeground().
Supposons, par exemple, qu'une application de fitness exécute un service de suivi de course à pied qui a toujours besoin d'informations de location, mais qui peut ou non avoir besoin de lire des contenus multimédias. Vous devez déclarer location et mediaPlayback dans le fichier manifeste. Si un utilisateur commence une course et souhaite uniquement que sa position soit suivie, votre application doit appeler startForeground() et ne transmettre que l'autorisation ACCESS_FINE_LOCATION. Ensuite, si l'utilisateur souhaite commencer à lire du contenu audio, appelez à nouveau startForeground() et transmettez la combinaison au niveau du bit de tous les types de services de premier plan (dans ce cas, ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK).
L'exemple suivant montre le code qu'un service d'appareil photo utiliserait pour se promouvoir en service de premier plan :
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) } // ... } } //... }
Points clés concernant le code
- L'application a déjà déclaré dans le fichier manifeste qu'elle a besoin de l'autorisation
CAMERA. Toutefois, l'application doit également vérifier au moment de l'exécution que l'utilisateur a accordé cette autorisation. Si l'application ne dispose pas des autorisations appropriées, elle doit informer l'utilisateur du problème. - Différents types de services de premier plan ont été introduits avec différentes versions de la plate-forme Android. Ce code vérifie la version d'Android sur laquelle il s'exécute et demande les autorisations appropriées.
- Le code recherche
ForegroundServiceStartNotAllowedExceptionau cas où il tente de démarrer un service de premier plan dans une situation non autorisée (par exemple, s'il tente de promouvoir le service au premier plan alors que l'application s'exécute en arrière-plan).