Créer une application de navigation

Cette page présente les différentes fonctionnalités de la bibliothèque d'applications pour voitures que vous pouvez utiliser pour implémenter la fonctionnalité de navigation détaillée de votre application.

Déclarer une prise en charge de la navigation dans votre fichier manifeste

Votre application de navigation doit déclarer la catégorie d'application automobile androidx.car.app.category.NAVIGATION dans le filtre d'intent de son CarAppService :

<application>
    ...
   <service
       ...
        android:name=".MyNavigationCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService" />
        <category android:name="androidx.car.app.category.NAVIGATION"/>
      </intent-filter>
    </service>
    ...
</application>

Prendre en charge les intents de navigation

Afin de pouvoir prendre en charge les intents de navigation dans votre application, y compris ceux provenant de l'Assistant Google par requête vocale, votre application doit gérer l'intent CarContext.ACTION_NAVIGATE dans ses Session.onCreateScreen et Session.onNewIntent.

Consultez la documentation de CarContext.startCarApp pour en savoir plus sur le format de l'intent.

Accéder aux modèles de navigation

Les applications de navigation peuvent accéder aux modèles suivants, qui affichent une surface dans en arrière-plan avec la carte et, pendant la navigation, la navigation détaillée les instructions de navigation.

  • NavigationTemplate : affiche également un message d'information et des estimations de trajets facultatifs pendant la navigation active.
  • MapWithContentTemplate: Un modèle qui permet à une application d'afficher des tuiles de carte avec un certain type de contenu (par par exemple, une liste). Le contenu est généralement affiché en superposition sur la des tuiles de carte, la carte étant visible et les zones stables s'ajustant au contenu.

Pour en savoir plus sur la conception de l'interface utilisateur de votre application de navigation à l'aide de ces modèles, consultez l'article Applications de navigation.

Pour accéder aux modèles de navigation, votre application doit déclarer l'autorisation androidx.car.app.NAVIGATION_TEMPLATES dans son fichier AndroidManifest.xml :

<manifest ...>
  ...
  <uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES"/>
  ...
</manifest>

Une autorisation supplémentaire est requise pour dessiner des cartes.

Migrer vers MapWithContentTemplate

À partir du niveau d'API 7 de Car App, MapTemplate, PlaceListNavigationTemplate, et RoutePreviewNavigationTemplate sont obsolètes. Les modèles obsolètes continueront d'être acceptés, mais Nous vous recommandons vivement de migrer vers MapWithContentTemplate.

Les fonctionnalités fournies par ces modèles peuvent être implémentées à l'aide de MapWithContentTemplate. Consultez les extraits de code suivants pour obtenir des exemples:

Modèle de carte

Kotlin

// MapTemplate (deprecated)
val template = MapTemplate.Builder()
    .setPane(paneBuilder.build())
    .setActionStrip(actionStrip)
    .setHeader(header)
    .setMapController(mapController)
    .build()

// MapWithContentTemplate
val template = MapWithContentTemplate.Builder()
    .setContentTemplate(
        PaneTemplate.Builder(paneBuilder.build())
            .setHeader(header)
            .build())
    .setActionStrip(actionStrip)
    .setMapController(mapController)
    .build()

Java

// MapTemplate (deprecated)
MapTemplate template = new MapTemplate.Builder()
    .setPane(paneBuilder.build())
    .setActionStrip(actionStrip)
    .setHeader(header)
    .setMapController(mapController)
    .build();

// MapWithContentTemplate
MapWithContentTemplate template = new MapWithContentTemplate.Builder()
    .setContentTemplate(new PaneTemplate.Builder(paneBuilder.build())
        .setHeader(header)
        build())
    .setActionStrip(actionStrip)
    .setMapController(mapController)
    .build();

Modèle PlaceListNavigationTemplate

Kotlin

// PlaceListNavigationTemplate (deprecated)
val template = PlaceListNavigationTemplate.Builder()
    .setItemList(itemListBuilder.build())
    .setHeader(header)
    .setActionStrip(actionStrip)
    .setMapActionStrip(mapActionStrip)
    .build()

