API Instrument Cluster

Utilisez l'API Instrument Cluster (une API Android) pour afficher les applications de navigation. y compris Google Maps, sur l'écran secondaire d'une voiture, par exemple à l'arrière sur le tableau de bord. Cette page explique comment créer un de contrôler cet écran secondaire et d'intégrer le service CarService afin que les applications de navigation puissent afficher une de l'interface utilisateur.

Terminologie

Les termes suivants sont utilisés sur cette page.

Gestionnaire de clusters CarInstrument
Instance de CarManager qui permet aux applications externes de lancer une activité sur le cluster "Instruments" et recevez des rappels lorsque celui-ci est prêt à être affiché activités.
Gestionnaire de voitures
Classe de base de tous les administrateurs utilisés par les applications externes pour interagir avec des personnes mis en œuvre par CarService.
CarService
Service de plate-forme Android qui permet la communication entre les applications externes (y compris Google Maps) et des fonctionnalités propres aux voitures, comme l'accès au cluster d'instruments.
Destination
Destination finale vers laquelle le véhicule se dirigera.
Heure d'arrivée estimée (ETA)
Heure d'arrivée estimée à destination.
Unité principale (HU)
Unité de calcul principale intégrée à une voiture. Le HU exécute tout le code Android et est connecté à l'écran central de la voiture.
Cluster d'instruments
Écran secondaire situé derrière le volant et entre la voiture d'instruments. Il peut s'agir d'une unité de calcul indépendante connectée au HU via le réseau interne de la voiture (bus CAN) ou un écran secondaire attaché au HU.
Service de rendu de cluster d'instruments
Classe de base du service utilisé pour l'interface avec le cluster "Instrument" l'écran. Les OEM doivent fournir une extension de cette classe qui interagit avec du matériel propre à l'OEM.
Application KitchenSink
Application de test incluse avec Android Automotive.
Itinéraire
Chemin spécifique sur lequel suit un véhicule pour arriver à une destination.
Service Singleton
Service Android avec l'attribut android:singleUser. À à un moment donné, au maximum une instance du service s'exécute sur le système Android.

Prérequis

Avant de continuer, assurez-vous de disposer des éléments suivants:

  • Environnement de développement Android. Pour configurer l'Android environnement de développement, consultez Exigences de compilation
  • Téléchargez le code source Android. Téléchargez la dernière version de le code source Android de la branche pi-car-release (ou ultérieure) à l'adresse https://android.googlesource.com.
  • Unité principale (HU) : Un appareil Android capable d'exécuter Android 9 (ou version ultérieure) Cet appareil doit avoir son propre écran et être en mesure d'effectuer les opérations suivantes : avec les nouvelles versions d'Android.
  • Le cluster d'instruments peut être l'un des éléments suivants: <ph type="x-smartling-placeholder">
      </ph>
    • Écran secondaire physique connecté à la HU. Si le le matériel et le noyau de l’appareil prennent en charge la gestion de plusieurs écrans.
    • Bloc indépendant. Toute unité de calcul connectée au HU via une connexion réseau, capable de recevoir et d'afficher un flux vidéo sur son propre écran.
    • Écran émulé. Pendant le développement, vous pouvez utiliser ces environnements émulés: <ph type="x-smartling-placeholder">
        </ph>
      • Écrans secondaires simulés. Pour activer une simulation écran secondaire sur n'importe quelle distribution Android AOSP, accédez aux Options pour les développeurs dans l'application système Paramètres, puis sélectionnez Simuler une application "écrans". Cette configuration équivaut à connecter un serveur d'affichage, à ceci près que celui-ci est superposé à l'affichage principal l'écran.
      • Cluster d'instruments émulés. Android Emulator inclus avec AAOS permet d'afficher un groupe d'instruments ClusterRenderingService.

Architecture d'intégration

Composants d'intégration

Toute intégration de l'API Instrument Cluster comprend les trois composants suivants:

  • CarService
  • Applications de navigation
  • Service de cluster d'instruments OEM

Composants d&#39;intégration

CarService

CarService effectue la médiation entre les applications de navigation et la voiture, afin de s'assurer que une seule application de navigation est active et seules les applications dont le L'autorisation android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL peut envoyer des données à la voiture.

CarService démarre tous les services spécifiques aux voitures et donne accès à ces services par le biais d'une série de gestionnaires. Pour interagir avec les services, les applis exécutées dans la voiture peuvent accéder à ces gestionnaires.

