Les services de premier plan effectuent des opérations visibles par l'utilisateur.
Les services de premier plan affichent une notification dans la barre d'état pour indiquer aux utilisateurs que votre application effectue une tâche au premier plan et consomme des ressources système.
Voici quelques exemples d'applications qui utilisent des services de premier plan:
- Application de lecteur musical qui lit de la musique dans un service de premier plan. La notification peut afficher le titre en cours de lecture.
- Une application de fitness qui enregistre la course d'un utilisateur dans un service de premier plan, après avoir reçu l'autorisation de l'utilisateur. La notification peut indiquer la distance parcourue par l'utilisateur au cours de la session de fitness en cours.
N'utilisez un service de premier plan que lorsque votre application doit effectuer une tâche visible par l'utilisateur, même lorsqu'il n'interagit pas directement avec l'application. Si l'action est suffisamment peu importante pour que vous souhaitiez utiliser une notification de priorité minimale, créez plutôt une tâche en arrière-plan.
Ce document décrit l'autorisation requise pour utiliser les services de premier plan, et explique comment démarrer un service de premier plan et le supprimer de l'arrière-plan. Il décrit également comment associer certains cas d'utilisation à des types de services de premier plan et les restrictions d'accès qui s'appliquent lorsque vous démarrez un service de premier plan à partir d'une application exécutée en arrière-plan.
L'utilisateur peut ignorer la notification par défaut
À partir d'Android 13 (niveau d'API 33), les utilisateurs peuvent ignorer la notification associée à un service de premier plan par défaut. Pour ce faire, les utilisateurs effectuent un geste de balayage sur la notification. Traditionnellement, la notification n'est pas ignorée, sauf si le service de premier plan est arrêté ou supprimé du premier plan.
Si vous ne souhaitez pas que l'utilisateur puisse ignorer la notification, transmettez true
à la méthode setOngoing()
lorsque vous créez votre notification à l'aide de Notification.Builder
.
Services qui affichent une notification immédiatement
Si un service de premier plan présente au moins l'une des caractéristiques suivantes, le système affiche la notification associée immédiatement après le démarrage du service, même sur les appareils équipés d'Android 12 ou version ultérieure:
- Le service est associé à une notification qui inclut des boutons d'action.
- Le service dispose d'un
foregroundServiceType
demediaPlayback
,mediaProjection
ouphoneCall
. - Le service fournit un cas d'utilisation lié aux appels téléphoniques, à la navigation ou à la lecture de contenus multimédias, comme défini dans l'attribut catégorie de la notification.
- Le service a désactivé le changement de comportement en transmettant
FOREGROUND_SERVICE_IMMEDIATE
àsetForegroundServiceBehavior()
lors de la configuration de la notification.
Sous Android 13 (niveau d'API 33) ou version ultérieure, si l'utilisateur refuse l'autorisation de notification, il voit toujours les notifications liées aux services de premier plan dans le gestionnaire de tâches, mais pas dans le panneau des notifications.
Déclarer les services de premier plan dans votre fichier manifeste
Dans le fichier manifeste de votre application, déclarez chacun de ses services de premier plan avec un élément <service>
. Pour chaque service, utilisez un attribut android:foregroundServiceType
pour déclarer le type de travail effectué par le service.
Par exemple, si votre application crée un service de premier plan qui diffuse de la musique, vous pouvez déclarer le service comme suit:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" ...>
<application ...>
<service
android:name=".MyMediaPlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="false">
</service>
</application>
</manifest>
Si plusieurs types s'appliquent à votre service, séparez-les avec l'opérateur |
. Par exemple, un service qui utilise la caméra et le micro déclarerait cela comme suit:
android:foregroundServiceType="camera|microphone"
Demander les autorisations du service de premier plan
Les applications qui ciblent Android 9 (niveau d'API 28) ou une version ultérieure et qui utilisent des services de premier plan doivent demander FOREGROUND_SERVICE
dans le fichier manifeste de l'application, comme indiqué dans l'extrait de code suivant. Il s'agit d'une autorisation normale. Le système l'accorde donc automatiquement à l'application à l'origine de la demande.
De plus, si l'application cible le niveau d'API 34 ou supérieur, elle doit demander le type d'autorisation approprié pour le type de travail que le service de premier plan effectuera. Chaque type de service de premier plan possède un type d'autorisation correspondant. Par exemple, si une application lance un service de premier plan qui utilise l'appareil photo, vous devez demander les autorisations FOREGROUND_SERVICE
et FOREGROUND_SERVICE_CAMERA
. Il s'agit toutes d'autorisations normales. Le système les accorde donc automatiquement si elles sont listées dans le fichier manifeste.
<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>
Prérequis pour les services de premier plan
À partir d'Android 14 (niveau d'API 34), lorsque vous lancez un service de premier plan, le système vérifie les conditions préalables spécifiques en fonction du type de service. Par exemple, si vous essayez de lancer un service de premier plan de type location
, le système vérifie que votre application dispose déjà de l'autorisation ACCESS_COARSE_LOCATION
ou ACCESS_FINE_LOCATION
. Dans le cas contraire, le système génère une exception SecurityException
.
Pour cette raison, vous devez vérifier que les conditions préalables requises sont remplies avant de démarrer un service de premier plan. La documentation sur le type de service de premier plan liste les conditions préalables requises pour chaque type de service de premier plan.
Lancer un service de premier plan
Avant de demander au système d'exécuter un service en tant que service de premier plan, démarrez le service lui-même:
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);
Dans le service, généralement dans onStartCommand()
, vous pouvez demander à ce que votre service s'exécute au premier plan. Pour ce faire, appelez ServiceCompat.startForeground()
(disponible dans androidx-core 1.12 et versions ultérieures). Cette méthode utilise les paramètres suivants:
- Le service
- Entier positif qui identifie de manière unique la notification dans la barre d'état
- L'objet
Notification
lui-même - Les types de services de premier plan qui identifient le travail effectué par le service
Ces types peuvent constituer un sous-ensemble des 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 à nouveau appeler startForeground()
.
Par exemple, supposons qu'une application de fitness exécute un service de suivi de la course à pied qui a toujours besoin d'informations location
, mais qui peut ou non avoir besoin de lire des contenus multimédias. Vous devez déclarer à la fois location
et mediaPlayback
dans le fichier manifeste. Si un utilisateur commence à courir et souhaite simplement 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 de l'audio, appelez à nouveau startForeground()
et transmettez la combinaison par bits de tous les types de services de premier plan (dans ce cas, ACCESS_FINE_LOCATION|FOREGROUND_SERVICE_MEDIA_PLAYBACK
).
Voici un exemple qui lance un service de premier plan d'appareil photo:
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) } // ... } } //... }
Supprimer un service du premier plan
Pour supprimer le service du premier plan, appelez stopForeground()
.
Cette méthode utilise une valeur booléenne, qui indique si la notification de la barre d'état doit également être supprimée. Notez que le service continue à s'exécuter.
Si vous arrêtez le service alors qu'il s'exécute au premier plan, sa notification est supprimée.
Gérer l'arrêt des applications exécutant des services de premier plan déclenché par l'utilisateur
À partir d'Android 13 (niveau d'API 33), les utilisateurs peuvent effectuer un workflow depuis le volet de notification pour arrêter une application qui utilise des services de premier plan, quelle que soit la version du SDK cible de cette application. Cette affordance, appelée Gestionnaire des tâches, affiche la liste des applications qui exécutent actuellement un service de premier plan.
Cette liste est intitulée Applications actives. À côté de chaque application se trouve un bouton Arrêter. La figure 1 illustre le workflow du gestionnaire de tâches sur un appareil exécutant Android 13.
Lorsque l'utilisateur appuie sur le bouton Stop (Arrêter) à côté de votre application dans le Gestionnaire des tâches, les actions suivantes se produisent:
- Le système supprime votre application de la mémoire. Par conséquent, l'intégralité de votre application s'arrête, et pas seulement le service de premier plan en cours d'exécution.
- Le système supprime la pile "Retour" de l'activité de votre application.
- La lecture des contenus multimédias s'arrête.
- La notification associée au service de premier plan est supprimée.
- Votre application reste dans l'historique.
- Les jobs planifiés s'exécutent à l'heure prévue.
- Les alarmes se déclenchent à l'heure ou à la période programmée.
Pour vérifier que votre application se comporte comme prévu pendant et après l'arrêt par un utilisateur, exécutez la commande ADB suivante dans une fenêtre de terminal:
adb shell cmd activity stop-app PACKAGE_NAME
Exceptions
Le système propose plusieurs niveaux d'exemptions pour certains types d'applications, qui sont décrits dans les sections suivantes.
Les exceptions sont imposées par application et non par processus. Si le système exempte un processus d'une application, tous les autres processus de cette application sont également exemptés.
Exemptions d'affichage dans le gestionnaire de tâches
Les applications suivantes peuvent exécuter un service de premier plan et ne pas apparaître du tout dans le gestionnaire de tâches:
- Applications au niveau du système
- Les applications de sécurité, c'est-à-dire celles ayant le rôle
ROLE_EMERGENCY
- Appareils en mode démo
Exceptions à l'arrêt par les utilisateurs
Lorsque les types d'applications suivants exécutent un service de premier plan, ils apparaissent dans le gestionnaire de tâches, mais aucun bouton Arrêter ne s'affiche à côté du nom de l'application pour que l'utilisateur puisse appuyer dessus:
- Applis de propriétaires d'appareils
- Applications de propriétaires de profils
- Applications persistantes
- Applications disposant du rôle
ROLE_DIALER
Utiliser des API dédiées plutôt que des services de premier plan
Pour de nombreux cas d'utilisation, vous pouvez utiliser des API de plate-forme ou de Jetpack pour effectuer des tâches pour lesquelles vous pourriez utiliser un service de premier plan. Si une API dédiée est disponible, vous devez presque toujours l'utiliser au lieu d'un service de premier plan. Les API dédiées fournissent souvent des fonctionnalités supplémentaires spécifiques aux cas d'utilisation que vous auriez autrement dû créer vous-même. Par exemple, l' API Bubbles gère la logique d'UI complexe pour les applications de messagerie qui doivent implémenter les fonctionnalités des bulles de chat.
La documentation sur les types de services de premier plan présente de bonnes alternatives à utiliser à la place des services de premier plan.
Restrictions concernant le démarrage d'un service de premier plan en arrière-plan
Les applications qui ciblent Android 12 ou version ultérieure ne peuvent pas démarrer de services de premier plan lorsque l'application s'exécute en arrière-plan, sauf dans quelques cas particuliers. Si une application tente de démarrer un service de premier plan alors qu'elle s'exécute en arrière-plan et que le service de premier plan ne répond pas à l'un des cas exceptionnels, le système génère une erreur ForegroundServiceStartNotAllowedException
.
De plus, si une application souhaite lancer un service de premier plan qui nécessite des autorisations en cours d'utilisation (par exemple, des autorisations pour les capteurs corporels, l'appareil photo, le micro ou la position), elle ne peut pas créer le service lorsque l'application est en arrière-plan, même si elle fait partie des exceptions aux restrictions de démarrage en arrière-plan. La raison en est expliquée dans la section Restrictions sur le démarrage de services de premier plan nécessitant des autorisations en cours d'utilisation.
Exemptions des restrictions de démarrage en arrière-plan
Dans les situations suivantes, votre application peut démarrer des services de premier plan même lorsqu'elle s'exécute en arrière-plan:
- Votre application passe d'un état visible par l'utilisateur, comme une activité.
- Votre application peut démarrer une activité en arrière-plan, sauf si elle contient une activité dans la pile "Retour" d'une tâche existante.
Votre application reçoit un message à priorité élevée à l'aide de Firebase Cloud Messaging.
L'utilisateur effectue une action sur un élément d'interface utilisateur lié à votre application. Par exemple, il peut interagir avec une bulle, une notification, un widget ou une activité.
Votre application appelle une alarme exacte pour effectuer une action demandée par l'utilisateur.
Votre application est la méthode d'entrée actuelle de l'appareil.
Votre application reçoit un événement lié au geofencing ou à la transition de reconnaissance d'activité.
Une fois que l'appareil a redémarré et reçu l'action d'intent
ACTION_BOOT_COMPLETED
,ACTION_LOCKED_BOOT_COMPLETED
ouACTION_MY_PACKAGE_REPLACED
dans un broadcast receiver.Votre application reçoit l'action d'intent
ACTION_TIMEZONE_CHANGED
,ACTION_TIME_CHANGED
ouACTION_LOCALE_CHANGED
dans un broadcast receiver.Votre application reçoit l'événement
ACTION_TRANSACTION_DETECTED
deNfcService
.Applications disposant de certains rôles ou autorisations système, tels que les propriétaires d'appareil et les propriétaires de profil
Votre application utilise Companion Device Manager et déclare l'autorisation
REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
ouREQUEST_COMPANION_RUN_IN_BACKGROUND
. Dans la mesure du possible, utilisezREQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND
.L'utilisateur désactive l'optimisation de la batterie pour votre application.
Votre application dispose de l'autorisation
SYSTEM_ALERT_WINDOW
. Remarque: Si votre application cible Android 15 ou version ultérieure, elle doit disposer de l'autorisationSYSTEM_ALERT_WINDOW
et elle doit actuellement avoir une fenêtre superposée visible.
Restrictions concernant le démarrage de services de premier plan nécessitant des autorisations en cours d'utilisation
Sur Android 14 (niveau d'API 34) ou version ultérieure, vous devez tenir compte de certaines situations spéciales si vous démarrez un service de premier plan qui nécessite des autorisations en cours d'utilisation.
Si votre application cible Android 14 ou une version ultérieure, le système d'exploitation vérifie lorsque vous créez un service de premier plan pour s'assurer qu'elle dispose de toutes les autorisations appropriées pour ce type de service. Par exemple, lorsque vous créez un service de premier plan de type micro, le système d'exploitation vérifie que votre application dispose actuellement de l'autorisation RECORD_AUDIO
. Si vous ne disposez pas de cette autorisation, le système génère une exception SecurityException
.
Cela peut poser problème pour les autorisations en cours d'utilisation. Si votre application dispose d'une autorisation "si l'application est ouverte", elle ne dispose de cette autorisation que lorsque l'application est au premier plan. Cela signifie que si votre application est en arrière-plan et qu'elle tente de créer un service de premier plan de type appareil photo, position ou micro, le système voit que votre application ne dispose pas actuellement des autorisations requises et génère une erreur SecurityException
.
De même, si votre application s'exécute en arrière-plan et qu'elle crée un service de santé qui nécessite l'autorisation BODY_SENSORS
, elle ne dispose pas actuellement de cette autorisation et le système génère une exception.
(Cela ne s'applique pas s'il s'agit d'un service de santé nécessitant des autorisations différentes, comme ACTIVITY_RECOGNITION
.) L'appel de PermissionChecker.checkSelfPermission()
n'empêche pas ce problème. Si votre application dispose d'une autorisation "pendant l'utilisation" et qu'elle appelle checkSelfPermission()
pour vérifier si elle dispose de cette autorisation, la méthode renvoie PERMISSION_GRANTED
, même si l'application est en arrière-plan. Lorsque la méthode renvoie PERMISSION_GRANTED
, cela signifie que votre application dispose de cette autorisation lorsque l'application est en cours d'utilisation.
Pour cette raison, si votre service de premier plan nécessite une autorisation en cours d'utilisation, vous devez appeler Context.startForegroundService()
ou Context.bindService()
tant que votre application présente une activité visible, sauf si le service correspond à l'une des exceptions définies.
Exceptions aux restrictions concernant les autorisations en cours d'utilisation
Dans certains cas, même si un service de premier plan est démarré alors que l'application s'exécute en arrière-plan, il peut toujours accéder aux informations de localisation, de l'appareil photo et du micro lorsque l'application s'exécute au premier plan ("while-in-use").
Dans ces mêmes situations, si le service déclare un type de service de premier plan de location
et est lancé par une application disposant de l'autorisation ACCESS_BACKGROUND_LOCATION
, ce service peut accéder aux informations de localisation en permanence, même lorsque l'application s'exécute en arrière-plan.
La liste suivante contient ces situations:
- Un composant système démarre le service.
- Le service commence par interagir avec les widgets d'application.
- Le service commence par interagir avec une notification.
- Le service commence comme un
PendingIntent
envoyé à partir d'une autre application visible. - Le service est lancé par une application qui est un outil de contrôle des règles relatives aux appareils qui s'exécute en mode propriétaire de l'appareil.
- Le service est démarré par une application qui fournit le
VoiceInteractionService
. - Le service est démarré par une application disposant de l'autorisation privilégiée
START_ACTIVITIES_FROM_BACKGROUND
.
Déterminer les services concernés dans votre application
Lorsque vous testez votre application, démarrez ses services de premier plan. Si un service démarré a un accès limité à la position, au micro et à la caméra, le message suivant s'affiche dans Logcat:
Foreground service started from background can not have \ location/camera/microphone access: service SERVICE_NAME