// MapWithContentTemplate
val template = MapWithContentTemplate.Builder()
    .setContentTemplate(
        ListTemplate.Builder()
            .setSingleList(itemListBuilder.build())
            .setHeader(header)
            .build())
    .setActionStrip(actionStrip)
    .setMapController(
        MapController.Builder()
            .setMapActionStrip(mapActionStrip)
            .build())
    .build()

Java

// PlaceListNavigationTemplate (deprecated)
PlaceListNavigationTemplate template = new PlaceListNavigationTemplate.Builder()
    .setItemList(itemListBuilder.build())
    .setHeader(header)
    .setActionStrip(actionStrip)
    .setMapActionStrip(mapActionStrip)
    .build();

// MapWithContentTemplate
MapWithContentTemplate template = new MapWithContentTemplate.Builder()
    .setContentTemplate(new ListTemplate.Builder()
        .setSingleList(itemListBuilder.build())
        .setHeader(header)
        .build())
    .setActionStrip(actionStrip)
    .setMapController(new MapController.Builder()
        .setMapActionStrip(mapActionStrip)
        .build())
    .build();

RoutePreviewNavigationTemplate (Modèle de navigation preview)

Kotlin

// RoutePreviewNavigationTemplate (deprecated)
val template = RoutePreviewNavigationTemplate.Builder()
    .setItemList(
        ItemList.Builder()
            .addItem(
                Row.Builder()
                    .setTitle(title)
                    .build())
            .build())
    .setHeader(header)
    .setNavigateAction(
        Action.Builder()
            .setTitle(actionTitle)
            .setOnClickListener { ... }
            .build())
    .setActionStrip(actionStrip)
    .setMapActionStrip(mapActionStrip)
    .build()

// MapWithContentTemplate
val template = MapWithContentTemplate.Builder()
    .setContentTemplate(
        ListTemplate.Builder()
            .setSingleList(
                ItemList.Builder()
                    .addItem(
                        Row.Builder()
                            .setTitle(title)
                            .addAction(
                                Action.Builder()
                                    .setTitle(actionTitle)
                                    .setOnClickListener { ... }
                                    .build())
                            .build())
                    .build())
            .setHeader(header)
            .build())
    .setActionStrip(actionStrip)
    .setMapController(
        MapController.Builder()
            .setMapActionStrip(mapActionStrip)
            .build())
    .build()

Java

// RoutePreviewNavigationTemplate (deprecated)
RoutePreviewNavigationTemplate template = new RoutePreviewNavigationTemplate.Builder()
    .setItemList(new ItemList.Builder()
        .addItem(new Row.Builder()
            .setTitle(title))
            .build())
        .build())
    .setHeader(header)
    .setNavigateAction(new Action.Builder()
        .setTitle(actionTitle)
        .setOnClickListener(() -> { ... })
        .build())
    .setActionStrip(actionStrip)
    .setMapActionStrip(mapActionStrip)
    .build();

// MapWithContentTemplate
MapWithContentTemplate template = new MapWithContentTemplate.Builder()
    .setContentTemplate(new ListTemplate.Builder()
        .setSingleList(new ItemList.Builder()
            .addItem(new Row.Builder()
                  .setTitle(title))
                  .addAction(new Action.Builder()
                      .setTitle(actionTitle)
                      .setOnClickListener(() -> { ... })
                      .build())
                  .build())
            .build()))
        .setHeader(header)
        .build())
    .setActionStrip(actionStrip)
    .setMapController(new MapController.Builder()
        .setMapActionStrip(mapActionStrip)
        .build())
    .build();

Les applications de navigation doivent transmettre des métadonnées de navigation supplémentaires à l'hôte. L'hôte utilise ces informations pour fournir des informations à l'unité principale du véhicule et pour éviter les conflits de ressources partagées entre les applications de navigation.

Les métadonnées de navigation sont fournies via le service de voiture NavigationManager accessible à partir du CarContext :

Kotlin

val navigationManager = carContext.getCarService(NavigationManager::class.java)

Java

NavigationManager navigationManager = carContext.getCarService(NavigationManager.class);

Démarrer et arrêter la navigation