Pour la mise en œuvre d'un groupe d'instruments, les OEM automobiles doivent créer un la mise en œuvre d'InstrumentClusterRendererService et mettez à jour ClusterRenderingService.

Lors du rendu d'un cluster d'instruments, le processus de démarrage CarService lit la clé InstrumentClusterRendererService du ClusterRenderingService pour localiser une implémentation de InstrumentClusterService. Dans AOSP, cette entrée pointe vers le service de rendu de l'exemple d'implémentation de cluster de l'API Navigation State:

<string name="instrumentClusterRendererService">
android.car.cluster/.ClusterRenderingService
</string>

Le service mentionné dans cette entrée est initialisé et lié à CarService Lorsque les applications de navigation, comme Google Maps, demandent un CarInstrumentClusterManager et CarService fournit un gestionnaire qui met à jour l'état du cluster d'instruments à partir du InstrumentClusterRenderingService lié. (Dans ce cas, bound fait référence à Sur Android Services.)

Service de cluster d'instruments

Les OEM doivent créer un package Android (APK) contenant une sous-classe de ClusterRenderingService.

Cette classe sert deux objectifs:

  • Fournit une interface Android et l'appareil de rendu du cluster d'instruments (objectif de cette page).
  • Reçoit et affiche des mises à jour de l'état de la navigation, telles que la navigation détaillée le guidage de la navigation.

Dans le premier cas, les implémentations OEM de InstrumentClusterRendererService doit initialiser l'affichage secondaire utilisé pour afficher les informations sur les écrans de l'habitacle de la voiture et communiquer ces informations à CarService en appelant la InstrumentClusterRendererService.setClusterActivityOptions() et InstrumentClusterRendererService.setClusterActivityState().

Pour la deuxième fonction, le service de cluster d'instruments doit fournir une la mise en œuvre ClusterRenderingService qui reçoit des événements de mise à jour de l'état de la navigation, qui sont encodés en tant que eventType et données d'événement encodées dans un bundle.

Séquence d'intégration

Le schéma suivant illustre l'implémentation d'un état de navigation qui affiche les mises à jour:

Séquence d&#39;intégration

Dans cette illustration, les couleurs indiquent ce qui suit:

  • Jaune. CarService et CarNavigationStatusManager fournis par la plate-forme Android. Pour en savoir plus, consultez Car et CAR_NAVIGATION_SERVICE :
  • Cyan. InstrumentClusterRendererService implémenté par l'OEM.
  • Violet. Application Navigation implémentée par Google et par des tiers développeurs.
  • Vert. CarAppFocusManager. Pour en savoir plus, consultez Utiliser l'API CarAppFocusManager ci-dessous et CarAppFocusManager.

Le flux d'informations sur l'état de la navigation suit cette séquence:

  1. CarService initialise InstrumentClusterRenderingService.
  2. Lors de l'initialisation, InstrumentClusterRenderingService est mis à jour CarService avec: <ph type="x-smartling-placeholder">
      </ph>
    1. Propriétés d'affichage du cluster d'instruments, telles que les limites claires (vous trouverez plus d'informations sur les limites claires plus tard).
    2. Options d'activité nécessaires pour lancer des activités dans l'écran du cluster d'instruments. Pour en savoir plus, consultez ActivityOptions.
  3. Une application de navigation (par exemple, Google Maps pour Android Automotive ou toute application de cartographie) disposant des autorisations requises): <ph type="x-smartling-placeholder">
      </ph>
    1. Récupère un CarAppFocusManager à l'aide de la classe Car de car-lib.
    2. Avant le lancement de la navigation détaillée, les appels vers CarAppFocusManager.requestFocus() pour réussir CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION en tant que appType .
  4. CarAppFocusManager communique cette requête à CarService. Si cette autorisation est accordée, CarService inspecte le package de l'application de navigation et localise activité de la catégorie android.car.cluster.NAVIGATION.
  5. Si elle est trouvée, l'application de navigation utilise la ActivityOptions indiquée par le InstrumentClusterRenderingService pour lancer l'activité et inclut les Instrumentez les propriétés d'affichage du cluster en tant qu'extras dans l'intent.

Intégrer l'API

L'implémentation de InstrumentClusterRenderingService doit:

  • être désigné comme un service singleton en ajoutant la valeur suivante à le fichier AndroidManifest.xml. Cela est nécessaire pour garantir qu'une seule copie Le service de cluster d'instruments s'exécute, même pendant l'initialisation et le changement d'utilisateur:
    android:singleUser="true"
  • Conservez l'autorisation système BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE. Ce garantit que seul le service de rendu du cluster d'instruments est inclus de l'image système Android est toujours liée par CarService:
    <uses-permission android:name="android.car.permission.BIND_INSTRUMENT_CLUSTER_RENDERER_SERVICE"/>
    

