Ausführungsbefehle

Auf dieser Seite wird beschrieben, wie Sie Befehle per Sprachbefehl ausführen.

Medienbefehle ausführen

Medienbezogene Befehle lassen sich in drei verschiedene Gruppen unterteilen:

  • Externe Medienquellen (wie Spotify, die in AAOS installiert sind)
  • Back-End-Medienquellen (z. B. über VIA gestreamte Musik)
  • Lokale Medienquellen (z. B. Autoradio)

Befehle von externen Medienquellen verarbeiten

Externe Medienquellen sind Android-Apps, die MediaSessionCompat unterstützen und MediaBrowseCompat APIs (siehe Medien-Apps erstellen für Autos.

Wichtig:Damit sich eine Assistant-App mit dem MediaBrowseService aller installierten Medien-Apps im müssen folgende Voraussetzungen erfüllt sein:

  1. als systemsigniert installiert (siehe Richtlinien zur Entwicklung von Medienanwendungen für AAOS und den Beispielcode PackageValidator).
  2. android.permission.MEDIA_CONTENT_CONTROL systemprivilegiert halten (siehe Erteilen von Berechtigungen) Systemprivilegierte Berechtigungen)

Zusätzlich zu MediaBrowserCompat und MediaControllerCompat, AAOS bietet Folgendes:

  • CarMediaService stellt zentralisierte Informationen zur aktuell ausgewählten Medienquelle bereit. Dies ist wird auch verwendet, um eine zuvor abgespielte Medienquelle nach dem Ausschalten des Autos bzw. Neustarts des Autos fortzusetzen.
  • car-media-common bietet praktische Methoden zum Auflisten, Verbinden und Interagieren mit Medien-Apps.

Nachfolgend finden Sie Richtlinien für die Implementierung gängiger Sprachinteraktionen .

Liste der installierten Medienquellen abrufen

Medienquellen können mit PackageManager erkannt werden. und Filtern nach Diensten, die dem MediaBrowserService.SERVICE_INTERFACE entsprechen. In einigen Autos gibt es spezielle Implementierungen von Medienbrowserdiensten, die ausgeschlossen werden sollte. Hier ist ein Beispiel für diese Logik:

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;
}

Medienquellen können jederzeit installiert oder deinstalliert werden. In Um eine korrekte Liste zu erhalten, wird empfohlen, eine BroadcastReceiver zu implementieren. Instanz für die Intent-Aktionen ACTION_PACKAGE_ADDED ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REPLACED und ACTION_PACKAGE_REMOVED.

Mit der gerade wiedergegebenen Medienquelle verbinden

CarMediaService Methoden zum Abrufen der aktuell ausgewählten Medienquelle und zum Änderungen an der Quelle. Diese Änderungen können auftreten, weil der Nutzer mit dem direkt auf der Benutzeroberfläche oder über Hardwaretasten im Auto Im Gegensatz dazu Die Automedia-Bibliothek bietet praktische Möglichkeiten, eine Verbindung zu bestimmten Medien herzustellen. Quelle. Hier ist ein vereinfachtes Snippet für die Verbindung mit der aktuell ausgewählten Medien-App:

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
    }

    …
}

Wiedergabe der aktuell wiedergegebenen Medienquelle steuern

Mit einem verbundenen MediaBrowserCompat ist es einfach, Verkehrsmittel Steuerbefehle an die Ziel-App senden. Hier ist eine vereinfachte Beispiel:

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;
    }

    …
}

Befehle für lokale Medienquellen (Radio, CD-Player, Bluetooth, USB)

Lokale Medienquellen stellen dem System ihre Funktionen über dieselben MediaSession und MediaBrowse APIs (siehe oben) Um die Besonderheiten verwenden diese MediaBrowse-Dienste bestimmte Konventionen, ihre Informationen und Medienbefehle.

Radio verwenden

Radio MediaBrowseService kann an der ACTION_PLAY_BROADCASTRADIO erkannt werden. Intent-Filter. Es wird erwartet, dass sie die Wiedergabesteuerung und die Mediensuche befolgen. wie unter Radio implementieren beschrieben. AAOS bietet car-broadcastradio-support Bibliothek mit Konstanten und Methoden, die OEMs beim Erstellen von MediaBrowseService unterstützen Implementierungen für ihre eigenen Radiodienste, die dem definierten Protokoll folgen, und bietet Unterstützung für Anwendungen, die ihren Suchbaum nutzen (z. B. VIAs).

AUX-Eingang, CD-Audio und USB-Medien verarbeiten

Es gibt keine Standardimplementierung dieser Medienquellen als Teil von AOSP. Der empfohlene Ansatz sieht so aus:

  • Lassen Sie OEMs jeweils Mediendienste implementieren. Weitere Informationen finden Sie im Hilfeartikel Medien-Apps für Autos entwickeln.
  • Diese MediaBrowseService-Implementierungen werden identifiziert und in der Absicht Aktionen, die unter Allgemeine Spiele-Intents definiert sind
  • Diese Dienste würden einen Suchbaum gemäß den beschriebenen Richtlinien bereitstellen. unter Andere Quelltypen.

Umgang mit Bluetooth