Pour que l'hôte puisse gérer plusieurs applications de navigation, notifications d'itinéraire et données de clusters de véhicules, il doit connaître l'état actuel de la navigation. Lorsqu'un utilisateur démarre la navigation, appelez NavigationManager.navigationStarted. De même, lorsque la navigation se termine (par exemple, lorsque l'utilisateur arrive à destination ou annule la navigation), appelez NavigationManager.navigationEnded.

N'appelez NavigationManager.navigationEnded que lorsque la navigation de l'utilisateur est terminée. Par exemple, si vous devez recalculer l'itinéraire au milieu d'un trajet, utilisez plutôt Trip.Builder.setLoading(true).

Parfois, l'hôte a besoin d'une application pour arrêter la navigation et appelle onStopNavigation dans un objet NavigationManagerCallback fourni par votre application via NavigationManager.setNavigationManagerCallback. L'application doit ensuite cesser de fournir des informations sur le prochain virage dans l'écran du cluster, les notifications de navigation et le guidage vocal.

Mettre à jour les informations sur le trajet

Pendant la navigation active, appelez NavigationManager.updateTrip. Les informations fournies dans cet appel pourront être utilisées dans le cluster et les affichages tête haute du véhicule. Selon le véhicule conduit, toutes les informations ne sont pas visibles par l'utilisateur. Par exemple, l'unité principale pour ordinateur (DHU) affiche la Step ajoutée au Trip, mais pas les informations de Destination.

Intégrer à l'écran du cluster

Pour offrir l'expérience utilisateur la plus immersive possible, vous pouvez aller au-delà de l'affichage des métadonnées de base sur l'écran du cluster du véhicule. À partir du niveau d'API 6 de Car App, les applications de navigation ont la possibilité d'afficher leur propre contenu directement sur l'écran du cluster (dans les véhicules compatibles), avec les limites suivantes :

  • L'API de l'écran du cluster n'est pas compatible avec les commandes d'entrée
  • L'écran du cluster ne doit afficher que des tuiles de carte. Vous pouvez également afficher une navigation active sur ces tuiles.
  • L'API de l'écran du cluster est uniquement compatible avec l'utilisation de NavigationTemplate
    • Contrairement aux écrans principaux, l'écran du cluster peut ne pas afficher de façon cohérente tous les éléments d'interface utilisateur NavigationTemplate, tels que les instructions de navigation détaillée, les cartes ETA et les actions. Les tuiles de carte sont le seul élément d'interface utilisateur qui s'affiche de façon cohérente.

Déclarer la compatibilité des clusters

Pour indiquer à l'application hôte que votre application est compatible avec l'affichage sur l'écran du cluster, vous devez ajouter un élément androidx.car.app.category.FEATURE_CLUSTER <category> au <intent-filter> de votre CarAppService, comme indiqué dans l'extrait suivant :

<application>
    ...
   <service
       ...
        android:name=".MyNavigationCarAppService"
        android:exported="true">
      <intent-filter>
        <action android:name="androidx.car.app.CarAppService" />
        <category android:name="androidx.car.app.category.NAVIGATION"/>
        <category android:name="androidx.car.app.category.FEATURE_CLUSTER"/>
      </intent-filter>
    </service>
    ...
</application>

Gérer le cycle de vie et l'état

À partir du niveau d'API 6 de Car App, le flux de cycle de vie est identique, sauf que CarAppService::onCreateSession prend désormais un paramètre de type SessionInfo qui fournit des informations supplémentaires sur la Session en cours de création (le type d'écran et l'ensemble des modèles compatibles).

Les applications peuvent utiliser la même classe Session pour gérer l'écran du cluster et l'écran principal, ou créer des Sessions spécifiques à l'écran pour personnaliser le comportement sur chaque écran (comme indiqué dans l'extrait suivant).

Kotlin

override fun onCreateSession(sessionInfo: SessionInfo): Session {
  return if (sessionInfo.displayType == SessionInfo.DISPLAY_TYPE_CLUSTER) {
    ClusterSession()
  } else {
    MainDisplaySession()
  }
}

Java

@Override
@NonNull
public Session onCreateSession(@NonNull SessionInfo sessionInfo) {
  if (sessionInfo.getDisplayType() == SessionInfo.DISPLAY_TYPE_CLUSTER) {
    return new ClusterSession();
  } else {
    return new MainDisplaySession();
  }
}

