Pengembangan Aplikasi

Untuk menerapkan Aplikasi Interaksi Suara (VIA), Anda menyelesaikan langkah-langkah ini:

  1. Buat kerangka VIA.
  2. ( opsional ) Menerapkan alur penyiapan/masuk.
  3. ( opsional ) Menerapkan layar Pengaturan.
  4. Deklarasikan izin yang diperlukan dalam file manifes.
  5. Menerapkan UI pelat suara.
  6. Menerapkan pengenalan suara (harus menyertakan implementasi API RecognitionService).
  7. Menerapkan ucapan (opsional, Anda dapat mengimplementasikan TextToSpeech API).
  8. Melaksanakan pemenuhan perintah. Lihat konten ini di Memenuhi Perintah .

Bagian berikut menjelaskan cara menyelesaikan setiap langkah yang disebutkan di atas.

Buat Kerangka VIA

Manifest

Aplikasi terdeteksi sebagai satu dengan Interaksi Suara saat berikut ini 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 maksud untuk tindakan VoiceInteractionService.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 yang berisi 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 detail tentang setiap bidang, lihat R.styleable#VoiceInteractionService . Mengingat bahwa semua VIA juga merupakan layanan pengenal suara, Anda juga harus menyertakan 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 bagian 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 hidup masing-masing entitas ini:

Siklus hidup

Gambar 1. Siklus Hidup

Seperti yang dinyatakan sebelumnya, VoiceInteractionService adalah titik masuk ke VIA. Tanggung jawab utama dari layanan ini adalah:

  • Inisialisasi proses apa pun yang harus tetap berjalan selama VIA ini aktif. Misalnya, deteksi kata cepat.
  • Melaporkan tindakan suara yang didukung (lihat Voice Assistant Tap-to-Read ).
  • Luncurkan 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() diperlukan untuk menangani Voice Assistant Tap-to-Read . VoiceInteractionSessionService digunakan oleh sistem untuk membuat dan berinteraksi dengan VoiceInteractionSession . Hanya memiliki satu tanggung jawab, untuk memulai sesi baru saat diminta.

public class MyVoiceInteractionSessionService extends VoiceInteractionSessionService {
    @Override
    public VoiceInteractionSession onNewSession(Bundle args) {
        return new MyVoiceInteractionSession(this);
    }
}

Terakhir, VoiceInteractionSession adalah tempat sebagian besar pekerjaan akan dilakukan. Instance sesi tunggal dapat digunakan kembali untuk menyelesaikan beberapa interaksi pengguna. Di AAOS, terdapat pembantu CarVoiceInteractionSession , yang membantu mengimplementasikan 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 akan dijelaskan di bagian berikut. lihat dokumentasi untuk VoiceInterationSession daftar lengkap.

Terapkan Alur Penyiapan/Masuk

Penyiapan dan masuk dapat terjadi:

  • Selama orientasi perangkat (Setup Wizard).
  • Selama pertukaran layanan interaksi suara (Pengaturan).
  • Saat peluncuran pertama saat aplikasi dipilih.

Untuk detail tentang pengalaman pengguna yang direkomendasikan dan panduan visual, lihat Asisten yang Dimuat Sebelumnya: Panduan UX .

Pengaturan Selama Pertukaran Layanan Suara

Pengguna selalu dapat memilih VIA yang belum dikonfigurasi dengan benar. Hal ini dapat terjadi karena:

  • Pengguna melewatkan Wizard Penyiapan seluruhnya atau pengguna melewatkan langkah konfigurasi interaksi suara.
  • Pengguna memilih VIA yang berbeda dari yang dikonfigurasi selama orientasi perangkat.

Bagaimanapun, VoiceInteractionService memiliki beberapa cara untuk mendorong pengguna menyelesaikan penyiapan:

  • Pengingat pemberitahuan.
  • Balasan suara otomatis saat pengguna mencoba menggunakannya.

Catatan : Sangat tidak disarankan untuk menyajikan alur penyiapan VIA tanpa permintaan pengguna yang eksplisit. Ini berarti bahwa VIA harus menghindari secara otomatis menampilkan konten pada HU selama boot perangkat atau sebagai akibat dari peralihan atau pembukaan kunci pengguna.

1. Pengingat Pemberitahuan

Pengingat notifikasi adalah cara yang tidak mengganggu untuk menunjukkan perlunya penyiapan, dan untuk memberi pengguna kemampuan untuk menavigasi ke alur penyiapan asisten.

Pengingat pemberitahuan

Gambar 2. Pengingat notifikasi

Berikut adalah bagaimana aliran ini akan bekerja:

Alur pengingat notifikasi

Gambar 3. Alur pengingat notifikasi

