Completa i comandi

In questa pagina viene descritto come eseguire i comandi tramite interazione vocale.

Completa i comandi multimediali

Il comando relativo ai contenuti multimediali può essere suddiviso in tre gruppi diversi:

  • Fonti multimediali esterne (come Spotify installato con AAOS).
  • Sorgenti multimediali di backend (come musica riprodotta in streaming tramite VIA).
  • Fonti multimediali locali (come la radio dell'auto).

Gestire i comandi delle fonti multimediali esterne

Le fonti di contenuti multimediali esterne sono definite app per Android che supportano MediaSessionCompat e MediaBrowseCompat API (fai riferimento a Creare app multimediali per auto per una spiegazione dettagliata sull'uso di queste API).

Importante: perché un'app dell'assistente possa connettersi al MediaBrowseService di tutte le app multimediali installate nel deve:

  1. Essere installata come firmata dal sistema (consulta le linee guida per lo sviluppo di applicazioni multimediali per AAOS e il codice PackageValidator di esempio).
  2. Mantieni android.permission.MEDIA_CONTENT_CONTROL con privilegi di sistema l'autorizzazione (vedi Concedi autorizzazioni con privilegi di sistema).

Oltre a MediaBrowserCompat e MediaControllerCompat, AAOS fornisce quanto segue:

  • CarMediaService fornisce informazioni centralizzate sulla fonte di contenuti multimediali attualmente selezionata. Questo è utilizzata anche per riprendere la riproduzione di una fonte multimediale in precedenza dopo il riavvio o lo spegnimento dell'auto.
  • car-media-common offre metodi pratici per elencare, comunicare e interagire con le app multimediali.

Di seguito sono riportate le linee guida specifiche per l'implementazione dell'interazione vocale comune tramite comandi SQL.

Recupera un elenco di fonti di contenuti multimediali installate

Le fonti multimediali possono essere rilevate utilizzando PackageManager, e il filtro per i servizi corrispondenti a MediaBrowserService.SERVICE_INTERFACE. In alcune auto potrebbero esserci implementazioni speciali dei servizi di browser multimediali, che devono essere escluse. Ecco un esempio di questa logica:

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

Tieni presente che le origini multimediali potrebbero essere installate o disinstallate in qualsiasi momento. Nella per mantenere un elenco accurato, è consigliabile implementare una BroadcastReceiver per le azioni di intent ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REPLACED, e ACTION_PACKAGE_REMOVED.

Connetti a fonte multimediale attualmente in riproduzione

CarMediaService fornisce metodi per ottenere l'origine multimediale attualmente selezionata e quando questo contenuto multimediale modifiche all'origine. Queste modifiche possono verificarsi perché l'utente ha interagito con Interfaccia utente diretta o tramite l'uso di pulsanti hardware nell'auto. D'altra parte, la libreria car-media-common offre modi comodi per connettersi a un determinato contenuto multimediale sorgente. Ecco uno snippet semplificato su come connettersi all'account attualmente selezionato app multimediale:

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
    }

    …
}

Controlla la riproduzione della fonte multimediale in riproduzione

Con un dispositivo MediaBrowserCompat connesso è facile inviare trasporti di controllo all'app di destinazione. Ecco una panoramica esempio:

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

    …
}

Gestire i comandi delle fonti multimediali locali (radio, lettore CD, Bluetooth, USB)

Le fonti multimediali locali espongono la loro funzionalità al sistema utilizzando lo stesso API MediaSession e MediaSfoglia descritte sopra. Per soddisfare le peculiarità per ciascun tipo di hardware, i servizi MediaSfoglia utilizzano convenzioni specifiche per organizzare le informazioni e i comandi multimediali.

Gestisci la radio

Radio MediaSfogliaService può essere identificato dal ACTION_PLAY_BROADCASTRADIO filtro per intent. Gli utenti devono rispettare i controlli di riproduzione e la navigazione tra i contenuti multimediali. descritta in Implementare radio. AAOS offre car-broadcastradio-support libreria contenente costanti e metodi per aiutare gli OEM a creare Media BrowseService implementazioni per i propri servizi radio che seguono il protocollo definito, e offre supporto per le app che utilizzano la struttura di navigazione (ad esempio, VIA).

Gestisci ingresso ausiliario, CD audio e supporti USB

Non esiste un'implementazione predefinita di queste fonti multimediali come parte di AOSP. L'approccio consigliato è:

Gestisci Bluetooth

I contenuti multimediali Bluetooth sono esposti tramite il profilo Bluetooth AVRCP. Nella per facilitare l'accesso a questa funzionalità, AAOS include una MediaBrowserService e MediaSession che astrae dettagli delle comunicazioni (vedi pacchetti/app/Bluetooth).