Nous ne pouvons pas garantir si l'écran du cluster va s'afficher, ni à quel moment. De plus, il est possible que le cluster Session soit la seule Session (par exemple, l'utilisateur a remplacé l'écran principal par une autre application lorsque la navigation est active). L'accord standard est le suivant : l'application ne peut contrôler l'écran du cluster qu'après l'appel NavigationManager::navigationStarted. Toutefois, l'application peut afficher l'écran du cluster en l'absence de navigation active ou ne jamais l'afficher. Il appartient à l'application de gérer ces scénarios en rendant compte de l'état d'inactivité de ses tuiles de carte.

L'hôte crée un binder séparé des instances CarContext distinctes par Session. Autrement dit, lorsque vous utilisez des méthodes telles que ScreenManager::push ou Screen::invalidate, seule la Session à partir de laquelle elles sont appelées est concernée. Les applications doivent créer leurs propres canaux de communication entre ces instances si une communication interSession est nécessaire (par exemple, en utilisant des diffusions, un singleton partagé ou autre chose).

Tester la compatibilité des clusters

Vous pouvez tester votre implémentation sur Android Auto et sur Android Automotive OS Pour Android Auto, vous devez configurer l'unité principale de l'ordinateur de bureau pour émuler l'écran d'un cluster secondaire. Pour Android Automotive OS, les images système génériques de niveau d'API 30 ou supérieur émulent l'écran du cluster.

Personnaliser TravelEstimate avec du texte ou une icône

Pour personnaliser l'estimation du temps de trajet avec du texte et/ou une icône, utilisez la setTripIcon du TravelEstimate.Builder ou les méthodes setTripText. Le NavigationTemplate utilise TravelEstimate pour éventuellement définir le texte et les icônes à côté ou à la place de l'heure d'arrivée prévue, du temps restant et de la distance restante.

Figure 1 : Estimation du temps de trajet avec icône et texte personnalisés

L'extrait suivant utilise setTripIcon et setTripText pour personnaliser l'estimation du temps de trajet :

Kotlin

TravelEstimate.Builder(Distance.create(...), DateTimeWithZone.create(...))
      ...
      .setTripIcon(CarIcon.Builder(...).build())
      .setTripText(CarText.create(...))
      .build()

Java

new TravelEstimate.Builder(Distance.create(...), DateTimeWithZone.create(...))
      ...
      .setTripIcon(CarIcon.Builder(...).build())
      .setTripText(CarText.create(...))
      .build();

Envoyer des notifications de navigation détaillée

Fournissez des instructions de navigation détaillée à l'aide d'une notification de navigation fréquemment mise à jour. Pour être traité comme une notification de navigation sur l'écran de la voiture, le compilateur de notifications doit effectuer les opérations suivantes :

  1. Marquer la notification comme étant en cours avec la méthode NotificationCompat.Builder.setOngoing
  2. Définir la catégorie de la notification sur Notification.CATEGORY_NAVIGATION.
  3. Étendre la notification avec un CarAppExtender

Une notification de navigation s'affiche dans le widget de rail au bas de l'écran de la voiture. Si le niveau d'importance de la notification est défini sur IMPORTANCE_HIGH, elle s'affiche également sous la forme d'une notification prioritaire. Si l'importance n'est pas définie avec la méthode CarAppExtender.Builder.setImportance, l'importance du canal de notification est utilisée.

L'application peut définir un PendingIntent dans le CarAppExtender qui est envoyé à l'application lorsque l'utilisateur appuie sur la notification prioritaire ou le widget de rail.

Si NotificationCompat.Builder.setOnlyAlertOnce est appelé avec la valeur true, une notification d'importance élevée émet une alerte qu'une fois sous forme de notification prioritaire.

L'extrait de code suivant indique comment créer une notification de navigation :

Kotlin

NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
    ...
    .setOnlyAlertOnce(true)
    .setOngoing(true)
    .setCategory(NotificationCompat.CATEGORY_NAVIGATION)
    .extend(
        CarAppExtender.Builder()
            .setContentTitle(carScreenTitle)
            ...
            .setContentIntent(
                PendingIntent.getBroadcast(
                    context,
                    ACTION_OPEN_APP.hashCode(),
                    Intent(ACTION_OPEN_APP).setComponent(
                        ComponentName(context, MyNotificationReceiver::class.java)),
                        0))
            .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
            .build())
    .build()

Java

