Android Automotive menganggap suara sebagai komponen penting untuk
interaksi yang aman saat mengemudi dan salah satu cara teraman bagi pengguna untuk
berinteraksi dengan Android Automotive OS saat mengemudi. Oleh karena itu, kami memperluas
API asisten suara Android (termasuk VoiceInteractionSession
)
agar asisten suara dapat melakukan tugas untuk pengguna
yang mungkin sulit dilakukan saat mengemudi.
Ketuk untuk Membaca memungkinkan asisten suara membaca dan membalas pesan teks
atas nama pengguna, saat pengguna berinteraksi dengan notifikasi pesan. Untuk menyediakan
fungsi ini, Anda dapat mengintegrasikan asisten suara dengan
CarVoiceInteractionSession
.
Di Automotive, notifikasi yang diposting ke Pusat Notifikasi yang diidentifikasi
sebagai INBOX
atau INBOX_IN_GROUP
(misalnya, pesan SMS) menyertakan
tombol Putar. Pengguna dapat mengklik Putar agar asisten
suara yang dipilih membacakan notifikasi dengan keras, dan secara opsional membalas dengan suara.
Gambar 1. Notifikasi Ketuk untuk Membaca dengan tombol Play.
Mengintegrasikan dengan CarVoiceInteractionSession
Bagian berikutnya menjelaskan cara mengintegrasikan asisten suara dengan
CarVoiceInteractionSession
.
Mendukung interaksi suara
Aplikasi yang menyediakan layanan interaksi suara mobil harus
terintegrasi dengan interaksi suara Android yang ada. Untuk mempelajari lebih lanjut, lihat Asisten Google untuk Android
(kecuali VoiceInteractionSession
). Meskipun semua elemen API interaksi
suara tetap sama seperti yang diterapkan di perangkat seluler, CarVoiceInteractionSession
(dijelaskan dalam Menerapkan CarVoiceInteractionSession) menggantikan
VoiceInteractionSession
. Untuk informasi selengkapnya, lihat halaman berikut:
Mengimplementasikan CarVoiceInteractionSession
CarVoiceInteractionSession
mengekspos API yang dapat Anda gunakan untuk memungkinkan asisten suara membaca pesan teks dengan lantang, lalu
membalas pesan tersebut atas nama pengguna.
Perbedaan utama antara class CarVoiceInteractionSession
dan
VoiceInteractionSession
adalah
CarVoiceInteractionSession
meneruskan tindakan di onShow
sehingga asisten suara dapat mendeteksi konteks permintaan pengguna segera setelah
CarVoiceInteractionSession
memulai sesi. Parameter untuk onShow
untuk setiap class tercantum dalam tabel berikut:
CarVoiceInteractionSession | VoiceInteractionSession |
---|---|
onShow menggunakan tiga parameter berikut:
|
onShow menggunakan dua parameter berikut:
|
Perubahan di Android 10
Mulai Android 10, platform memanggil VoiceInteractionService.onGetSupportedVoiceActions
untuk mendeteksi tindakan yang didukung. Asisten suara mengganti dan
menerapkan VoiceInteractionService.onGetSupportedVoiceActions
,
seperti yang ditunjukkan pada contoh berikut:
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; } }
Tindakan yang valid dijelaskan dalam tabel berikut. Untuk mengetahui detail tentang setiap tindakan, lihat Diagram urutan.
Tindakan | Payload yang diharapkan | Tindakan interaksi suara yang diharapkan |
---|---|---|
VOICE_ACTION_READ_NOTIFICATION |
Baca pesan dengan lantang kepada pengguna, lalu aktifkan intent Tandai sebagai Telah Dibaca yang tertunda kembali saat pesan berhasil dibaca. Secara opsional, minta pengguna untuk membalas. | |
VOICE_ACTION_REPLY_NOTIFICATION |
Parcelable dengan kunci.KEY_NOTIFICATION
yang dipetakan ke StatusBarNotification .Memerlukan android.permission.BIND_NOTIFICATION_LISTENER_SERVICE . |
Minta pengguna untuk menyatakan pesan balasan, masukkan pesan balasan ke
RemoteInputReply intent yang tertunda, lalu aktifkan
intent yang tertunda. |
VOICE_ACTION_HANDLE_EXCEPTION |
String dengan kunci.KEY_EXCEPTION
yang dipetakan ke ExceptionValue
(dijelaskan dalam Nilai pengecualian).KEY_FALLBACK_ASSISTANT_ENABLED yang dipetakan ke nilai Boolean. Jika nilainya
true , asisten penggantian yang dapat menangani permintaan pengguna telah
dinonaktifkan. |
Tindakan yang diharapkan untuk dilakukan terhadap pengecualian ditentukan dalam dokumentasi untuk pengecualian tersebut. |
Nilai pengecualian
EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING
menunjukkan kepada asisten suara bahwa asisten suara tersebut tidak memiliki izin Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE
dan untuk mendapatkan izin ini dari pengguna.
Meminta izin pemroses notifikasi
Jika asisten suara default tidak memiliki izin pemroses notifikasi, FallbackAssistant
platform (jika diaktifkan oleh produsen mobil) mungkin membaca pesan dengan lantang sebelum asisten suara
diberi tahu untuk meminta izin. Untuk menentukan apakah FallbackAssistant
diaktifkan dan
telah membaca pesan, asisten suara harus memeriksa
nilai Boolean KEY_FALLBACK_ASSISTANT_ENABLED
dalam payload.
Platform merekomendasikan asisten suara untuk menambahkan logika pembatasan kapasitas untuk
jumlah permintaan izin ini. Tindakan ini menghormati pengguna yang tidak
ingin memberikan izin ini kepada asisten suara dan lebih memilih
FallbackAssistant
untuk membaca pesan teks dengan lantang. Meminta izin
kepada pengguna setiap kali pengguna menekan Putar pada notifikasi pesan
dapat menjadi pengalaman pengguna yang negatif. Platform ini tidak menerapkan batas kapasitas
atas nama asisten suara.
Saat meminta izin pemroses notifikasi, asisten suara harus
menggunakan CarUxRestrictionsManager
untuk menentukan apakah pengguna sedang parkir atau mengemudi. Jika pengguna sedang mengemudi, asisten suara
akan menampilkan notifikasi yang memberikan petunjuk tentang cara memberikan izin. Tindakan ini
membantu (dan mengingatkan) pengguna untuk memberikan izin saat lebih aman.
Menggunakan StatusBarNotification
StatusBarNotification
yang diteruskan dengan tindakan suara Baca dan Balas
selalu dalam notifikasi pesan yang kompatibel dengan mobil seperti yang dijelaskan
dalam Memberi tahu
pengguna tentang pesan. Meskipun beberapa notifikasi mungkin tidak memiliki intent Reply Pending, semuanya memiliki intent menandai sebagai Telah Dibaca yang tertunda.
Untuk menyederhanakan interaksi dengan notifikasi, gunakan NotificationPayloadHandler
,
yang menyediakan metode untuk mengekstrak pesan dari notifikasi dan menulis
pesan balasan ke intent tertunda yang sesuai dari notifikasi. Setelah
asisten suara membaca pesan, asisten suara harus memicu intent Tandai
sebagai Telah Dibaca.
Memenuhi prasyarat Ketuk untuk Membaca
Hanya VoiceInteractionSession
dari asisten suara
default yang diberi tahu saat pengguna memicu tindakan suara untuk membaca dan
membalas pesan. Seperti yang disebutkan di atas, asisten suara default ini juga harus
memiliki izin pemroses notifikasi.
Diagram urutan
Gambar ini menampilkan alur logika CarVoiceInteractionSession actions
:
Gambar 2. Diagram urutan untuk VOICE_ACTION_READ_NOTIFICATION.
Dalam kasus Gambar 3, aplikasi pembatasan kapasitas pada permintaan izin direkomendasikan:
Gambar 3. Diagram urutan untuk VOICE_ACTION_REPLY_NOTIFICATION.
Gambar 4. Diagram urutan untuk VOICE_ACTION_HANDLE_EXCEPTION.
Membaca nama aplikasi
Jika Anda ingin asisten suara membaca nama aplikasi pesan dengan lantang selama pembacaan pesan (misalnya, "Sam dari Hangouts mengatakan..."), buat fungsi seperti yang ditampilkan dalam contoh kode berikut untuk memastikan asisten membaca nama yang benar:
@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; }