La rispettiva struttura ad albero del browser multimediale è definita all'indirizzo BrowseTree . I comandi di controllo della riproduzione possono essere inviati allo stesso modo di qualsiasi altra app, mediante l'implementazione di MediaSession.

Gestire i comandi di streaming multimediale

Per implementare lo streaming multimediale lato server, VIA deve diventare sé stesso una fonte multimediale, implementando l'API MediaSfoglia e l'API MediaSession. Consulta Crea app multimediali per le auto. Implementando queste API, un'app con controllo vocale sarebbe in grado (tra le altre cose):

  • Partecipare senza problemi alla selezione delle fonti multimediali
  • Ripresa automaticamente dopo il riavvio dell'auto
  • Fornire i controlli di riproduzione e navigazione tramite l'interfaccia utente di Media Center
  • Ricevi eventi relativi ai pulsanti hardware standard

Non esiste un modo standardizzato di interagire con tutte le app di navigazione. Per le integrazioni con Google Maps, consulta la sezione Google Maps per Android Automotive Intents. Per integrazioni con altri contatta direttamente gli sviluppatori. Prima del lancio a qualsiasi app (incluso Google Maps), verificare che l'intent possa essere risolte (vedi Intent richieste). Ciò crea l'opportunità di informare l'utente in caso l'app di destinazione non è disponibile.

Esegui i comandi del veicolo

L'accesso alle proprietà del veicolo sia per la lettura che per la scrittura viene fornito tramite CarPropertyManager. Vengono illustrati i tipi di proprietà dei veicoli, la relativa implementazione e altri dettagli in Proprietà configurazioni. Per una descrizione accurata delle strutture supportate da Android, è preferibile fare riferimento direttamente a hardware/interfaces/automotive/vehicle/2.0/types.hal. La proprietà Veicoli l'enum definito contiene proprietà sia standard che specifiche del fornitore, tipo, modifica della modalità, unità e definizione dell'accesso in lettura/scrittura.

Per accedere a queste stesse costanti da Java, puoi utilizzare VehiclePropertyIds e le relative classi companion. Proprietà diverse hanno autorizzazioni Android diverse che controllano l'accesso. Queste autorizzazioni vengono dichiarate in CarService del file manifest, nonché la mappatura tra proprietà e autorizzazioni descritte nel valore di VeicoliPropertyIds Javadoc e applicato in PropertyHalServiceIds.

Leggere la proprietà di un veicolo

Di seguito è riportato un esempio che mostra come leggere la velocità del veicolo:

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

    ...
}

Impostare una proprietà del veicolo

Di seguito è riportato un esempio che mostra come accendere e spegnere l'aria condizionata anteriore.

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

    …
}

Completa i comandi di comunicazione

Gestire i comandi di messaggistica

Le VIA devono gestire i messaggi in arrivo che seguono l'impostazione "tocca per leggere" flusso descritto in Assistente vocale Tocca per leggere, che può gestire facoltativamente l'invio di risposte al mittente del messaggio in arrivo. Inoltre, le VIA possono utilizzare SmsManager (parte di android.telephony per comporre e inviare SMS direttamente dall'auto o tramite Bluetooth.

Gestire i comandi di chiamata

In modo simile, i VIP possono utilizzare TelephonyManager per effettuare telefonate e chiamare il numero di segreteria telefonica dell'utente. In questi casi, I via cavo interagiranno con lo stack di telefonia direttamente o con Car Dialer dell'app. In ogni caso, dovrebbe essere visualizzata l'app Car Dialer UI correlata alle chiamate vocali all'utente.

Esegui altri comandi

Per un elenco di altri possibili punti di integrazione tra VIA e consulta l'elenco di intent Android noti. Molti i comandi utente possono essere risolti lato server (ad esempio, le email e gli eventi di calendario degli utenti) e non richiedono alcuna interazione con il sistema. a parte l'interazione vocale.

Azioni immersive (mostra contenuti visivi)

Se migliora le azioni o la comprensione degli utenti, una VIA può fornire contenuti visivi supplementari sullo schermo dell'auto. Per ridurre al minimo le distrazioni per chi guida, mantieni questi contenuti semplici, brevi e fruibili. Per maggiori dettagli sulle linee guida relative all'UI/UX sulle azioni immersive, Assistenti precaricati: indicazioni UX.

Per consentire la personalizzazione e la coerenza con nel resto del design dell'unità principale (HU), le VIA dovrebbero utilizzare Automobile libreria UI per la maggior parte degli elementi UI. Per maggiori dettagli, vedi Personalizzazione.