new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
    ...
    .setOnlyAlertOnce(true)
    .setOngoing(true)
    .setCategory(NotificationCompat.CATEGORY_NAVIGATION)
    .extend(
        new CarAppExtender.Builder()
            .setContentTitle(carScreenTitle)
            ...
            .setContentIntent(
                PendingIntent.getBroadcast(
                    context,
                    ACTION_OPEN_APP.hashCode(),
                    new Intent(ACTION_OPEN_APP).setComponent(
                        new ComponentName(context, MyNotificationReceiver.class)),
                        0))
            .setImportance(NotificationManagerCompat.IMPORTANCE_HIGH)
            .build())
    .build();

Mettez régulièrement à jour la notification de navigation détaillée pour les changements de distance, ce qui actualise le widget de rail, et affichez-la uniquement sous la forme de notification prioritaire. Vous pouvez contrôler le comportement de la notification prioritaire en définissant l'importance de la notification avec CarAppExtender.Builder.setImportance. Si l'importance est définie sur IMPORTANCE_HIGH, une notification prioritaire s'affiche. Si elle est définie sur une autre valeur, seul le widget de rail est actualisé.

Actualiser le contenu de "PlaceListNavigationTemplate"

Vous pouvez autoriser les conducteurs à actualiser le contenu d'un simple geste, tout en parcourant des listes de lieux créées avec PlaceListNavigationTemplate. Pour activer l'actualisation des listes, implémentez la méthode onContentRefreshRequested de l'interface OnContentRefreshListener et utilisez PlaceListNavigationTemplate.Builder.setOnContentRefreshListener afin de définir l'écouteur au niveau du modèle.

L'extrait de code suivant montre comment définir l'écouteur au niveau du modèle :

Kotlin

PlaceListNavigationTemplate.Builder()
    ...
    .setOnContentRefreshListener {
        // Execute any desired logic
        ...
        // Then call invalidate() so onGetTemplate() is called again
        invalidate()
    }
    .build()

Java

new PlaceListNavigationTemplate.Builder()
        ...
        .setOnContentRefreshListener(() -> {
            // Execute any desired logic
            ...
            // Then call invalidate() so onGetTemplate() is called again
            invalidate();
        })
        .build();

Le bouton d'actualisation ne s'affiche dans l'en-tête du PlaceListNavigationTemplate que si l'écouteur a une valeur.

Lorsque le conducteur clique sur le bouton d'actualisation, la méthode onContentRefreshRequested de votre implémentation de OnContentRefreshListener est appelée. Dans onContentRefreshRequestedScreen.invalidate, appelez la méthode. L'hôte rappelle ensuite la méthode Screen.onGetTemplate de votre application pour récupérer le modèle avec le contenu actualisé. Pour plus d'informations, consultez la section Actualiser le contenu d'un modèle. Tant que le modèle suivant renvoyé par onGetTemplate est du même type, il est considéré comme une actualisation et n'est pas comptabilisé dans le quota de modèles.

Fournir des instructions audio

Pour lire les instructions de navigation sur les haut-parleurs de la voiture, votre application doit demander la priorité audio. Dans le cadre de votre AudioFocusRequest, définissez l'utilisation comme AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE. Définissez également l'obtention de la priorité comme AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK.

Simuler la navigation

Pour valider la fonctionnalité de navigation de votre application lorsque vous l'envoyez au Google Play Store, celle-ci doit implémenter le rappel NavigationManagerCallback.onAutoDriveEnabled. Lorsque ce rappel est appelé, votre application doit simuler la navigation vers la destination choisie lorsque l'utilisateur démarre la navigation. Votre application peut quitter ce mode chaque fois que le cycle de vie de la Session actuelle atteint l'état Lifecycle.Event.ON_DESTROY.

Vous pouvez vérifier que votre implémentation de onAutoDriveEnabled est appelée en exécutant la commande suivante depuis une ligne de commande :

adb shell dumpsys activity service CAR_APP_SERVICE_NAME AUTO_DRIVE

Ce processus est illustré dans l'exemple suivant :

adb shell dumpsys activity service androidx.car.app.samples.navigation.car.NavigationCarAppService AUTO_DRIVE

Application de navigation par défaut pour voiture

Dans Android Auto, l'application de navigation par défaut pour voiture correspond à la dernière application de navigation lancée par l'utilisateur. Il s'agit de l'application qui reçoit des intents de navigation lorsque l'utilisateur appelle des commandes de navigation via l'Assistant ou lorsqu'une autre application envoie un intent pour démarrer la navigation.

Afficher des alertes de navigation contextuelles

Alert affiche des informations importantes au conducteur avec des actions facultatives, sans quitter le contexte de l'écran de navigation. Pour fournir une expérience optimale au conducteur, Alert fonctionne dans le NavigationTemplate afin d'éviter de bloquer l'itinéraire de navigation et de minimiser les distractions du conducteur.

Alert n'est disponible que dans le NavigationTemplate. Pour avertir un utilisateur hors du NavigationTemplate, envisagez d'utiliser une notification prioritaire, comme expliqué dans la section Afficher les notifications.

Par exemple, utilisez Alert pour :

  • informer le conducteur d'une information pertinente pour la navigation actuelle, comme une modification des conditions de circulation ;
  • demander au conducteur une information concernant la navigation actuelle, telle que la présence d'un radar mobile ;
  • proposer une tâche à venir et demander au conducteur s'il l'accepte ou non, par exemple s'il est disposé à prendre quelqu'un à bord sur son chemin.

Dans sa forme de base, une Alert est composée d'un titre et de la durée de l'Alert. La durée est représentée par une barre de progression. Vous pouvez éventuellement ajouter un sous-titre, une icône et jusqu'à deux objets Action.

Figure 2 : Alerte de navigation contextuelle

Une fois qu'une Alert est affichée, elle n'est pas reportée sur un autre modèle si une interaction du conducteur lui fait quitter le NavigationTemplate. Elle reste dans le NavigationTemplate d'origine jusqu'à ce que l'Alert expire, que l'utilisateur effectue une action ou que l'application ignore l'Alert.

Créer une alerte

Utilisez Alert.Builder pour créer une instance Alert :

Kotlin

Alert.Builder(
        /*alertId*/ 1,
        /*title*/ CarText.create("Hello"),
        /*durationMillis*/ 5000
    )
    // The fields below are optional
    .addAction(firstAction)
    .addAction(secondAction)
    .setSubtitle(CarText.create(...))
    .setIcon(CarIcon.APP_ICON)
    .setCallback(...)
    .build()

Java

new Alert.Builder(
        /*alertId*/ 1,
        /*title*/ CarText.create("Hello"),
        /*durationMillis*/ 5000
    )
    // The fields below are optional
    .addAction(firstAction)
    .addAction(secondAction)
    .setSubtitle(CarText.create(...))
    .setIcon(CarIcon.APP_ICON)
    .setCallback(...)
    .build();

Si vous souhaitez écouter l'annulation ou la fermeture de l'Alert, créez une implémentation de l'interface AlertCallback. Les chemins d'appel AlertCallback sont les suivants :

Configurer la durée de l'alerte

Choisissez une durée d'Alert correspondant aux besoins de votre application. La durée recommandée pour une Alert de navigation est de 10 secondes. Consultez Alertes de navigation. pour en savoir plus.

Afficher une alerte

Pour afficher une Alert, appelez la méthode AppManager.showAlert disponible via le CarContext de votre application.

// Show an alert
carContext.getCarService(AppManager.class).showAlert(alert)
  • L'appel de showAlert avec une Alert dont l'alertId est identique à celui de l'Alert actuellement affichée n'a aucun effet. L'Alert n'est pas mise à jour. Pour mettre à jour une Alert, vous devez la recréer avec un nouvel alertId.
  • Si vous appelez showAlert avec une Alert dont l'alertId est différent de celui de l'Alert actuellement affichée, l'Alert affichée est ignorée.

Ignorer une alerte

Bien qu'une Alert soit automatiquement ignorée en raison d'un délai d'inactivité ou d'une interaction du conducteur, vous pouvez également ignorer une Alert, par exemple si ses informations deviennent obsolètes. Pour ignorer une Alert, appelez la méthode dismissAlert avec l'alertId de l'Alert.

// Dismiss the same alert
carContext.getCarService(AppManager.class).dismissAlert(alert.getId())

L'appel de dismissAlert avec un alertId qui ne correspond pas à celui de l'Alert actuellement affichée n'a aucun effet. Cela ne génère pas d'exception.