Halaman ini menjelaskan cara menjalankan perintah dengan interaksi suara.
Memenuhi perintah media
Perintah terkait media dapat dibagi menjadi tiga grup yang berbeda:
- Sumber media eksternal (seperti Spotify yang diinstal di AAOS).
- Sumber media backend (seperti musik yang di-streaming melalui VIA).
- Sumber media lokal (seperti radio mobil).
Menangani perintah sumber media eksternal
Sumber media eksternal didefinisikan sebagai aplikasi Android yang mendukung MediaSessionCompat
dan MediaBrowseCompat
API (lihat Membangun aplikasi media untuk
mobil untuk mendapatkan penjelasan mendetail tentang penggunaan API ini).
Penting: Agar aplikasi asisten dapat terhubung ke
MediaBrowseService
dari semua aplikasi media terinstal di
sistem, maka sistem harus:
- Diinstal sebagai ditandatangani sistem (lihat panduan Pengembangan Aplikasi Media untuk
AAOS dan kode contoh
PackageValidator
). - Pertahankan
android.permission.MEDIA_CONTENT_CONTROL
hak istimewa sistem izin (lihat Memberikan izin dengan hak istimewa sistem).
Selain MediaBrowserCompat
dan MediaControllerCompat
,
AAOS menyediakan hal berikut:
CarMediaService
memberikan informasi terpusat tentang sumber media yang dipilih saat ini. Ini adalah juga digunakan untuk melanjutkan sumber media yang sebelumnya diputar setelah menyalakan ulang mobil dimatikan.car-media-common
menyediakan metode yang mudah untuk membuat daftar, menghubungkan, dan berinteraksi dengan aplikasi media.
Di bawah ini adalah panduan khusus untuk penerapan interaksi suara umum perintah.
Mendapatkan daftar sumber media yang terinstal
Sumber media dapat dideteksi menggunakan PackageManager
,
dan memfilter layanan yang cocok dengan MediaBrowserService.SERVICE_INTERFACE
.
Di beberapa mobil mungkin ada beberapa
implementasi layanan {i>browser<i} media khusus,
yang harus dikecualikan. Berikut adalah contoh logika ini:
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; }
Perhatikan bahwa sumber media dapat diinstal atau di-uninstal kapan saja. Di beberapa
Untuk mempertahankan daftar yang akurat, sebaiknya terapkan BroadcastReceiver
untuk tindakan intent ACTION_PACKAGE_ADDED
,
ACTION_PACKAGE_CHANGED
,
ACTION_PACKAGE_REPLACED
,
dan ACTION_PACKAGE_REMOVED
.
Hubungkan ke sumber media yang sedang diputar
CarMediaService
menyediakan metode untuk mendapatkan sumber media yang dipilih saat ini, dan kapan
perubahan sumber. Perubahan ini dapat terjadi karena pengguna berinteraksi dengan
UI secara langsung, atau karena penggunaan tombol fisik di mobil. Di sisi lain,
{i>car-media-common library<i} menawarkan cara
mudah untuk terhubung ke media
sumber. Berikut adalah cuplikan sederhana tentang cara terhubung ke API yang saat ini dipilih
aplikasi media:
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 } … }
Mengontrol pemutaran sumber media yang sedang diputar
Dengan MediaBrowserCompat
yang terhubung
mudah untuk mengirim transportasi
perintah kontrol ke aplikasi target. Berikut adalah
contoh:
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; } … }
Menangani perintah sumber media lokal (radio, pemutar CD, Bluetooth, USB)
Sumber media lokal mengekspos fungsinya ke sistem menggunakan MediaSession dan MediaBrowse API yang dijelaskan di atas. Untuk mengakomodasi kekhususan setiap jenis perangkat keras, layanan MediaBrowse ini menggunakan konvensi khusus untuk mengatur informasi dan perintah media mereka.
Tangani radio
Radio MediaBrowseService dapat diidentifikasi oleh ACTION_PLAY_BROADCASTRADIO
filter intent. Penonton diharapkan mengikuti kontrol pemutaran dan penjelajahan media
yang dijelaskan dalam Mengimplementasikan radio. AAOS menawarkan
car-broadcastradio-support
library yang berisi konstanta dan metode untuk membantu OEM membuat MediaBrowseService
implementasi untuk layanan radio mereka sendiri
yang mengikuti protokol yang ditentukan,
dan memberikan dukungan untuk aplikasi yang menggunakan hierarki penjelajahannya (misalnya, VIA).
Menangani input tambahan, audio CD, dan media USB
Tidak ada implementasi default sumber media ini sebagai bagian dari AOSP. Pendekatan yang disarankan adalah:
- Minta OEM menerapkan layanan media untuk setiap produk. Untuk mengetahui detailnya, lihat Membangun aplikasi media untuk mobil.
- Penerapan MediaBrowseService ini akan diidentifikasi dan ditanggapi dalam intent tindakan yang ditentukan di Intent putar umum.
- Layanan ini akan menampilkan hierarki penjelajahan yang mengikuti panduan yang dijelaskan di Jenis sumber lainnya.
Menangani Bluetooth
Konten media Bluetooth terekspos melalui profil Bluetooth AVRCP. Di beberapa Untuk memfasilitasi akses ke fungsi ini, AAOS menyertakan Implementasi MediaBrowserService dan MediaSession yang memisahkan detail komunikasi (lihat paket/aplikasi/Bluetooth).
Masing-masing struktur hierarki browser media ditentukan di BrowseTree . Perintah kontrol pemutaran dapat dikirimkan seperti aplikasi lainnya, menggunakan implementasi MediaSession.
Menangani perintah media streaming
Untuk menerapkan streaming media sisi server, VIA harus menjadi dirinya sendiri sumber media, yang menerapkan MediaBrowse dan MediaSession API. Rujuk ke Membangun aplikasi media untuk mobil. Dengan menerapkan API ini, aplikasi kontrol suara akan dapat (antara lain):
- Berpartisipasi dengan lancar dalam pemilihan sumber media
- Otomatis dilanjutkan setelah mobil dimulai ulang
- Menyediakan kontrol pemutaran dan penjelajahan menggunakan UI Pusat Media
- Menerima peristiwa tombol media hardware standar
Memenuhi perintah navigasi
Tidak ada cara standar untuk berinteraksi dengan semua aplikasi navigasi. Untuk integrasi dengan Google Maps, lihat Google Maps untuk Intent Android Automotive. Untuk integrasi dengan aplikasi, hubungi langsung pengembang aplikasi. Sebelum diluncurkan intent ke aplikasi apa pun (termasuk Google Maps), memverifikasi bahwa intent tersebut dapat diselesaikan (lihat Intent permintaan). Hal ini menciptakan peluang untuk memberi tahu pengguna jika aplikasi target tidak tersedia.
Memenuhi perintah kendaraan
Akses ke properti kendaraan untuk baca dan tulis disediakan melalui
CarPropertyManager.
Jenis properti kendaraan, penerapannya, dan detail lainnya telah dijelaskan
di Properti
konfigurasi. Untuk deskripsi yang akurat tentang properti yang didukung
oleh Android, sebaiknya lihat langsung hardware/interfaces/automotive/vehicle/2.0/types.hal
.
Properti Kendaraan
yang didefinisikan di sana berisi
properti khusus standar dan vendor, data
jenis, ubah mode, unit, dan definisi akses baca/tulis.
Untuk mengakses konstanta yang sama ini dari Java, Anda dapat menggunakan KendaraanPropertyIds dan class pendampingnya. Properti yang berbeda memiliki izin Android yang berbeda yang mengontrol akses. Izin ini dideklarasikan di CarService manifes, dan pemetaan antara properti dan izin yang dijelaskan di bagian KendaraanPropertyIds Javadoc dan diterapkan di PropertyHalServiceIds.
Membaca properti kendaraan
Berikut adalah contoh yang menunjukkan cara membaca kecepatan kendaraan:
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); } ... }
Tetapkan properti kendaraan
Berikut adalah contoh yang menunjukkan cara menyalakan dan mematikan AC depan.
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")); } … }
Memenuhi perintah komunikasi
Menangani perintah pesan
VIA harus menangani pesan masuk yang mengikuti gerakan "ketuk untuk membaca" alur dijelaskan
di Asisten suara
Ketuk untuk Baca, yang secara opsional dapat menangani pengiriman balasan ke pengirim pesan masuk.
Selain itu, VIA dapat menggunakan SmsManager
(bagian dari android.telephony
) untuk menulis dan mengirim pesan SMS langsung dari mobil atau melalui Bluetooth.
Menangani perintah panggilan
Dengan cara yang sama, VIA dapat menggunakan TelephonyManager
untuk melakukan panggilan telepon dan menghubungi nomor pesan suara pengguna. Dalam kasus ini,
VIA akan berinteraksi dengan stack telepon secara langsung atau dengan Telepon Mobil
. Bagaimanapun, aplikasi Telepon Mobil harus yang menampilkan
UI terkait panggilan suara kepada pengguna.
Memenuhi perintah lainnya
Untuk daftar kemungkinan titik integrasi antara VIA dan periksa daftar intent Android yang dikenal. Banyak perintah pengguna dapat diselesaikan di sisi server (misalnya, email dan acara kalender pengguna) serta tidak memerlukan interaksi apa pun dengan sistem selain interaksi suara itu sendiri.
Tindakan imersif (konten visual tampilan)
Ketika meningkatkan tindakan atau pemahaman pengguna, VIA dapat memberikan konten visual tambahan di layar mobil. Untuk meminimalkan gangguan bagi pengemudi, menjaga konten tetap sederhana, singkat, dan dapat ditindaklanjuti. Untuk mengetahui detail tentang panduan UI/UX tentang tindakan imersif, lihat Asisten Pramuat: Panduan UX.
Untuk memungkinkan penyesuaian dan konsistensi dengan desain head unit (HU) lainnya, VIA harus menggunakan Mobil komponen Library UI untuk sebagian besar elemen UI. Untuk mengetahui detailnya, lihat Penyesuaian.