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ı grupta toplanabilir:
- Harici medya kaynakları (ör. AAOS'ye yüklenen Spotify)
- Arka uç medya kaynakları (ör. VIA üzerinden yayınlanan müzikler)
- Yerel medya kaynakları (ör. araba radyosu)
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ı geliştirme başlıklı makaleyi inceleyin).
Önemli: Bir asistan uygulamasının sistemdeki tüm yüklü medya uygulamalarının MediaBrowseService ile bağlantı kurabilmesi için:
- Sistem tarafından imzalanmış olarak yüklenmelidir (AAOS için Medya Uygulaması Geliştirme kurallarına ve örnek
PackageValidatorkoduna bakın). android.permission.MEDIA_CONTENT_CONTROLsistem ayrıcalıklı iznine sahip olmanız gerekir (bkz. Sistem ayrıcalıklı izinler verme).
MediaBrowserCompat ve MediaControllerCompat'a ek olarak AAOS aşağıdakileri sağlar:
CarMediaServiceŞu anda seçili olan medya kaynağıyla ilgili merkezi bilgiler sağlar. Bu, araba kapatılıp 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şim kurma için kullanışlı yöntemler sunar.
Aşağıda, yaygın sesli etkileşim komutlarının uygulanmasına özel yönergeler verilmiştir.
Yüklü medya kaynaklarının listesini alma
Medya kaynakları PackageManager kullanılarak algılanabilir ve MediaBrowserService.SERVICE_INTERFACE ile eşleşen hizmetler için filtreleme yapılabilir.
Bazı arabalarda, hariç tutulması gereken özel medya tarayıcı hizmeti uygulamaları olabilir. Bu mantığa dair bir örnek:
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 BroadcastReceiver, ACTION_PACKAGE_ADDED, ACTION_PACKAGE_CHANGED, ACTION_PACKAGE_REPLACED ve ACTION_PACKAGE_REMOVED amaçlı işlemler için bir örnek uygulamanız önerilir.
Şu anda oynatılan medya kaynağına bağlanma
CarMediaService
Şu anda seçili olan medya kaynağını ve bu medya kaynağı değiştiğinde kullanılacak yöntemleri sağlar. Bu değişiklikler, kullanıcının doğrudan kullanıcı arayüzüyle etkileşime girmesi veya arabadaki donanım düğmelerinin kullanılması nedeniyle gerçekleşebilir. Öte yandan, car-media-common kitaplığı, belirli bir medya kaynağına bağlanmak için kullanışlı yöntemler sunar. Şu anda seçili medya uygulamasına nasıl bağlanılacağıyla ilgili 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ım kontrolü komutları göndermek kolaydır. Basitleştirilmiş bir örnek aşağıda 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 ayrıntılı olarak açıklanan MediaSession ve MediaBrowse API'lerini kullanarak işlevlerini sisteme sunar. 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.
Telsizi kullanma
Radyo MediaBrowseService, ACTION_PLAY_BROADCASTRADIO
intent filtresiyle tanımlanabilir. Radyo uygulama bölümünde açıklanan oynatma kontrollerine ve medya göz atma yapısına uymaları beklenir. AAOS, OEM'lerin tanımlanmış protokole uyan kendi radyo hizmetleri için MediaBrowseService uygulamaları oluşturmasına yardımcı olacak sabitleri ve yöntemleri içeren car-broadcastradio-support kitaplığını sunar ve göz atma ağaçlarını kullanan uygulamalar (ör. VIA'lar) için destek sağlar.
Yardımcı girişi, CD sesi ve USB ortamını işleme
Bu medya kaynaklarının AOSP kapsamında varsayılan bir uygulaması yoktur. Önerilen yaklaşım:
- OEM'lerin her biri için medya hizmetleri uygulamalarını sağlayın. Ayrıntılar için Arabalar için medya uygulamaları geliştirme başlıklı makaleyi inceleyin.
- Bu MediaBrowseService uygulamaları, Genel oynatma amaçları bölümünde tanımlanan amaç işlemlerinde tanımlanır ve bunlara yanıt verilir.
- Bu hizmetler, Diğer kaynak türleri bölümünde açıklanan yönergeleri izleyen bir göz atma ağacı sunar.
Bluetooth'u kullanma
Bluetooth medya içeriği, AVRCP Bluetooth profili aracılığıyla gösterilir. AAOS, bu işlevselliğe erişimi kolaylaştırmak için iletişim ayrıntılarını soyutlayan bir MediaBrowserService ve MediaSession uygulaması içerir (bkz. packages/apps/Bluetooth).
İlgili medya tarayıcı ağacı yapısı BrowseTree sınıfında tanımlanır. Oynatma kontrolü komutları, MediaSession uygulaması kullanılarak diğer uygulamalara benzer şekilde iletilebilir.
Akış medya komutlarını işleme
VIA'nın sunucu tarafında medya akışını uygulamak için MediaBrowse ve MediaSession API'lerini uygulayarak kendisi bir medya kaynağı haline gelmesi gerekir. Arabalar için medya uygulamaları geliştirme başlıklı makaleyi inceleyin. Bu API'leri uygulayan bir sesli kontrol uygulaması (diğer işlevlerin yanı sıra):
- Medya kaynağı seçimine sorunsuz bir şekilde katılma
- Araba yeniden başlatıldıktan sonra otomatik olarak devam ettirilir.
- Medya Merkezi kullanıcı arayüzünü kullanarak oynatma ve göz atma kontrolü sağlama
- Standart donanım medya düğmesi etkinliklerini alma
Navigasyon komutlarını yerine getirme
Tüm rota izleme uygulamalarıyla etkileşim kurmanın standart bir yolu yoktur. Google Haritalar ile entegrasyonlar için Android Automotive'de Google Haritalar Amaçları başlıklı makaleyi inceleyin. Diğer uygulamalarla entegrasyon için doğrudan uygulama geliştiricilerle iletişime geçin. Herhangi bir uygulamaya (Google Haritalar dahil) niyet başlatmadan önce niyetin çözümlenebildiğini doğrulayın (Google Haritalar Niyetleri bölümüne bakın). Bu sayede, hedef uygulama kullanılamıyorsa kullanıcıyı bilgilendirme fırsatı elde edebilirsiniz.
Araç komutlarını yerine getirme
Hem okuma hem de yazma için araç özelliklerine erişim CarPropertyManager üzerinden sağlanır.
Araç mülkü türleri, bunların uygulanması ve diğer ayrıntılar Mülk yapılandırmaları bölümünde açıklanmaktadır. Android tarafından desteklenen özelliklerin doğru bir açıklaması için doğrudan hardware/interfaces/automotive/vehicle/2.0/types.hal adresine başvurmanız önerilir.
Burada tanımlanan VehicleProperty enum'u hem standart hem de tedarikçiye özel özellikleri, veri türlerini, değişiklik modunu, birimleri ve okuma/yazma erişimi tanımını içerir.
Bu sabitlere Java'dan erişmek için VehiclePropertyIds ve yardımcı sınıflarını kullanabilirsiniz. Farklı mülklerin erişimlerini kontrol eden farklı Android izinleri vardır. Bu izinler CarService manifestinde beyan edilir ve özellikler ile izinler arasındaki eşleme, VehiclePropertyIds Javadoc'ta açıklanır ve PropertyHalServiceIds'de zorunlu kılını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ğını gösteren bir örnek verilmiştir.
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: Dokunarak Okuma bölümünde açıklanan "dokunarak okuma" akışına göre işlemelidir. Bu akış, gelen mesajın gönderenine yanıt göndermeyi isteğe bağlı olarak işleyebilir.
Ayrıca, VIA'lar SmsManager
(android.telephony
paketinin bir parçası) kullanarak doğrudan arabadan veya Bluetooth üzerinden SMS mesajları oluşturup gönderebilir.
Arama komutlarını kullanma
Benzer şekilde, VIA'lar TelephonyManager
kullanarak telefon araması yapabilir ve kullanıcının sesli mesaj numarasına çağrı gönderebilir. Bu durumlarda, VIAs doğrudan telefon yığınıyla veya Araç Çevirici uygulamasıyla etkileşime girer. Her durumda, sesli arama ile ilgili kullanıcı arayüzünü kullanıcıya gösteren uygulama Araç Çevirici uygulaması olmalıdır.
Diğer komutları yerine getirme
VIA ile sistem arasındaki diğer olası entegrasyon noktalarının listesi için iyi bilinen Android amaçlarının listesine göz atın. Birçok kullanıcı komutu sunucu tarafında çözülebilir (örneğin, kullanıcıların e-postalarını ve takvim etkinliklerini okuma) ve sesli etkileşim dışında sistemle herhangi bir etkileşim gerektirmez.
Etkileyici işlemler (görsel içerik gösterme)
VIA, kullanıcı işlemlerini veya anlayışını geliştirdiği durumlarda araba ekranında ek görsel içerik sağlayabilir. Sürücünün dikkatini dağıtmayı en aza indirmek için bu tür içerikleri basit, kısa ve uygulanabilir tutun. Immersive Actions'daki 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.
Özelleştirme ve ana birimin (HU) geri kalan tasarımıyla tutarlılık sağlamak için VIA'lar, 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ünü inceleyin.