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:
- Essere installata come firmata dal sistema (consulta le linee guida per lo sviluppo di applicazioni multimediali per
AAOS e il codice
PackageValidator
di esempio). - 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 è:
- Fai in modo che gli OEM implementino servizi multimediali per ciascuno di loro. Per maggiori dettagli, vedi Creare app multimediali per le auto.
- Queste implementazioni MediaSfogliaService verrebbero identificate e rispondete nell'intento azioni definite nella sezione Intent di riproduzione generali.
- Questi servizi esporrebbero una struttura di navigazione seguendo le linee guida descritte in Altri tipi di origini.
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
Completa i comandi di navigazione
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.