Untuk menerapkan Aplikasi Interaksi Suara (VIA), Anda perlu menyelesaikan langkah-langkah berikut:
- Buat kerangka VIA.
- (opsional) Terapkan alur penyiapan/login.
- (opsional) Terapkan layar Setelan.
- Mendeklarasikan izin yang diperlukan dalam file manifes.
- Mengimplementasikan UI pelat suara.
- Mengimplementasikan pengenalan suara (harus menyertakan implementasi RecognitionService API).
- Mengimplementasikan ucapan (secara opsional, Anda dapat mengimplementasikan TextToSpeech API).
- Mengimplementasikan fulfillment perintah. Lihat konten ini di Memenuhi Perintah.
Bagian berikut menjelaskan cara menyelesaikan setiap langkah yang disebutkan di atas.
Membuat kerangka VIA
Manifes
Aplikasi terdeteksi sebagai satu aplikasi dengan Interaksi Suara saat hal berikut disertakan dalam manifes:
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myvoicecontrol"> ... <application ... > <service android:name=".MyInteractionService" android:label="@string/app_name" android:permission="android.permission.BIND_VOICE_INTERACTION" android:process=":interactor"> <meta-data android:name="android.voice_interaction" android:resource="@xml/interaction_service" /> <intent-filter> <action android:name= "android.service.voice.VoiceInteractionService" /> </intent-filter> </service> </application> </manifest>
Dalam contoh ini:
- VIA harus mengekspos layanan yang memperluas
VoiceInteractionService
, dengan filter intent untuk tindakanVoiceInteractionService.SERVICE_INTERFACE ("android.service.voice.VoiceInteractionService")
. - Layanan ini harus memiliki izin tanda tangan sistem
BIND_VOICE_INTERACTION
. - Layanan ini harus menyertakan file metadata
android.voice_interaction
untuk memuat hal-hal berikut:res/xml/interaction_service.xml
<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android" android:sessionService= "com.example.MyInteractionSessionService" android:recognitionService= "com.example.MyRecognitionService" android:settingsActivity= "com.example.MySettingsActivity" android:supportsAssist="true" android:supportsLaunchVoiceAssistFromKeyguard="true" android:supportsLocalInteraction="true" />
Untuk mengetahui detail tentang setiap kolom, lihat R.styleable#VoiceInteractionService
.
Mengingat semua VIA juga merupakan layanan pengenalan suara, Anda juga harus
sertakan yang berikut ini dalam manifes Anda:
AndroidManifest.xml
<manifest ...> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <application ...> ... <service android:name=".RecognitionService" ...> <intent-filter> <action android:name="android.speech.RecognitionService" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> <meta-data android:name="android.speech" android:resource="@xml/recognition_service" /> </service> </application> </manifest>
Layanan pengenalan suara juga memerlukan metadata berikut:
res/xml/recognition_service.xml
<recognition-service xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="com.example.MyRecognizerSettingsActivity" />
VoiceInteractionService, VoiceInteractionSessionService, dan VoiceInteractionSession
Diagram berikut menggambarkan siklus proses dari setiap entity ini:
Gambar 1. Lifecycle
Seperti yang disebutkan sebelumnya, VoiceInteractionService
adalah titik entri
dengan VIA. Tanggung jawab utama layanan ini adalah:
- Melakukan inisialisasi setiap proses yang harus tetap berjalan selama VIA ini adalah yang aktif. Misalnya, deteksi frasa pengaktif.
- Melaporkan voice action yang didukung (lihat Ketuk untuk Membaca Asisten Suara).
- Meluncurkan sesi interaksi suara dari layar kunci (keyguard).
Dalam bentuknya yang paling sederhana, implementasi VoiceInteractionService akan terlihat seperti ini:
public class MyVoiceInteractionService extends VoiceInteractionService { private static final List<String> SUPPORTED_VOICE_ACTIONS = Arrays.asList( CarVoiceInteractionSession.VOICE_ACTION_READ_NOTIFICATION, CarVoiceInteractionSession.VOICE_ACTION_REPLY_NOTIFICATION, CarVoiceInteractionSession.VOICE_ACTION_HANDLE_EXCEPTION ); @Override public void onReady() { super.onReady(); // TODO: Setup hotword detector } @NonNull @Override public Set<String> onGetSupportedVoiceActions( @NonNull Set<String> voiceActions) { Set<String> result = new HashSet<>(voiceActions); result.retainAll(SUPPORTED_VOICE_ACTIONS); return result; } ... }
Implementasi VoiceInteractionService#onGetSupportedVoiceActions()
adalah
yang diperlukan untuk menangani
Ketuk untuk Membaca dari Asisten Suara.
VoiceInteractionSessionService digunakan oleh sistem untuk membuat dan
berinteraksi dengan VoiceInteractionSession. IPS hanya memiliki satu tanggung jawab,
untuk memulai sesi baru bila diminta.
public class MyVoiceInteractionSessionService extends VoiceInteractionSessionService { @Override public VoiceInteractionSession onNewSession(Bundle args) { return new MyVoiceInteractionSession(this); } }
Terakhir, VoiceInteractionSession adalah tempat sebagian besar pekerjaan
apa yang akan dilakukan. Satu instance sesi dapat digunakan kembali untuk menyelesaikan beberapa
interaksi pengguna. Di AAOS, tersedia CarVoiceInteractionSession
helper,
yang membantu menerapkan beberapa
fungsi unik otomotif.
public class MyVoiceInteractionSession extends CarVoiceInteractionSession { public InteractionSession(Context context) { super(context); } @Override protected void onShow(String action, Bundle args, int showFlags) { closeSystemDialogs(); // TODO: Unhide UI and update UI state // TODO: Start processing audio input } ... }
VoiceInteractionSession
memiliki sekumpulan besar metode callback yang
yang dijelaskan di bagian berikut. baca daftar lengkapnya di dokumentasi untuk VoiceInteractionSession
.
Menerapkan alur penyiapan/login
Penyiapan dan login dapat terjadi:
- Selama orientasi perangkat (Wizard Penyiapan).
- Selama pertukaran layanan interaksi suara (Setelan).
- Setelah peluncuran pertama saat aplikasi dipilih.
Untuk mengetahui detail tentang pengalaman pengguna dan panduan visual yang direkomendasikan, lihat Asisten Pramuat: Panduan UX.
Penyiapan saat pertukaran layanan suara
Pengguna dapat selalu memilih VIA yang belum dikonfigurasi. Hal ini dapat terjadi karena:
- Pengguna melewati Wizard Penyiapan sepenuhnya atau pengguna melewati suara model interaksi.
- Pengguna memilih VIA yang berbeda dari yang dikonfigurasi selama perangkat proses orientasi.
Bagaimanapun, VoiceInteractionService
memiliki beberapa cara untuk mendorong pengguna
untuk menyelesaikan penyiapan:
- Pengingat notifikasi.
- Balasan suara otomatis saat pengguna mencoba menggunakannya.
Catatan: Sangat tidak disarankan untuk menyajikan alur penyiapan VIA tanpa permintaan eksplisit dari pengguna. Ini berarti bahwa VIA harus menghindari secara otomatis menampilkan konten di HU selama booting perangkat atau sebagai akibat dari peralihan pengguna atau buka kunci.
Pengingat notifikasi
Pengingat notifikasi adalah cara yang tidak mengganggu untuk menunjukkan perlunya pengaturan, dan untuk memberi pengguna keleluasaan untuk menavigasi ke pengaturan asisten alur kerja.
Gambar 2. Pengingat notifikasi
Berikut adalah cara kerja alur ini:
Gambar 3. Alur pengingat notifikasi
Balasan suara
Ini adalah alur paling sederhana untuk diimplementasikan, memulai sebuah ucapan
callback VoiceInteractionSession#onShow()
, yang menjelaskan kepada pengguna
perlu dilakukan, lalu memintanya (jika pengaturan diizinkan dengan status Pembatasan UX)
jika mereka ingin memulai alur penyiapan. Jika penyiapan tidak dapat dilakukan pada saat itu, jelaskan hal ini
situasi.
Penyiapan saat penggunaan pertama
Selalu ada kemungkinan pengguna memicu VIA yang belum dikonfigurasi. Dalam kasus semacam ini:
- Beri tahu pengguna secara verbal tentang situasi ini (misalnya, "Agar dapat bekerja dengan baik, Saya minta Anda menyelesaikan beberapa langkah ... ").
- Jika mesin pembatasan UX mengizinkan (lihat UX_LIMITEDIONS_NO_SETUP), tanyakan pengguna apakah mereka ingin memulai pengaturan dan kemudian buka layar Pengaturan untuk VIA.
- Atau (misalnya, jika pengguna mengemudi), tinggalkan notifikasi untuk pengguna. klik pada opsi jika aman untuk melakukannya.
Membuat layar penyiapan interaksi suara
Layar penyiapan dan login harus dikembangkan sebagai aktivitas reguler. Lihat Panduan UX dan visual untuk pengembangan UI di Asisten Pramuat: Panduan UX.
Pedoman umum:
- VIA harus mengizinkan pengguna untuk menginterupsi dan melanjutkan penyiapan kapan saja.
- Penyiapan tidak akan diizinkan jika pembatasan
UX_RESTRICTIONS_NO_SETUP
diberlakukan. Untuk mengetahui detailnya, lihat Panduan Gangguan bagi Pengemudi. - Layar pengaturan harus sesuai dengan sistem desain untuk setiap kendaraan. Layar umum tata letak, ikon, warna dan aspek lainnya harus konsisten dengan keseluruhan UI. Lihat Penyesuaian untuk mengetahui detailnya.
Menerapkan layar setelan
Gambar 4. Integrasi setelan
Layar setelan merupakan aktivitas Android reguler. Jika diterapkan, titik masuknya
harus dinyatakan dalam res/xml/interaction_service.xml
sebagai bagian dari VIA
manifes (lihat
Manifes).
Bagian Setelan adalah tempat yang tepat untuk melanjutkan penyiapan dan login (jika pengguna belum menyelesaikannya
) atau tawarkan opsi logout atau beralih pengguna jika diperlukan. Mirip dengan Penyiapan
layar yang dijelaskan di atas, layar tersebut harus:
- Berikan opsi untuk keluar kembali ke layar sebelumnya di stack layar (misalnya, ke Setelan Mobil).
- Tidak diizinkan saat mengemudi. Untuk mengetahui detailnya, lihat Panduan Gangguan bagi Pengemudi.
- Cocokkan setiap sistem desain kendaraan. Untuk mengetahui detailnya, lihat Penyesuaian.
Mendeklarasikan izin yang diperlukan dalam file manifes
Izin yang diperlukan oleh VIA dapat dibagi menjadi tiga kategori:
- Izin tanda tangan sistem. Ini adalah izin hanya diberikan kepada APK yang telah diinstal sebelumnya dan ditandatangani sistem. Pengguna tidak dapat memberikan izin tersebut, hanya OEM yang dapat memberikan izin tersebut saat membangun image sistem mereka. Untuk informasi selengkapnya tentang cara mendapatkan izin tanda tangan, lihat Memberikan Izin yang Dilindungi Sistem.
- Izin berbahaya. Ini adalah izin akses yang harus berikan menggunakan dialog PermissionsController. OEM dapat memberikan beberapa izin ke VoiceInteractionService default. Namun, mengingat bahwa default ini mungkin berubah dari satu perangkat ke perangkat lainnya, aplikasi harus dapat meminta izin lainnya jika diperlukan.
- Izin lainnya. Ini semua adalah izin akses lain yang tidak memerlukan intervensi pengguna. Izin ini diberikan secara otomatis oleh sistem.
Berdasarkan penjelasan di atas, bagian berikut hanya berfokus pada permintaan izin berbahaya. Izin hanya boleh diminta saat pengguna di layar login atau setelan.
Jika aplikasi tidak memiliki izin yang diperlukan untuk beroperasi, alur yang direkomendasikan adalah menggunakan ucapan suara untuk menjelaskan situasi kepada dan notifikasi untuk memberikan {i>affordance<i} yang dapat digunakan pengguna untuk arahkan kembali ke layar pengaturan VIA. Untuk mengetahui detailnya, lihat 1. Pengingat notifikasi.
Meminta izin sebagai bagian dari layar setelan
Izin berbahaya diminta menggunakan metode ActivityCompat#requestPermission()
reguler (atau yang setara). Untuk mengetahui detail tentang cara meminta izin, lihat
Meminta Izin Aplikasi.
Gambar 5. Meminta izin
Izin pemroses notifikasi
Untuk mengimplementasikan alur TTR, VIA harus ditetapkan sebagai pemroses notifikasi. Ini bukan izin akses itu sendiri, melainkan konfigurasi yang memungkinkan sistem untuk mengirim notifikasi ke alamat pemroses. Untuk mengetahui apakah VIA diberi akses terhadap informasi ini, aplikasi tersebut dapat:
- (Opsional) Periksa apakah ada pemroses notifikasi sebelumnya dengan menggunakan
CarAssistUtils#assistantIsNotificationListener()
. Hal ini bisa dilakukan, misalnya, selama alur penyiapan. - (Wajib) Merespons penanganan
CarVoiceInteractionSession#onShow()
dengan tindakanVOICE_ACTION_HANDLE_EXCEPTION
dan pengecualianEXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING
.
Jika akses ini belum diberikan sebelumnya, VIA harus mengarahkan pengguna ke Bagian Akses Notifikasi di Setelan Mobil, menggunakan kombinasi ucapan dan notifikasi. Kode berikut dapat digunakan untuk membuka bagian yang sesuai dari aplikasi setelan:
private void requestNotificationListenerAccess() { Intent intent = new Intent(Settings .ACTION_NOTIFICATION_LISTENER_SETTINGS); intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName()); startActivity(intent); }
Mengimplementasikan UI pelat suara
Saat VoiceInteractionSession
menerima callback onShow()
,
perangkat itu bisa menampilkan
UI pelat suara. Untuk panduan visual dan UX terkait implementasi pelat suara,lihat
Asisten Pramuat: Panduan UX.
Gambar 6. Menampilkan pelat suara
Ada dua opsi cara menerapkan UI ini:
- Mengganti
VoiceInteractionSession#onCreateContentView()
- Meluncurkan Aktivitas menggunakan
VoiceInteractionSession#startAssistantActivity()
Menggunakan onCreateContentView()
Ini adalah cara default untuk menampilkan pelat suara. VoiceInteractionSession
class dasar membuat jendela dan mengelola siklus prosesnya selama suara
tetap hidup. Aplikasi harus mengganti VoiceInteractionSession#onCreateContentView()
dan mengembalikan tampilan yang dilampirkan ke jendela itu segera setelah sesi
dibuat. Tampilan ini seharusnya tidak terlihat terlebih dahulu. Saat interaksi suara dimulai,
tampilan ini harus terlihat di VoiceInteractionSession#onShow()
lalu tidak terlihat kembali di VoiceInteractionSession#onHide()
.
public class MyVoiceInteractionSession extends CarVoiceInteractionSession { private View mVoicePlate; … @Override public View onCreateContentView() { mVoicePlate = inflater.inflate(R.layout.voice_plate, null); … } @Override protected void onShow(String action, Bundle args, int showFlags) { // TODO: Update UI state to "listening" mVoicePlate.setVisibility(View.VISIBLE); } @Override public void onHide() { mVoicePlate.setVisibility(View.GONE); } … }
Saat menggunakan metode ini, Anda mungkin perlu menyesuaikan VoiceInteractionSession#onComputeInsets()
untuk memperhitungkan wilayah terhalang UI Anda.
Menggunakan startAssistantActivity()
Dalam hal ini, VoiceInteractionSession
mendelegasikan penanganan suara
UI ke aktivitas reguler. Jika opsi ini digunakan, VoiceInteractionSession
harus menonaktifkan pembuatan jendela konten defaultnya (lihat Menggunakan onCreateContentView()) pada onPrepareShow()
. Pukul VoiceInteractionSession#onShow()
, sesi akan memulai suara
aktivitas pelat menggunakan VoiceInteractionSession#startAssistantActivity()
. Ini
memulai UI dengan setelan jendela dan tanda aktivitas yang tepat.
public class MyVoiceInteractionSession extends CarVoiceInteractionSession { … @Override public void onPrepareShow(Bundle args, int showFlags) { super.onPrepareShow(args, showFlags); setUiEnabled(false); } @Override protected void onShow(String action, Bundle args, int showFlags) { closeSystemDialogs(); Intent intent = new Intent(getContext(), VoicePlateActivity.class); intent.putExtra(VoicePlateActivity.EXTRA_ACTION, action); intent.putExtra(VoicePlateActivity.EXTRA_ARGS, args); startAssistantActivity(intent); } … }
Untuk menjaga komunikasi
antara aktivitas ini dan
VoiceInteractionSession
, kumpulan Intent internal atau binding layanan dapat
tidak diperlukan. Misalnya, saat VoiceInteractionSession#onHide()
dipanggil, metode
sesi harus bisa meneruskan permintaan ini ke aktivitas.
Penting. Di Otomotif, hanya diberi anotasi khusus
satu atau beberapa aktivitas yang tercantum dalam "daftar yang diizinkan" UXR dapat ditampilkan saat
mengemudi. Ini berlaku untuk aktivitas yang dimulai dengan
VoiceInteractionSession#startAssistantActivity()
. Ingatlah untuk
anotasikan aktivitas Anda dengan <meta-data
android:name="distractionOptimized" android:value="true"/>
atau sertakan ini
aktivitas di tombol systemActivityWhitelist
dari /packages/services/Car/service/res/values/config.xml
. Untuk informasi selengkapnya, lihat Pengemudi
Pedoman Gangguan.
Mengimplementasikan pengenalan suara
Di bagian ini, Anda akan mempelajari cara mengimplementasikan pengenalan suara melalui deteksi dan pengenalan frasa pengaktif. Kata cepat adalah kata pemicu yang digunakan untuk memulai kueri baru atau tindakan dengan suara. Misalnya, "Ok Google" atau "Ok Google".
Deteksi frasa pengaktif DSP
Android menyediakan akses ke detektor frasa pengaktif selalu aktif di tingkat DSP dengan
dari AlwaysOnHotwordDetector
.
deteksi frasa pengaktif dengan CPU rendah. Penggunaan fungsi ini
dibagi menjadi dua bagian:
- Pembuatan instance
AlwaysOnHotwordDetector
. - Pendaftaran model suara deteksi frasa pengaktif.
Implementasi VoiceInteractionService dapat membuat pendeteksi frasa pengaktif menggunakan
VoiceInteractionService#createAlwaysOnHotwordDetector()
,
meneruskan frasa kunci dan lokal yang
ingin digunakan untuk deteksi. Hasilnya,
aplikasi menerima onAvailabilityChanged()
dengan salah satu kemungkinan nilai berikut:
STATE_HARDWARE_UNAVAILABLE
. Kemampuan DSP tidak tersedia di perangkat seluler. Dalam hal ini, Deteksi frasa pengaktif software digunakan.STATE_HARDWARE_UNSUPPORTED
. Dukungan DSP tidak tersedia secara umum, tetapi DSP tidak mendukung kombinasi frasa kunci dan lokal tertentu. Aplikasi dapat memilih untuk menggunakan Deteksi Frasa Pengaktif Software.STATE_HARDWARE_ENROLLED
. Deteksi hot word sudah siap dan dapat dimulai dengan memanggil metodestartRecognition()
.STATE_HARDWARE_UNENROLLED
. Model suara untuk frasa utama yang diminta tidak tersedia, tetapi Anda juga dapat melakukan pendaftaran.
Pendaftaran model suara deteksi frasa pengaktif dapat dilakukan dengan menggunakan IVoiceInteractionManagerService#updateKeyphraseSoundModel()
.
Beberapa model dapat didaftarkan ke dalam sistem pada waktu tertentu, tetapi hanya satu model
model terkait dengan AlwaysOnHotwordDetector
.
Deteksi frasa pengaktif DSP mungkin hanya tersedia di perangkat tertentu. MELALUI developer
harus memeriksa kemampuan hardware menggunakan getDspModuleProperties()
. Untuk contoh kode yang ditampilkan
cara mendaftarkan model suara, lihat VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java
.
Lihat Rekaman serentak terkait
pengenalan frasa pengaktif serentak.
Deteksi frasa pengaktif software
Seperti yang ditunjukkan di atas, deteksi frasa pengaktif DSP mungkin tidak tersedia di semua (misalnya, Android Emulator tidak menyediakan emulasi DSP). Dalam kasus ini, pengenalan suara perangkat lunak adalah satu-satunya alternatif. Untuk menghindari gangguan dengan aplikasi yang mungkin memerlukan akses ke mikrofon, VIA harus mengakses input audio menggunakan:
- Perekaman audio harus menggunakan MediaRecorder.AudioSource.HOTWORD.
- Tahan izin
android.Manifest.permission.CAPTURE_AUDIO_HOTWORD
.
Kedua konstanta ini adalah @hide
dan hanya tersedia untuk aplikasi yang dipaketkan.
Mengelola input audio dan pengenalan suara
Input audio akan diterapkan menggunakan class MediaRecorder.
Untuk mengetahui informasi selengkapnya tentang cara menggunakan API ini, lihat dokumen MediaRecorder
Ringkasan. Layanan interaksi suara juga diharapkan RecognitionService
implementasi class. Aplikasi apa pun dalam sistem yang memerlukan pengenalan suara akan menggunakan
untuk mengakses kemampuan ini. Untuk melakukan pengenalan suara dan memiliki akses ke mikrofon, VIA
harus berisi android.permission.RECORD_AUDIO
.
Aplikasi yang mengakses RecognitionService
implementasi diharapkan juga menyimpan izin ini.
Sebelum Android 10, akses mikrofon hanya diberikan ke satu aplikasi di (kecuali deteksi frasa pengaktif, lihat di atas). Mulai dari Android 10, dapat dibagikan akses mikrofon. Untuk informasi selengkapnya, lihat Berbagi Input Audio.
Mengakses output audio
Ketika VIA siap memberikan tanggapan verbal, penting untuk ikuti serangkaian panduan berikut:
- Saat meminta fokus audio atau mengelola output audio, aplikasi
harus menggunakan
AudioAttributes#USAGE_ASSISTANT
danAudioAttributes#CONTENT_TYPE_SPEECH
sebagai atribut audio. - Selama pengenalan ucapan, fokus audio harus diminta dengan
AudioManage#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE
. Perlu diketahui bahwa beberapa aplikasi media mungkin tidak bereaksi dengan baik terhadap perintah media (lihat Memenuhi Perintah Media) selagi audionya fokus dihapus.