Implémenter le service InstrumentClusterRenderingService

Pour créer le service:

  1. Écrivez une classe qui s'étend de ClusterRenderingService puis ajoutez l'entrée correspondante dans votre fichier AndroidManifest.xml. Ce cours contrôle l'affichage du cluster d'instruments et peut afficher (en option) l'état de navigation les données de l'API.
  2. Pendant onCreate(), utilisez ce service pour initialiser la communication avec le matériel de rendu. Les options sont les suivantes: <ph type="x-smartling-placeholder">
      </ph>
    • Déterminez l'affichage secondaire à utiliser pour le cluster d'instruments.
    • Créez un affichage virtuel afin que l'application Cluster d'instruments affiche et transmet le dans une unité externe (en utilisant un format de streaming vidéo tel que H.264).
  3. Lorsque l'écran indiqué ci-dessus est prêt, ce service doit appeler InstrumentClusterRenderingService#setClusterActivityLaunchOptions() pour définir le ActivityOptions exact qui doit être utilisé pour afficher une activité sur le Cluster d'instruments. Utilisez les paramètres suivants: <ph type="x-smartling-placeholder">
      </ph>
    • category. ClusterRenderingService.
    • ActivityOptions. : instance ActivityOptions pouvant être utilisée pour lancer une activité dans le cluster "Instruments". Par exemple, à partir de l'exemple Implémentation d'un cluster d'instruments sur AOSP:
      getService().setClusterActivityLaunchOptions(
        CATEGORY_NAVIGATION,
        ActivityOptions.makeBasic()
            .setLaunchDisplayId(displayId));
  4. Lorsque le cluster "Instruments" est prêt à afficher les activités, ce service doit appeler InstrumentClusterRenderingService#setClusterActivityState() Utilisez ces paramètres: <ph type="x-smartling-placeholder">
      </ph>
    • category ClusterRenderingService.
    • state groupe généré avec ClusterRenderingService. Veillez à fournir ces données: <ph type="x-smartling-placeholder">
        </ph>
      • visible spécifie que le cluster d'instruments est visible et prêt à afficher du contenu.
      • unobscuredBounds : rectangle qui définit la zone à l'intérieur de Écran du cluster d'instruments, sur lequel l'affichage du contenu peut être effectué en toute sécurité. Par exemple, les zones couvertes par des cadrans et des jauges.
  5. Remplacez la méthode Service#dump() et signalez les informations d'état utiles pour débogage (voir dumpsys pour en savoir plus).

Exemple d'implémentation d'InstrumentClusterRenderingService

L'exemple suivant décrit un élément InstrumentClusterRenderingService qui crée un VirtualDisplay pour présenter l'objet Instrument Mettre en cluster le contenu sur un écran physique distant

Ce code peut également transmettre le displayId d'un serveur secondaire physique l'écran connecté au HU, s'il est disponible.

/**
* Sample {@link InstrumentClusterRenderingService} implementation
*/
public class SampleClusterServiceImpl extends InstrumentClusterRenderingService {
   // Used to retrieve or create displays
   private final DisplayManager mDisplayManager;
   // Unique identifier for the display to be used for instrument
   // cluster
   private final String mUniqueId = UUID.randomUUID().toString();
   // Format of the instrument cluster display
   private static final int DISPLAY_WIDTH = 1280;
   private static final int DISPLAY_HEIGHT = 720;
   private static final int DISPLAY_DPI = 320;
   // Area not covered by instruments
   private static final int DISPLAY_UNOBSCURED_LEFT = 40;
   private static final int DISPLAY_UNOBSCURED_TOP = 0;
   private static final int DISPLAY_UNOBSCURED_RIGHT = 1200;
   private static final int DISPLAY_UNOBSCURED_BOTTOM = 680;
   @Override
   public void onCreate() {
      super.onCreate();
      // Create a virtual display to render instrument cluster activities on
      mDisplayManager = getSystemService(DisplayManager.class);
      VirtualDisplay display = mDisplayManager.createVirtualDisplay(
          mUniqueId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_DPI, null,
          0 /* flags */, null, null);
      // Do any additional initialization (e.g.: start a video stream
      // based on this virtual display to present activities on a remote
      // display).
      onDisplayReady(display.getDisplay());
}
private void onDisplayReady(Display display) {
    // Report activity options that should be used to launch activities on
    // the instrument cluster.
    String category = CarInstrumentClusterManager.CATEGORY_NAVIGATION;
    ActionOptions options = ActivityOptions.makeBasic()
        .setLaunchDisplayId(display.getDisplayId());
    setClusterActivityOptions(category, options);
    // Report instrument cluster state.
    Rect unobscuredBounds = new Rect(DISPLAY_UNOBSCURED_LEFT,
        DISPLAY_UNOBSCURED_TOP, DISPLAY_UNOBSCURED_RIGHT,
        DISPLAY_UNOBSCURED_BOTTOM);
    boolean visible = true;
    ClusterActivityState state = ClusterActivityState.create(visible,
       unobscuredBounds);
    setClusterActivityState(category, options);
  }
}

