Android Automotive, sesli etkileşimlerin sürüş güvenliği açısından önemli bir bileşen olduğunu ve kullanıcıların sürüş sırasında Android Automotive OS ile etkileşime geçmesinin en güvenli yollarından biri olduğunu kabul eder. Sonuç olarak, Android sesli asistan API'lerini (VoiceInteractionSession
dahil) genişleterek sesli asistanların, sürüş sırasında yapılması zor olabilecek görevleri kullanıcılar için gerçekleştirmesine olanak tanıdık.
Dokunarak Oku, kullanıcı mesaj bildirimleriyle etkileşime geçtiğinde sesli asistanların kullanıcı adına kısa mesajları okuyup yanıtlamasını sağlar. Bu işlevi sağlamak için CarVoiceInteractionSession
ile bir sesli asistan entegre edebilirsiniz.
Automotive'te, Bildirim Merkezi'ne gönderilen ve INBOX
veya INBOX_IN_GROUP
olarak tanımlanan bildirimler (ör. SMS mesajları) Oynat düğmesi içerir. Kullanıcı, seçili sesli asistanın bildirimi sesli okuması ve isteğe bağlı olarak sesle yanıt vermesi için Oynat'ı tıklayabilir.
Şekil 1. Oynat düğmesi içeren dokunarak okuma bildirimi.
CarVoiceInteractionSession ile entegrasyon
Sonraki bölümlerde, sesli asistanın CarVoiceInteractionSession
ile nasıl entegre edileceği açıklanmaktadır.
Sesli etkileşimleri destekleme
Araç sesli etkileşim hizmetleri sunan uygulamalar, mevcut Android sesli etkileşimleriyle entegre olmalıdır. Daha fazla bilgi için Android için Google Asistan'a (VoiceInteractionSession
hariç) bakın. Tüm ses etkileşimi API öğeleri mobil cihazlarda uygulandığı gibi kalır ancak CarVoiceInteractionSession
(CarVoiceInteractionSession'ı uygulama bölümünde açıklanmıştır) VoiceInteractionSession
'in yerini alır. Daha fazla bilgi için şu sayfalara göz atın:
CarVoiceInteractionSession'ı uygulama
CarVoiceInteractionSession
, sesli asistanların kısa mesajları sesli okumasını ve ardından bu mesajları kullanıcı adına yanıtlamasını sağlamak için kullanabileceğiniz API'leri sağlar.
CarVoiceInteractionSession
ve VoiceInteractionSession
sınıfları arasındaki temel fark, CarVoiceInteractionSession
'ün onShow
içinde işlemi iletmesidir. Böylece sesli asistan, CarVoiceInteractionSession
bir oturum başlatır başlatmaz kullanıcının isteği bağlamını algılayabilir. Her sınıf için onShow
parametreleri aşağıdaki tabloda listelenmiştir:
CarVoiceInteractionSession | VoiceInteractionSession |
---|---|
onShow , aşağıdaki üç parametreyi alır:
|
onShow , şu iki parametreyi alır:
|
Android 10'daki değişiklikler
Android 10'dan itibaren platform, hangi işlemlerin desteklendiğini algılamak için VoiceInteractionService.onGetSupportedVoiceActions
işlevini çağırır. Sesli asistan, aşağıdaki örnekte gösterildiği gibi VoiceInteractionService.onGetSupportedVoiceActions
öğesini geçersiz kılar ve uygular:
public class MyInteractionService extends VoiceInteractionService { private static final ListSUPPORTED_VOICE_ACTIONS = Arrays.asList( CarVoiceInteractionSession.VOICE_ACTION_READ_NOTIFICATION); @Override public Set onGetSupportedVoiceActions(@NonNull Set voiceActions) { Set result = new HashSet<>(voiceActions); result.retainAll(SUPPORTED_VOICE_ACTIONS); return result; } }
Geçerli işlemler aşağıdaki tabloda açıklanmıştır. Her işlemle ilgili ayrıntılar için Sıralı diyagramlar bölümüne bakın.
İşlem | Beklenen yük | Beklenen sesli etkileşim işlemi |
---|---|---|
VOICE_ACTION_READ_NOTIFICATION |
Mesajları kullanıcıya sesli olarak okuyun ve ardından mesajlar başarıyla okunduğunda "Okundu olarak işaretle" isteğinin beklemede olduğunu bildirin. İsteğe bağlı olarak kullanıcıdan yanıt isteyebilirsiniz. | |
VOICE_ACTION_REPLY_NOTIFICATION |
Anahtarla paketlenebilir.KEY_NOTIFICATION
StatusBarNotification ile eşleşir.android.permission.BIND_NOTIFICATION_LISTENER_SERVICE gerektirir. |
Kullanıcıdan yanıt mesajını belirtmesini isteyin, yanıt mesajını bekleyen intent'in RemoteInputReply alanına girin ve ardından bekleyen intent'i tetikleyin. |
VOICE_ACTION_HANDLE_EXCEPTION |
Anahtar içeren dize.KEY_EXCEPTION
ExceptionValue ile eşleşen (İstisna değerleri bölümünde açıklanan)KEY_FALLBACK_ASSISTANT_ENABLED Boole değeriyle eşlenir. Değer true ise kullanıcının isteğini yerine getirebilecek yedek yardımcı devre dışı bırakılmıştır. |
İstisna için yapılması beklenen işlem, istisnayla ilgili dokümanda tanımlanır. |
İstisna değerleri
EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING
sesli asistana Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE
izninin eksik olduğunu ve bu izni kullanıcıdan alması gerektiğini belirtir.
Bildirim dinleyici izni isteme
Varsayılan sesli asistanın bildirim dinleyici izni yoksa platformun FallbackAssistant
(araba üreticisi tarafından etkinleştirildiyse) sesli asistana izin istemesi için bildirim gönderilmeden önce mesajı sesli olarak okuyabilir. Sesli asistan, FallbackAssistant
'ün etkin olup olmadığını ve mesajı okuyup okumadığını belirlemek için yükte KEY_FALLBACK_ASSISTANT_ENABLED
Boole değerini kontrol etmelidir.
Platform, sesli asistanın bu iznin istek sayısı için hız sınırlama mantığı eklemesini önerir. Bu sayede, sesli asistana bu izni vermek istemeyen ve FallbackAssistant
'ün kısa mesajları sesli okumasını tercih eden kullanıcılara saygı gösterilir. Kullanıcı bir mesaj bildirimindeki Oynat'a her basışında izin isteğinde bulunmak olumsuz bir kullanıcı deneyimi olabilir. Platform, sesli asistan adına ücret sınırlamaları uygulamaz.
Sesli asistan, bildirim dinleyici iznini istediğinde kullanıcının park halinde mi yoksa araba kullanırken mi olduğunu belirlemek için CarUxRestrictionsManager
değerini kullanmalıdır. Kullanıcı araç kullanıyorsa sesli asistan, iznin nasıl verileceğine dair talimatlar içeren bir bildirim gösterir. Bu, kullanıcının daha güvenli olduğunda izni vermesine yardımcı olur (ve bunu hatırlatır).
StatusBarNotification ile çalışma
Okuma ve yanıtlama sesli işlemleriyle birlikte iletilen StatusBarNotification
, Kullanıcılara mesaj bildirin bölümünde açıklandığı gibi her zaman araçla uyumlu bir mesajlaşma bildiriminde bulunur. Bazı bildirimlerde Beklemede Yanıtla intent'i bulunmasa da hepsinin Beklemede Okundu Olarak İşaretle intent'i vardır.
Bildirimlerle etkileşimleri kolaylaştırmak için NotificationPayloadHandler
'i kullanın. Bu API, bildirimdeki mesajları ayıklamak ve yanıt mesajlarını bildirimin bekleyen intent'ine yazmak için yöntemler sağlar. Sesli asistan mesajı okuduktan sonra, Okundu Olarak İşaretle intent'ini çalıştırmalıdır.
Dokunarak Okuma ön koşullarını karşılama
Bir kullanıcı mesajları okumak ve yanıtlamak için sesli işlemi tetiklediğinde varsayılan sesli asistanın yalnızca VoiceInteractionSession
'ü bilgilendirilir. Yukarıda belirtildiği gibi, bu varsayılan sesli asistanın bildirim dinleyici izni de olmalıdır.
Adım sırası diyagramları
Bu şekillerde CarVoiceInteractionSession actions
mantık akışları gösterilmektedir:
Şekil 2. VOICE_ACTION_READ_NOTIFICATION için ardışık düzen şeması.
Şekil 3'te, izin isteklerinde hız sınırlarının uygulanması önerilir:
Şekil 3. VOICE_ACTION_REPLY_NOTIFICATION için ardışık düzen şeması.
Şekil 4. VOICE_ACTION_HANDLE_EXCEPTION için ardışık düzen şeması.
Uygulamanın adını okuma
Sesli asistanınızın, mesaj okunurken mesajlaşma uygulamasının adını sesli olarak okumasını istiyorsanız (ör. "Hangouts'taki Sam şöyle dedi:") asistanın doğru adı okuduğundan emin olmak için aşağıdaki kod örneğinde gösterilen gibi bir işlev oluşturun:
@Nullable String getMessageApplicationName(Context context, StatusBarNotification statusBarNotification) { ApplicationInfo info = getApplicationInfo(context, statusBarNotification.getPackageName()); if (info == null) return null; Notification notification = statusBarNotification.getNotification(); // Sometimes system packages will post on behalf of other apps, so check this // field for a system app notification. if (isSystemApp(info) && notification.extras.containsKey(Notification.EXTRA_SUBSTITUTE_APP_NAME)) { return notification.extras.getString(Notification.EXTRA_SUBSTITUTE_APP_NAME); } else { PackageManager pm = context.getPackageManager(); return String.valueOf(pm.getApplicationLabel(info)); } } @Nullable ApplicationInfo getApplicationInfo(Context context, String packageName) { final PackageManager pm = context.getPackageManager(); ApplicationInfo info; try { info = pm.getApplicationInfo(packageName, 0); } catch (PackageManager.NameNotFoundException e) { return null; } return info; } boolean isSystemApp(ApplicationInfo info) { return (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; }