Bu sayfada, sesli etkileşimle komutların nasıl yerine getirileceği açıklanmaktadır.
Medya komutlarını yerine getirme
Medya ile ilgili komutlar üç farklı gruba ayrılabilir:
- Harici medya kaynakları (AAOS'te yüklü Spotify gibi).
- Arka uç medya kaynakları (ör. VIA üzerinden yayınlanan müzik).
- Yerel medya kaynakları (araba radyosu gibi).
Harici medya kaynağı komutlarını işleme
Harici medya kaynakları, MediaSessionCompat
ve MediaBrowseCompat
API'lerini destekleyen Android uygulamaları olarak tanımlanır (bu API'lerin kullanımıyla ilgili ayrıntılı açıklama için Arabalar için medya uygulamaları oluşturma başlıklı makaleyi inceleyin).
Önemli: Bir asistan uygulamasının sistemdeki tüm yüklü medya uygulamalarının MediaBrowseService
'sine bağlanması için:
- Sistem imzalı olarak yüklenmelidir (AAOS için medya uygulaması geliştirme kurallarına ve örnek
PackageValidator
koduna bakın). android.permission.MEDIA_CONTENT_CONTROL
sistem ayrıcalıklı iznine sahip olmalıdır (Sistem ayrıcalıklı izin verme bölümüne bakın).
MediaBrowserCompat
ve MediaControllerCompat
'e ek olarak AOAS aşağıdakileri sağlar:
CarMediaService
mevcut medya kaynağıyla ilgili merkezi bilgiler sağlar. Bu, araç kapatıldıktan ve yeniden başlatıldıktan sonra daha önce oynatılan bir medya kaynağını devam ettirmek için de kullanılır.car-media-common
, medya uygulamalarını listeleme, bağlama ve bunlarla etkileşime geçmeye yönelik kullanışlı yöntemler sunar.
Aşağıda, yaygın sesli etkileşim komutlarının uygulanmasına özel kurallar verilmiştir.
Yüklü medya kaynaklarının listesini alma
Medya kaynakları, PackageManager
kullanılarak ve MediaBrowserService.SERVICE_INTERFACE
ile eşleşen hizmetler için filtreleme yapılarak algılanabilir.
Bazı araçlarda, hariç tutulması gereken özel medya tarayıcısı hizmeti uygulamaları olabilir. Bu mantıkla ilgili bir örnek aşağıda verilmiştir:
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; }
Medya kaynaklarının dilediğiniz zaman yüklenebileceğini veya kaldırılabileceğini unutmayın. Doğru bir liste tutmak için ACTION_PACKAGE_ADDED
,
ACTION_PACKAGE_CHANGED
,
ACTION_PACKAGE_REPLACED
ve ACTION_PACKAGE_REMOVED
intent işlemleri için bir BroadcastReceiver
örneği uygulamanız önerilir.
Şu anda çalan medya kaynağına bağlanma
CarMediaService
, şu anda seçili olan medya kaynağını ve bu medya kaynağının ne zaman değiştiğini alma yöntemleri sağlar. Bu değişiklikler, kullanıcının doğrudan kullanıcı arayüzüyle etkileşime geçmesi veya araçtaki donanım düğmelerinin kullanılması nedeniyle gerçekleşebilir. Öte yandan, car-media-common kitaplığı belirli bir medya kaynağına bağlanmanın kullanışlı yollarını sunar. Şu anda seçili olan medya uygulamasına nasıl bağlanacağınıza dair basitleştirilmiş bir snippet'i aşağıda bulabilirsiniz:
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 } … }
Şu anda oynatılan medya kaynağının oynatılmasını kontrol etme
Bağlı bir MediaBrowserCompat
ile hedef uygulamaya aktarıcı denetim komutları göndermek kolaydır. Aşağıda basitleştirilmiş bir örnek verilmiştir:
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; } … }
Yerel medya kaynağı komutlarını (radyo, CD çalar, Bluetooth, USB) işleme
Yerel medya kaynakları, yukarıda açıklanan MediaSession ve MediaBrowse API'lerini kullanarak işlevlerini sisteme gösterir. Bu MediaBrowse hizmetleri, her donanım türünün özelliklerine uyum sağlamak için bilgilerini ve medya komutlarını düzenlemek üzere belirli kurallar kullanır.
Radyoyla ilgili işlemler
Radyo MediaBrowseService, ACTION_PLAY_BROADCASTRADIO
intent filtresiyle tanımlanabilir. Radyo uygulama bölümünde açıklanan oynatma kontrollerini ve medya tarama yapısını uygulamaları beklenir. AAOS, OEM'lerin kendi radyo hizmetleri için tanımlanmış protokole uyan MediaBrowseService uygulamaları oluşturmasına yardımcı olacak sabitler ve yöntemler içeren car-broadcastradio-support
kitaplığını sunar ve tarama ağaçlarını kullanan uygulamalara (ör. VIA'lar) destek sağlar.
Yardımcı giriş, CD sesi ve USB medyasını işleme
AOSP kapsamında bu medya kaynaklarının varsayılan bir uygulaması yoktur. Önerilen yaklaşım şudur:
- OEM'lerin her biri için medya hizmetlerini uygulamasını sağlayın. Ayrıntılar için Arabalar için medya uygulamaları oluşturma başlıklı makaleyi inceleyin.
- Bu MediaBrowseService uygulamaları, Genel oynatma intent'lerinde tanımlanan intent işlemlerinde tanımlanır ve bunlara yanıt verilir.
- Bu hizmetler, Diğer kaynak türleri bölümünde açıklanan yönergelere uygun bir göz atma ağacı gösterir.
Bluetooth'u kullanma
Bluetooth medya içeriği, AVRCP Bluetooth profili aracılığıyla gösterilir. Bu işleve erişimi kolaylaştırmak için AAOS, iletişim ayrıntılarını soyutlayan bir MediaBrowserService ve MediaSession uygulaması içerir (packages/apps/Bluetooth bölümüne bakın).
İlgili medya tarayıcısı ağaç yapısı, BrowseTree sınıfında tanımlanır. Oynatma kontrol komutları, MediaSession uygulaması kullanılarak diğer uygulamalara benzer şekilde gönderilebilir.
Medya aktarma komutlarını işleme
Sunucu tarafı medya aktarımını uygulamak için VIA'nın, MediaBrowse ve MediaSession API'yi uygulayarak bir medya kaynağı haline gelmesi gerekir. Arabalar için medya uygulamaları oluşturma başlıklı makaleyi inceleyin. Bu API'leri uygulayan bir sesli kontrol uygulaması, diğerlerinin yanı sıra şunları yapabilir:
- Medya kaynağı seçimine sorunsuz bir şekilde katılma
- Araç yeniden başlatıldıktan sonra otomatik olarak devam eder.
- Medya Merkezi kullanıcı arayüzünü kullanarak oynatma ve göz atma kontrolü sağlama
- Standart donanım medya düğmesi etkinliklerini alma
Gezinme komutlarını yerine getirme
Tüm navigasyon uygulamalarıyla etkileşime geçmenin standart bir yolu yoktur. Google Haritalar ile entegrasyonlar için Android Automotive Intents için Google Haritalar başlıklı makaleyi inceleyin. Diğer uygulamalarla entegrasyon için doğrudan uygulama geliştiricileriyle iletişime geçin. Herhangi bir uygulamada (Google Haritalar dahil) intent başlatmadan önce intent'in çözülebileceğini doğrulayın (Intent isteklerine bakın). Bu sayede, hedef uygulama kullanılamıyorsa kullanıcıyı bilgilendirme fırsatı elde edilir.
Araç komutlarını yerine getirme
Araç özelliklerine hem okuma hem de yazma için erişim CarPropertyManager aracılığıyla sağlanır.
Araç mülkleri türleri, bunların uygulanması ve diğer ayrıntılar Mülk yapılandırmaları bölümünde açıklanmıştır. Android tarafından desteklenen özelliklerin doğru açıklaması için doğrudan hardware/interfaces/automotive/vehicle/2.0/types.hal
sayfasına bakmanız önerilir.
Burada tanımlanan VehicleProperty enum'u hem standart hem de tedarikçiye özgü mülkleri, veri türlerini, değişiklik modunu, birimleri ve okuma/yazma erişim tanımını içerir.
Java'dan aynı sabitlere erişmek için VehiclePropertyIds ve tamamlayıcı sınıflarını kullanabilirsiniz. Farklı mülklerin erişimini kontrol eden farklı Android izinleri vardır. Bu izinler CarService manifest dosyasında tanımlanır. Mülkler ile izinler arasındaki eşleme, VehiclePropertyIds Javadoc'ında açıklanır ve PropertyHalServiceIds'de uygulanır.
Araç özelliğini okuma
Aşağıda, araç hızının nasıl okunacağını gösteren bir örnek verilmiştir:
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); } ... }
Araç özelliği ayarlama
Aşağıda, ön klimanın nasıl açılıp kapatılacağı gösterilmektedir.
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")); } … }
İletişim komutlarını yerine getirme
Mesajlaşma komutlarını işleme
VIA'lar, gelen mesajları Sesli Asistan'da dokunarak okuma bölümünde açıklanan "dokunarak okuma" akışını izleyerek işlemelidir. Bu akış, isteğe bağlı olarak gelen mesajın gönderenine yanıt göndermeyi de işleyebilir.
Ayrıca, VIA'lar doğrudan arabadan veya Bluetooth üzerinden SMS mesajları oluşturmak ve göndermek için SmsManager
(android.telephony
paketinin bir parçası) kullanabilir.
Arama komutlarını işleme
Benzer şekilde, VIA'lar telefon araması yapmak ve kullanıcının sesli mesaj numarasını aramak için TelephonyManager
simgesini kullanabilir. Bu gibi durumlarda, VIA'lar doğrudan telefon yığını veya Car Dialer uygulamasıyla etkileşim kurar. Her durumda, kullanıcıya sesli aramayla ilgili kullanıcı arayüzünü gösteren Car Dialer uygulaması olmalıdır.
Diğer komutları yerine getirme
VIA ile sistem arasında olası diğer entegrasyon noktalarının listesi için bilinen Android intent'lerinin listesini inceleyin. Birçok kullanıcı komutu sunucu tarafında çözülebilir (ör. kullanıcıların e-postalarını ve takvim etkinliklerini okuma) ve sesli etkileşim dışında sistemle herhangi bir etkileşim gerektirmez.
Immersive actions (display visual content)
Kullanıcı işlemlerini veya anlayışını geliştirdiği durumlarda VIA, araç ekranında ek görsel içerik sağlayabilir. Sürücünün dikkatini dağıtmamak için bu tür içerikleri basit, kısa ve uygulanabilir tutun. Tam sayfa işlemlerle ilgili kullanıcı arayüzü/kullanıcı deneyimi yönergeleri hakkında ayrıntılı bilgi için Önceden yüklenmiş asistanlar: Kullanıcı deneyimi rehberliği başlıklı makaleyi inceleyin.
VIA'lar, ana birimin (HU) tasarımının geri kalanıyla tutarlılığı ve özelleştirmeyi sağlamak için kullanıcı arayüzü öğelerinin çoğunda Car UI Library bileşenlerini kullanmalıdır. Ayrıntılar için Özelleştirme bölümüne bakın.