Utiliser l'API CarAppFocusManager

L'API CarAppFocusManager fournit une méthode nommée getAppTypeOwner(), qui permet Le service de cluster écrit par les OEM pour savoir quelle application de navigation cible la navigation en temps réel. Les OEM peuvent utiliser la méthode CarAppFocusManager#addFocusListener() existante. puis utilisez getAppTypeOwner() pour identifier l'application ciblée. Grâce à ces informations, Les OEM peuvent:

  • Basculez l'activité affichée dans le cluster sur l'activité du cluster fournie par l'application de navigation en maintenant le focus.
  • Peut détecter si l'application de navigation sélectionnée présente une activité de cluster ou non. Si l'élément sélectionné l'application de navigation n'a pas d'activité de cluster (ou si cette activité est désactivée), les OEM peuvent envoyer ce signal à l'DIM de la voiture afin que l'attribut de navigation du cluster soit complètement ignoré.

Utilisez CarAppFocusManager pour définir et écouter le focus de l'application actuel, comme : la navigation active ou une commande vocale. Habituellement, une seule instance de ce type d'application est activement en cours d'exécution (ou ciblées) dans le système.

Utiliser la méthode CarAppFocusManager#addFocusListener(..) pour écouter le focus de l'application modifications:

import android.car.CarAppFocusManager;

...

Car car = Car.createCar(this);
mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE);
mAppFocusManager.addFocusListener(this, CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);

...

public void onAppFocusChanged(int appType, boolean active) {
    // Use the CarAppFocusManager#getAppTypeOwner(appType) method call
    // to retrieve a list of active package names
}

Utiliser la méthode CarAppFocusManager#getAppTypeOwner(..) pour récupérer le package noms du propriétaire actuel d'un type d'application donné qui est sélectionné. Cette méthode peut renvoyer plusieurs noms de package si le propriétaire actuel utilise la fonctionnalité android:sharedUserId.

import android.car.CarAppFocusManager;

...

Car car = Car.createCar(this);
mAppFocusManager = (CarAppFocusManager)car.getCarManager(Car.APP_FOCUS_SERVICE);
List<String> focusOwnerPackageNames = mAppFocusManager.getAppTypeOwner(
              CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);

if (focusOwnerPackageNames == null || focusOwnerPackageNames.isEmpty()) {
        // No Navigation app has focus
        // OEM may choose to show their default cluster view
} else {
       // focusOwnerPackageNames
       // Use the PackageManager to retrieve the cluster activity for the package(s)
       // returned in focusOwnerPackageNames
}

...

Annexe: Utiliser l'application exemple

AOSP fournit une application exemple qui implémente l'API Navigation State.

Pour exécuter cette application exemple, procédez comme suit:

  1. Créez et flashez Android Auto sur une HU compatible. Utilisez les Instructions de compilation et de flashage Android spécifiques à votre appareil. Pour savoir comment procéder, consultez Utiliser des tableaux de référence.
  2. Connectez un écran secondaire physique à la HU (si compatible) ou activez l'écran virtuel HU secondaire: <ph type="x-smartling-placeholder">
      </ph>
    1. Dans l'application Paramètres, sélectionnez Mode développeur.
    2. Accédez à Paramètres > Système > Paramètres avancés > Options pour les développeurs > Simuler des écrans secondaires
  3. Redémarrer la HU
  4. Pour lancer l'application KitchenSink:
    1. Ouvrez le panneau.
    2. Accédez à Inst. Cluster.
    3. Cliquez sur COMMENCER LES MÉTADONNÉES.

KitchenSink demande la sélection NAVIGATION, ce qui indique à DirectRenderingCluster pour afficher une simulation d'interface utilisateur sur le cluster d'instruments.