Bluetooth-Medieninhalte werden über das AVRCP-Bluetooth-Profil freigegeben. In Um den Zugriff auf diese Funktion zu erleichtern, enthält AAOS eine MediaBrowserService- und MediaSession-Implementierung, die das Kommunikationsdetails (siehe Pakete/Apps/Bluetooth)

Die Baumstruktur des jeweiligen Medienbrowsers wird unter BrowseTree definiert. . Steuerbefehle für die Wiedergabe können ähnlich wie jede andere App übermittelt werden, mithilfe der MediaSession-Implementierung.

Befehle für Streaming Media verarbeiten

Um serverseitiges Mediastreaming zu implementieren, muss die VIA zu sich selbst werden. eine Medienquelle, die MediaBrowse und die MediaSession API implementiert. Weitere Informationen finden Sie unter Medien-Apps entwickeln für Autos. Durch die Implementierung dieser APIs könnte eine Sprachsteuerungs-App (unter anderem):

  • Nahtlos an der Auswahl der Medienquelle teilnehmen
  • Automatische Fortsetzung nach dem Neustart des Autos
  • Wiedergabe- und Browsersteuerung über die Media Center-Benutzeroberfläche
  • Ereignisse zu Standard-Hardwaremedientasten empfangen

Es gibt keine standardisierte Art der Interaktion mit allen Navigations-Apps. Informationen zur Integration in Google Maps finden Sie unter Google Maps for Android Automotive Intents Für Integrationen mit anderen sollten Sie sich direkt an die App-Entwickler wenden. Vor der Einführung Intent für eine App (einschließlich Google Maps) erstellt haben, prüfen Sie, ob der Intent behoben (siehe Intent -Anfragen). So haben Sie die Möglichkeit, die Nutzenden zu informieren, falls die Ziel-App nicht verfügbar ist.

Fahrzeugbefehle ausführen

Der Zugriff auf Fahrzeugeigenschaften für Lese- und Schreibzugriff erfolgt über CarPropertyManager zur Verfügung. Fahrzeugeigenschaftentypen, ihre Implementierung und andere Details werden erläutert in Property Konfigurationen Für eine genaue Beschreibung der unterstützten Eigenschaften von Android, empfehlen wir, direkt auf hardware/interfaces/automotive/vehicle/2.0/types.hal zu verweisen. Das Attribut VehicleProperty Die dort definierte Enum enthält sowohl standardmäßige als auch anbieterspezifische Eigenschaften, Daten Typen, Änderungsmodus, Einheiten und Definition des Lese-/Schreibzugriffs.

Um in Java auf dieselben Konstanten zuzugreifen, können Sie VehiclePropertyIds verwenden. und zugehörigen Companion-Klassen. Unterschiedliche Properties haben unterschiedliche Android-Berechtigungen, Zugriff haben. Diese Berechtigungen werden im CarService Manifest und die Zuordnung zwischen Properties und Berechtigungen beschrieben. in VehiclePropertyIds Javadoc, die in PropertyHalServiceIds erzwungen werden.

Fahrzeugeigenschaft lesen

Das folgende Beispiel zeigt, wie die Fahrzeuggeschwindigkeit gelesen wird:

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);
    }

    ...
}

Fahrzeugeigenschaft festlegen

Das folgende Beispiel zeigt, wie die Klimaanlage vorne ein- und ausgeschaltet wird.

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"));
    }

    …
}

Kommunikationsbefehle ausführen

Messaging-Befehle verarbeiten

VIAs müssen eingehende Nachrichten nach dem „Tap-to-Read“-Protokoll verarbeiten. beschriebener Ablauf im Sprachassistenten Tap-to-Read: Damit können optional Antworten an den Absender eingehender Nachrichten gesendet werden. Außerdem können VIAs SmsManager verwenden. (Teil der android.telephony -Paket), um SMS direkt im Auto oder über Bluetooth zu verfassen und zu senden.

Anrufbefehle verarbeiten

Ähnliches gilt für VIAs: TelephonyManager , um Telefonanrufe zu tätigen und die Voicemail-Nummer des Nutzers anzurufen. In diesen Fällen VIAs interagieren direkt mit dem Telefonie-Stack oder mit dem Auto-Dialer. In jedem Fall sollte die Auto-Dialer-App Sprachanruf-Benutzeroberfläche für den Nutzer.

Andere Befehle ausführen

Eine Liste weiterer möglicher Integrationspunkte zwischen VIA und dem finden Sie in der Liste bekannter Android-Intents. Viele Benutzerbefehle können serverseitig aufgelöst werden (z. B. Lesen E-Mail-Adressen und Kalenderterminen Ihrer Nutzer) und erfordern keine Interaktion mit dem System, als die Sprachinteraktion selbst.

Immersive Aktionen (visuelle Inhalte anzeigen)

VIA kann die Nutzeraktionen oder das Verständnis verbessern. zusätzliche visuelle Inhalte auf dem Autodisplay. Damit der Fahrer nicht abgelenkt wird, Halten Sie solche Inhalte einfach, kurz und entscheidungsrelevant. Weitere Informationen zu UI-/UX-Richtlinien zu immersiven Aktionen, siehe Vorinstallierte Assistenten: UX-Anleitung.

Um Anpassungen und Einheitlichkeit mit für das restliche Design der Haupteinheit (HU), sollten VIAs Auto UI Library-Komponenten für die meisten UI-Elemente. Weitere Informationen finden Sie unter Anpassung: