Exécuter les commandes

Cette page explique comment utiliser des commandes vocales.

Traiter les commandes multimédias

La commande liée aux contenus multimédias peut être divisée en trois groupes différents:

  • Sources multimédias externes (telles que Spotify installées dans AAOS)
  • Sources multimédias backend (musique diffusée par l'intermédiaire de l'interface VIA, par exemple)
  • Sources multimédias locales (radio, par exemple)

Gérer les commandes de sources multimédias externes

Les sources multimédias externes sont définies comme des applications Android compatibles avec MediaSessionCompat. et MediaBrowseCompat (consultez Créer des applications multimédias voitures pour obtenir des explications détaillées sur l'utilisation de ces API).

Important:Pour qu'une application d'assistant se connecte au MediaBrowseService de toutes les applications multimédias installées dans le il doit:

  1. être installé en tant que signé par le système (consultez les consignes de développement d'applications multimédias pour AAOS et l'exemple de code PackageValidator).
  2. Conserver les privilèges système android.permission.MEDIA_CONTENT_CONTROL (voir la section Autorisations autorisations privilégiées du système).

En plus de MediaBrowserCompat et MediaControllerCompat, AAOS fournit les éléments suivants:

  • CarMediaService fournit des informations centralisées sur la source multimédia sélectionnée. C'est également utilisé pour reprendre la lecture d'une source multimédia précédemment après l'arrêt ou le redémarrage de la voiture.
  • car-media-common fournit des méthodes pratiques pour répertorier, se connecter et interagir. avec des applications multimédias.

Vous trouverez ci-dessous des consignes spécifiques à l'implémentation des interactions vocales courantes. commandes.

Obtenir la liste des sources multimédias installées

Les sources multimédias peuvent être détectées à l'aide de PackageManager, et le filtrage des services correspondant au MediaBrowserService.SERVICE_INTERFACE. Dans certaines voitures, il peut y avoir des implémentations spéciales de services de navigateur multimédia, qui doivent être exclus. Voici un exemple de cette logique:

private Map<String, MediaSource> getAvailableMediaSources() {
    List<String> customMediaServices =
        Arrays.asList(mContext.getResources()
            .getStringArray(R.array.custom_media_packages));
    List<ResolveInfo> mediaServices = mPackageManager.queryIntentServices(
            new Intent(MediaBrowserService.SERVICE_INTERFACE),
            PackageManager.GET_RESOLVED_FILTER);
    Map<String, MediaSource> result = new HashMap<>();
    for (ResolveInfo info : mediaServices) {
        String packageName = info.serviceInfo.packageName;
        if (customMediaServices.contains(packageName)) {
            // Custom media sources should be ignored, as they might have a
            // specialized handling (e.g., radio).
            continue;
        }
        String className = info.serviceInfo.name;
        ComponentName componentName = new ComponentName(packageName,
            className);
        MediaSource source = MediaSource.create(mContext, componentName);
        result.put(source.getDisplayName().toString().toLowerCase(),
            source);
    }
    return result;
}

Sachez que les sources multimédias peuvent être installées ou désinstallées à tout moment. Dans Afin de maintenir une liste précise, nous vous recommandons d'implémenter un BroadcastReceiver une instance pour les actions d'intent ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REPLACED et ACTION_PACKAGE_REMOVED.

Se connecter à la source multimédia en cours de lecture

CarMediaService fournit des méthodes pour obtenir la source multimédia actuellement sélectionnée, ainsi que les cas où ce contenu les modifications de la source. Ces changements peuvent se produire parce que l'utilisateur a interagi avec UI directement ou en raison de l'utilisation de boutons physiques dans la voiture. Par ailleurs, La bibliothèque car-media-common propose des moyens pratiques de se connecter à un contenu multimédia donné source. Voici un aperçu simplifié de la procédure de connexion à l'instance actuellement sélectionnée. application multimédia:

public class MediaActuator implements
        MediaBrowserConnector.onConnectedBrowserChanged {
    private final Car mCar;
    private CarMediaManager mCarMediaManager;
    private MediaBrowserConnector mBrowserConnector;

    …

    public void initialize(Context context) {
        mCar = Car.createCar(context);
        mBrowserConnector = new MediaBrowserConnector(context, this);
        mCarMediaManager = (CarMediaManager)
            mCar.getCarManager(Car.CAR_MEDIA_SERVICE);
        mBrowserConnector.connectTo(mCarMediaManager.getMediaSource());
        …
    }

    @Override
    public void onConnectedBrowserChanged(
            @Nullable MediaBrowserCompat browser) {
        // TODO: Handle connected/disconnected browser
    }

    …
}

Contrôler la lecture de la source multimédia en cours de lecture

Avec un MediaBrowserCompat connecté il est facile d'envoyer des messages commandes de contrôle à l'application cible. Voici une version simplifiée Exemple:

public class MediaActuator …  {
    …
    private MediaControllerCompat mMediaController;

    @Override
    public void onConnectedBrowserChanged(
            @Nullable MediaBrowserCompat browser) {
        if (browser != null && browser.isConnected()) {
            mMediaController = new MediaControllerCompat(mContext,
                browser.getSessionToken());
        } else {
            mMediaController = null;
        }
    }

    private boolean playSongOnCurrentSource(String song) {
        if (mMediaController == null) {
            // No source selected.
            return false;
        }
        MediaControllerCompat.TransportControls controls =
            mMediaController.getTransportControls();
        PlaybackStateCompat state = controller.getPlaybackState();
        if (state == null || ((state.getActions() &
                PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH) == 0)) {
            // Source can't play from search
            return false;
        }
        controls.playFromSearch(query, null);
        return true;
    }

    …
}

Gérer les commandes de la source multimédia locale (radio, lecteur CD, Bluetooth, USB)

Les sources multimédias locales exposent leurs fonctionnalités au système à l'aide de la même API MediaSession et MediaBrowse détaillées ci-dessus. Pour tenir compte des spécificités de pour chaque type de matériel, ces services MediaBrowse utilisent des conventions spécifiques pour organiser leurs informations et leurs commandes multimédias.

Gérer la radio

Le service Radio MediaBrowseService peut être identifié par le ACTION_PLAY_BROADCASTRADIO filtre d'intent intégré. Ils doivent suivre les commandes de lecture et parcourir les contenus multimédias. décrit dans la section Implémenter le signal radio. AAOS propose car-broadcastradio-support Bibliothèque contenant des constantes et des méthodes pour aider les OEM à créer MediaBrowseService les implémentations pour leurs propres services de radio qui suivent le protocole défini, et est compatible avec les applications qui consomment leur arborescence de navigation (par exemple, les ViA).

Gérer l'entrée auxiliaire, l'audio CD et les périphériques USB

Il n'existe pas d'implémentation par défaut de ces sources multimédias dans AOSP. L'approche suggérée est la suivante:

Gérer le Bluetooth

Le contenu multimédia Bluetooth est exposé via le profil Bluetooth AVRCP. Dans afin de faciliter l'accès à cette fonctionnalité, AAOS inclut MediaBrowserService et l'implémentation MediaSession qui élimine le les détails de la communication (voir packages/apps/Bluetooth).

L'arborescence des navigateurs multimédias est définie dans BrowseTree. . Les commandes de contrôle de la lecture peuvent être transmises comme n'importe quelle autre application, à l'aide de son implémentation MediaSession.

Gérer les commandes de streaming de contenu multimédia

Pour implémenter le streaming multimédia côté serveur, l'interface doit devenir elle-même. une source multimédia, l'implémentation de l'API MediaBrowse et de l'API MediaSession. Consultez Créer des applications multimédias pour les voitures. En implémentant ces API, une application de commande vocale pourrait (entre autres):

  • Participation fluide à la sélection des sources multimédias
  • Reprise automatique après le redémarrage de la voiture
  • Fournir des commandes de lecture et de navigation à l'aide de l'interface utilisateur de Media Center
  • Recevoir les événements standards de boutons multimédias matériels

Il n'existe aucune manière standardisée d'interagir avec toutes les applications de navigation. Pour les intégrations avec Google Maps, consultez Google Maps pour Android Automotive Intents Pour les intégrations avec d'autres applications, contactez directement les développeurs des applications. Avant le lancement un intent vers n'importe quelle application (y compris Google Maps), vérifiez qu'il peut être résolues (voir Intention requêtes). Cela permet d'informer l'utilisateur au cas où l'application cible n'est pas disponible.

Exécuter les commandes du véhicule

L'accès aux propriétés du véhicule en lecture et en écriture est fourni via CarPropertyManager Explication des types de propriétés des véhicules, de leur implémentation et d'autres détails dans Propriété de configuration. Pour obtenir une description précise des propriétés prises en charge, par Android, il est préférable de faire référence directement à hardware/interfaces/automotive/vehicle/2.0/types.hal. VehicleProperty "enum" définie contient à la fois des propriétés standards et spécifiques au fournisseur, les types, le mode de modification, les unités et la définition de l'accès en lecture/écriture.

Pour accéder à ces mêmes constantes à partir de Java, vous pouvez utiliser VehiclePropertyIds et ses classes associées. Les autorisations Android varient selon les propriétés y accéder. Ces autorisations sont déclarées dans le CarService manifeste, et le mappage entre les propriétés et les autorisations décrites dans VehiclePropertyIds Javadoc et appliquées dans PropertyHalServiceIds.

Lire la propriété d'un véhicule

L'exemple suivant montre comment lire la vitesse du véhicule:

public class CarActuator ... {
    private final Car mCar;
    private final CarPropertyManager mCarPropertyManager;
    private final TextToSpeech mTTS;

    /** Global VHAL area id */
    public static final int GLOBAL_AREA_ID = 0;

    public CarActuator(Context context, TextToSpeech tts) {
        mCar = Car.createCar(context);
        mCarPropertyManager = (CarPropertyManager) mCar.getCarManager(Car.PROPERTY_SERVICE);
        mTTS = tts;
        ...
    }

    @Nullable
    private void getSpeedInMetersPerSecond() {
        if (!mCarPropertyManager.isPropertyAvailable(VehiclePropertyIds.PERF_VEHICLE_SPEED,
                GLOBAL_AREA_ID)) {
            mTTS.speak("I'm sorry, but I can't read the speed of this vehicle");
            return;
        }
        // Data type and unit can be found in
        // automotive/vehicle/2.0/types.hal
        float speedInMps = mCarPropertyManager.getFloatProperty(
                VehiclePropertyIds.PERF_VEHICLE_SPEED, GLOBAL_AREA_ID);
        int speedInMph = (int)(speedInMetersPerSecond * 2.23694f);
        mTTS.speak(String.format("Sure. Your current speed is %d miles "
                + "per hour", speedInUserUnit);
    }

    ...
}

Définir une propriété pour un véhicule

L'exemple suivant montre comment allumer et éteindre la climatisation avant.

public class CarActuator … {
    …

    private void changeFrontAC(boolean turnOn) {
        List<CarPropertyConfig> configs = mCarPropertyManager
                .getPropertyList(new ArraySet<>(Arrays.asList(
                    VehiclePropertyIds.HVAC_AC_ON)));
        if (configs == null || configs.size() != 1) {
            mTTS.speak("I'm sorry, but I can't control the AC of your vehicle");
            return;
        }

        // Find the front area Ids for the AC property.
        int[] areaIds = configs.get(0).getAreaIds();
        List<Integer> areasToChange = new ArrayList<>();
        for (int areaId : areaIds) {
            if ((areaId & (VehicleAreaSeat.SEAT_ROW_1_CENTER
                        | VehicleAreaSeat.SEAT_ROW_1_LEFT
                        | VehicleAreaSeat.SEAT_ROW_1_RIGHT)) == 0) {
                continue;
            }
            boolean isACInAreaAlreadyOn = mCarPropertyManager
                    .getBooleanProperty(VehiclePropertyIds.HVAC_AC_ON, areaId);
            if ((!isACInAreaAlreadyOn && turnOn) || (isACInAreaAlreadyOn && !turnOn)) {
                areasToChange.add(areaId);
            }
        }
        if (areasToChange.isEmpty()) {
            mTTS.speak(String.format("The AC is already %s", turnOn ? "on" : "off"));
            return;
        }

        for (int areaId : areasToChange) {
            mCarPropertyManager.setBooleanProperty(
                VehiclePropertyIds.HVAC_AC_ON, areaId, turnOn);
        }
        mTTS.speak(String.format("Okay, I'm turning your front AC %s",
            turnOn ? "on" : "off"));
    }

    …
}

Exécuter les commandes de communication

Gérer les commandes de messagerie

Les VIA doivent gérer les messages entrants après l'opération "Appuyer pour lire" procédure décrite dans Assistant vocal La fonctionnalité Appuyer pour lire, qui peut éventuellement gérer le renvoi des réponses à l'expéditeur du message entrant. De plus, les Via peuvent utiliser SmsManager. (dans le android.telephony ) pour rédiger et envoyer des SMS directement depuis la voiture ou via Bluetooth.

Gérer les commandes d'appel

De la même manière, les Via peuvent utiliser TelephonyManager. pour passer des appels téléphoniques et appeler le numéro de la messagerie vocale de l'utilisateur. Dans ces cas, Les assistants virtuels interagiront directement avec la pile de téléphonie ou avec l'application Car Dialer. l'application. Dans tous les cas, c'est l'application Car Dialer de l'interface utilisateur liée aux appels vocaux.

Exécuter d'autres commandes

Pour obtenir la liste des autres points d'intégration possibles entre l'IVA et consultez la liste des intents Android connus. Beaucoup les commandes utilisateur peuvent être résolues côté serveur (par exemple, lire les e-mails et les événements d'agenda des utilisateurs) et n'ont pas besoin d'interagir avec le système autres que l'interaction vocale elle-même.

Actions immersives (afficher du contenu visuel)

Lorsqu'elle améliore la compréhension ou les actions des utilisateurs, une VIA peut fournir du contenu visuel supplémentaire sur l'écran de la voiture. Pour limiter les distractions au volant, ce contenu doit rester simple, bref et exploitable. Pour en savoir plus sur les consignes relatives à l'UI/l'expérience utilisateur sur les actions immersives, consultez Assistants préchargés: conseils sur l'expérience utilisateur.

Pour permettre la personnalisation et la cohérence avec le reste de l'unité principale, les visuels d'interface utilisateur doivent utiliser Voiture Composants de la bibliothèque d'UI pour la plupart des éléments de l'UI. Pour en savoir plus, consultez Personnalisation.