Note : Bergantung pada aturan Pembatasan UX (lihat Panduan Pengalihan Pengemudi ), alur pengaturan mungkin tidak diizinkan saat mengemudi. Ketika pengguna mengklik pemberitahuan dan pengaturan tidak diizinkan, aplikasi harus menggunakan ucapan untuk menjelaskan situasi kepada pengguna daripada mencoba menampilkan UI yang akan segera diblokir.

2. Balasan suara

Ini adalah alur paling sederhana untuk diterapkan, memulai ucapan pada panggilan balik VoiceInteractionSession#onShow() , menjelaskan kepada pengguna apa yang perlu dilakukan, dan kemudian menanyakan mereka (jika penyiapan diizinkan dengan status Pembatasan UX) apakah mereka ingin memulai aliran pengaturan. Jika penyiapan tidak memungkinkan pada saat itu, jelaskan juga situasi ini.

Pengaturan Pada Penggunaan Pertama

Pengguna selalu dapat memicu VIA yang belum dikonfigurasi dengan benar. Dalam beberapa kasus:

  1. Informasikan secara lisan kepada pengguna tentang situasi ini (misalnya, "Agar berfungsi dengan baik, saya ingin Anda menyelesaikan beberapa langkah ... ").
  2. Jika mesin pembatasan UX mengizinkan (lihat UX_RESTRICTIONS_NO_SETUP ), tanyakan kepada pengguna apakah mereka ingin memulai proses penyiapan dan kemudian buka layar Pengaturan untuk VIA.
  3. Jika tidak (misalnya, jika pengguna mengemudi), tinggalkan pemberitahuan bagi pengguna untuk mengklik opsi saat aman untuk melakukannya.

Membangun Layar Pengaturan Interaksi Suara

Layar Penyetelan dan Masuk harus dikembangkan sebagai aktivitas reguler . Lihat UX dan panduan visual untuk pengembangan UI di Preloaded Assistants: UX Guidance .

Petunjuk umum:

  • VIA harus memungkinkan pengguna untuk menginterupsi dan melanjutkan penyiapan kapan saja.
  • Penyiapan tidak boleh diizinkan jika pembatasan UX_RESTRICTIONS_NO_SETUP berlaku. Untuk detailnya, lihat Panduan Pengalihan Pengemudi .
  • Layar pengaturan harus sesuai dengan sistem desain untuk setiap kendaraan. Tata letak layar umum, ikon, warna, dan aspek lainnya harus konsisten dengan UI lainnya. Lihat Penyesuaian untuk detailnya.

Terapkan Layar Pengaturan

Integrasi pengaturan

Gambar 4. Integrasi pengaturan

Layar pengaturan adalah aktivitas Android biasa. Jika diterapkan, titik masuknya harus dideklarasikan di res/xml/interaction_service.xml sebagai bagian dari manifes VIA (lihat Manifes ). Bagian Pengaturan adalah tempat yang baik untuk melanjutkan penyiapan dan masuk (jika pengguna tidak menyelesaikannya) atau menawarkan opsi keluar atau beralih pengguna jika diperlukan. Mirip dengan layar Pengaturan yang dijelaskan di atas, layar ini harus:

  • Berikan opsi untuk keluar kembali ke layar sebelumnya di tumpukan layar (misalnya, ke Pengaturan Mobil).
  • Tidak diizinkan saat mengemudi. Untuk detailnya, lihat Panduan Pengalihan Pengemudi .
  • Cocokkan setiap sistem desain kendaraan. Untuk detailnya, lihat Penyesuaian .

Deklarasikan Izin yang Diperlukan dalam File Manifes

Izin yang diperlukan oleh VIA dapat dibagi menjadi tiga kategori:

  • Izin tanda tangan sistem. Ini adalah izin yang hanya diberikan untuk APK yang telah diinstal sebelumnya dan ditandatangani oleh sistem. Pengguna tidak dapat memberikan izin ini, hanya OEM yang dapat memberikan izin tersebut saat membangun citra sistem mereka. Untuk informasi selengkapnya tentang mendapatkan izin tanda tangan, lihat Memberikan Izin Hak Istimewa Sistem .
  • Izin berbahaya. Ini adalah izin yang harus diberikan pengguna menggunakan dialog PermissionsController. OEM dapat memberikan beberapa izin ini sebelumnya ke VoiceInteractionService default. Tetapi mengingat bahwa default ini mungkin berubah dari perangkat ke perangkat, aplikasi harus dapat meminta izin ini saat diperlukan.
  • Izin lainnya. Ini semua adalah izin lain yang tidak memerlukan intervensi pengguna. Izin ini akan secara otomatis diberikan oleh sistem.

Mengingat hal di atas, bagian berikut hanya akan fokus pada meminta izin berbahaya. Izin hanya boleh diminta saat pengguna berada di layar masuk atau layar setelan.

Jika aplikasi tidak memiliki izin yang diperlukan untuk beroperasi, alur yang disarankan adalah menggunakan ucapan suara untuk menjelaskan situasi kepada pengguna, dan pemberitahuan untuk memberikan kemampuan yang dapat digunakan pengguna untuk menavigasi kembali ke layar pengaturan VIA . Untuk detailnya, lihat 1. Pengingat notifikasi .

Minta Izin sebagai Bagian dari Layar Pengaturan

Izin berbahaya diminta menggunakan metode ActivityCompat#requestPermission() reguler (atau yang setara). Untuk detail tentang cara meminta izin, lihat Meminta Izin Aplikasi .

Minta izin

Gambar 5. Meminta izin

Izin Pendengar Pemberitahuan

Untuk menerapkan alur TTR, VIA harus ditetapkan sebagai pendengar notifikasi. Ini bukan izin semata, melainkan konfigurasi yang memungkinkan sistem mengirim pemberitahuan ke pendengar terdaftar. Untuk mengetahui apakah VIA diberi akses ke informasi ini, aplikasi dapat:

Jika akses ini tidak diberikan sebelumnya, VIA harus mengarahkan pengguna ke bagian Akses Pemberitahuan di Pengaturan Mobil, menggunakan kombinasi ucapan dan pemberitahuan. Kode berikut dapat digunakan untuk membuka bagian yang sesuai dari aplikasi pengaturan:

private void requestNotificationListenerAccess() {
    Intent intent = new Intent(Settings
        .ACTION_NOTIFICATION_LISTENER_SETTINGS);
    intent.putExtra(Settings.EXTRA_APP_PACKAGE, getPackageName());
    startActivity(intent);
}

Menerapkan UI Pelat Suara

Saat VoiceInteractionSession menerima panggilan balik onShow() , itu dapat menampilkan UI pelat suara. Untuk panduan visual dan UX tentang implementasi pelat suara, lihat Asisten Termuat: Panduan UX .

Menampilkan pelat suara

Gambar 6. Menampilkan pelat suara

Ada dua opsi tentang cara mengimplementasikan UI ini:

  • Ganti VoiceInteractionSession#onCreateContentView()
  • Luncurkan Aktivitas menggunakan VoiceInteractionSession#startAssistantActivity()

Menggunakan onCreateContentView()

Ini adalah cara default untuk menampilkan pelat suara. Kelas dasar VoiceInteractionSession akan membuat jendela dan mengelola siklus hidupnya selama sesi suara masih hidup. Aplikasi harus mengganti VoiceInteractionSession#onCreateContentView() dan mengembalikan tampilan yang akan dilampirkan ke jendela itu segera setelah sesi dibuat. Pandangan ini pada awalnya seharusnya tidak terlihat. Saat interaksi suara dimulai, tampilan ini harus dibuat terlihat di VoiceInteractionSession#onShow() dan kemudian tidak terlihat lagi 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 ingin menyesuaikan VoiceInteractionSession#onComputeInsets() untuk memperhitungkan wilayah yang dikaburkan dari UI Anda.

Menggunakan startAssistantActivity()

Dalam hal ini, VoiceInteractionSession akan mendelegasikan penanganan UI pelat suara ke Aktivitas reguler. Saat opsi ini digunakan, implementasi VoiceInteractionSession harus menonaktifkan pembuatan jendela konten default (lihat Menggunakan onCreateContentView() ) pada callback onPrepareShow() . Di VoiceInteractionSession#onShow() , sesi akan memulai Aktivitas pelat suara menggunakan VoiceInteractionSession#startAssistantActivity() . Metode ini memulai UI dengan pengaturan Window 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 mempertahankan komunikasi antara aktivitas ini dan VoiceInteractionSession , serangkaian Intent internal atau pengikatan layanan mungkin diperlukan. Misalnya, saat VoiceInteractionSession#onHide() dipanggil, sesi harus dapat meneruskan permintaan ini ke aktivitas.

Penting. Di Otomotif, hanya aktivitas atau aktivitas beranotasi khusus yang tercantum dalam "daftar yang diizinkan" UXR yang dapat ditampilkan saat mengemudi. Ini berlaku untuk aktivitas yang dimulai dengan VoiceInteractionSession#startAssistantActivity() juga. Ingatlah untuk memberi anotasi pada aktivitas Anda dengan <meta-data android:name="distractionOptimized" android:value="true"/> atau sertakan aktivitas ini dalam kunci systemActivityWhitelist dari /packages/services/Car/service/res/values/config.xml file /packages/services/Car/service/res/values/config.xml . Untuk informasi lebih lanjut, lihat Pedoman Pengalihan Pengemudi .

Menerapkan Pengenalan Suara

Di bagian ini, Anda mempelajari cara menerapkan pengenalan suara melalui deteksi dan pengenalan kata cepat. Kata cepat adalah kata pemicu yang digunakan untuk memulai kueri atau tindakan baru dengan suara. Misalnya, "OK Google" atau "Hai Google".

Deteksi Kata Cepat DSP

Android menyediakan akses ke detektor kata cepat yang selalu aktif di tingkat DSP melalui kelas AlwaysOnHotwordDetector . Ini memberikan cara mudah untuk menerapkan deteksi kata cepat dengan CPU rendah. Penggunaan fungsi ini dibagi menjadi dua bagian:

Implementasi VoiceInteractionService dapat membuat detektor kata cepat menggunakan VoiceInteractionService#createAlwaysOnHotwordDetector() , meneruskan frasa kunci dan lokal yang ingin mereka gunakan untuk deteksi. Akibatnya, aplikasi akan menerima callback onAvailabilityChanged() dengan salah satu kemungkinan nilai berikut:

  • STATE_HARDWARE_UNAVAILABLE . Kemampuan DSP tidak tersedia pada perangkat. Dalam hal ini, deteksi kata cepat Perangkat Lunak akan digunakan.
  • STATE_HARDWARE_UNSUPPORTED . Dukungan DSP tidak tersedia secara umum, tetapi DSP tidak mendukung kombinasi frasa kunci dan lokal yang diberikan. Aplikasi dapat memilih untuk menggunakan Deteksi Kata Cepat Perangkat Lunak .
  • STATE_HARDWARE_ENROLLED . Deteksi kata panas sudah siap dan dapat dimulai dengan memanggil metode startRecognition() .
  • STATE_HARDWARE_UNENROLLED . Model suara untuk frasa kunci yang diminta tidak tersedia, tetapi pendaftaran dimungkinkan.

Pendaftaran model suara pendeteksi kata cepat dapat dilakukan dengan menggunakan IVoiceInteractionManagerService#updateKeyphraseSoundModel() . Beberapa model dapat didaftarkan dalam sistem pada waktu tertentu, tetapi hanya satu model yang akan dikaitkan dengan AlwaysOnHotwordDetector . Deteksi kata cepat DSP mungkin tidak tersedia di semua perangkat. Pengembang VIA harus memeriksa kemampuan perangkat keras menggunakan metode getDspModuleProperties() . Untuk kode contoh yang menunjukkan cara mendaftarkan model suara, lihat VoiceEnrollment/src/com/android/test/voiceenrollment/EnrollmentUtil.java . Lihat Pengambilan Serentak mengenai pengenalan kata cepat bersamaan.

Deteksi Kata Cepat Perangkat Lunak

Seperti yang ditunjukkan di atas, deteksi kata cepat DSP mungkin tidak tersedia di semua perangkat (misalnya, emulator Android tidak menyediakan emulasi DSP). Dalam hal ini, pengenalan suara perangkat lunak adalah satu-satunya alternatif. Untuk menghindari gangguan dengan aplikasi lain yang mungkin memerlukan akses ke mikrofon, VIA harus mengakses input audio menggunakan:

Kedua konstanta ini adalah @hide dan hanya tersedia untuk aplikasi yang dibundel.

Mengelola Input Audio dan Pengenalan Suara

Masukan audio akan diimplementasikan menggunakan MediaRecorder API . Untuk informasi selengkapnya tentang cara menggunakan API ini, lihat Ikhtisar MediaRecorder . Layanan interaksi suara juga diharapkan menjadi implementasi RecognitionService . Aplikasi apa pun dalam sistem yang memerlukan pengenalan suara akan menggunakan SpeechRecognizer API untuk mengakses kemampuan ini. Untuk melakukan pengenalan suara dan memiliki akses ke mikrofon, VIA harus memiliki android.permission.RECORD_AUDIO . Aplikasi yang mengakses implementasi RecognitionService diharapkan memiliki izin ini juga.

Sebelum Android 10, akses mikrofon hanya diberikan ke satu aplikasi dalam satu waktu (dengan pengecualian deteksi kata cepat, lihat di atas). Dimulai dengan Android 10, akses mikrofon dapat dibagikan. Untuk informasi lebih lanjut, lihat Berbagi Input Audio .

Mengakses Keluaran Audio

Ketika VIA siap memberikan tanggapan verbal, penting untuk mengikuti pedoman berikut ini: