Ketuk-untuk-Baca Asisten suara

Android Automotive menganggap suara sebagai komponen penting interaksi yang aman bagi pengguna dan merupakan salah satu cara aman bagi pengguna untuk berinteraksi dengan Android Automotive OS saat mengemudi. Hasilnya, kami memperluas API asisten suara Android (termasuk VoiceInteractionSession) untuk memungkinkan asisten suara melakukan tugas bagi pengguna yang mungkin sulit dicapai saat mengemudi.

Ketuk untuk Membaca memungkinkan asisten suara membaca dan membalas pesan teks di nama pengguna, saat pengguna berinteraksi dengan notifikasi pesan. Untuk menyediakan fungsionalitas ini, Anda dapat mengintegrasikan asisten suara dengan CarVoiceInteractionSession.

Di Otomotif, notifikasi yang diposting ke Pusat Notifikasi teridentifikasi sebagai INBOX atau INBOX_IN_GROUP (misalnya, pesan SMS) menyertakan Tombol Putar. Pengguna dapat mengklik Play untuk menampilkan asisten suara membacakan notifikasi dengan lantang, dan jika perlu, membalas dengan suara.

Notifikasi ketuk untuk membaca

Gambar 1. Notifikasi Ketuk untuk Membaca dengan tombol Putar.

Mengintegrasikan dengan CarVoiceInteractionSession

Bagian selanjutnya menjelaskan cara mengintegrasikan asisten suara dengan CarVoiceInteractionSession.

Mendukung interaksi suara

Aplikasi yang menyediakan layanan interaksi suara mobil harus terintegrasi dengan interaksi suara Android yang sudah ada. Untuk mempelajari lebih lanjut, lihat Asisten Google untuk Android (dengan pengecualian VoiceInteractionSession). Meskipun semua API interaksi suara elemen tetap sama seperti yang diterapkan di perangkat seluler, CarVoiceInteractionSession (dijelaskan dalam Menerapkan CarVoiceInteractionSession) menggantikan VoiceInteractionSession. Untuk informasi selengkapnya, lihat halaman ini:

Mengimplementasikan CarVoiceInteractionSession

CarVoiceInteractionSession mengekspos API yang dapat Anda gunakan untuk memungkinkan asisten suara membacakan pesan teks membalas pesan tersebut atas nama pengguna.

Perbedaan utama antara CarVoiceInteractionSession dan class VoiceInteractionSession adalah bahwa CarVoiceInteractionSession meneruskan dalam 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:

SesiInteraksiMobil VoiceInteractionSession
onShow menggunakan tiga parameter ini:
  • args
  • showFlags
  • actions
onShow menggunakan dua parameter ini:
  • args
  • showFlags

Perubahan di Android 10

Mulai Android 10, platform akan memanggil VoiceInteractionService.onGetSupportedVoiceActions untuk mendeteksi tindakan yang didukung. Asisten suara mengganti dan mengimplementasikan VoiceInteractionService.onGetSupportedVoiceActions, seperti yang ditunjukkan dalam contoh berikut:

public class MyInteractionService extends VoiceInteractionService {
    private static final List SUPPORTED_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 detail tentang setiap tindakan, lihat Diagram urutan.

Tindakan Payload yang diharapkan Tindakan interaksi suara yang diharapkan
VOICE_ACTION_READ_NOTIFICATION Bacakan pesan kepada pengguna, lalu aktifkan Tandai sebagai Sudah dibaca tertunda intent kembali saat pesan berhasil dibaca. Secara opsional, minta pengguna untuk membalas.
VOICE_ACTION_REPLY_NOTIFICATION Parcelable dengan kunci.
KEY_NOTIFICATION yang memetakan ke StatusBarNotification.
Memerlukan android.permission.BIND_NOTIFICATION_LISTENER_SERVICE.
Minta pengguna untuk menyatakan pesan balasan, masukkan pesan balasan ke dalam RemoteInputReply dari intent yang tertunda, lalu mengaktifkan intent yang tertunda.
VOICE_ACTION_HANDLE_EXCEPTION String dengan kunci.
KEY_EXCEPTION yang dipetakan ke ExceptionValue (dijelaskan di Nilai pengecualian).
KEY_FALLBACK_ASSISTANT_ENABLED yang memetakan ke nilai Boolean. Jika nilai adalah true, asisten penggantian yang dapat menangani permintaan pengguna telah dinonaktifkan.
Tindakan yang diharapkan yang akan dilakukan untuk pengecualian ditentukan dalam untuk pengecualian ini.

Nilai pengecualian

EXCEPTION_NOTIFICATION_LISTENER_PERMISSIONS_MISSING menunjukkan kepada asisten suara bahwa asisten suara tidak memiliki izin Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE dan memperoleh izin ini dari pengguna.

Meminta izin pemroses notifikasi

Jika asisten suara default tidak memiliki pemroses notifikasi izin akses, FallbackAssistant platform (jika diaktifkan oleh produsen mobil) mungkin membacakan pesan tersebut 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 ini merekomendasikan asisten suara menambahkan logika pembatasan kapasitas untuk berapa kali izin ini diminta. Hal itu akan menghormati pengguna yang tidak ingin memberikan izin ini kepada asisten suara dan memilih FallbackAssistant untuk membacakan pesan teks. Meminta untuk meminta izin pengguna setiap kali pengguna menekan Play pada notifikasi pesan bisa menjadi pengalaman pengguna yang negatif. Platform tidak menerapkan batas kapasitas atas nama asisten suara.

Saat meminta izin pemroses notifikasi, asisten suara harus menggunakan CarUxRestrictionsManager untuk menentukan apakah pengguna parkir atau mengemudi. Jika pengguna sedang mengemudi, asisten suara menampilkan notifikasi yang memberikan petunjuk tentang cara memberikan izin. Tindakan ini membantu (dan mengingatkan) pengguna untuk memberikan izin ketika lebih aman.

Menggunakan StatusBarNotification

StatusBarNotification lulus dengan fitur Baca dan Balas voice action selalu ada dalam notifikasi pesan yang kompatibel dengan mobil seperti yang dijelaskan di Beri tahu pengguna pesan. Meskipun beberapa notifikasi mungkin tidak memiliki opsi Reply Tertunda , mereka semua memiliki intent 'Tertunda' yang ditandai sebagai Baca.

Untuk menyederhanakan interaksi dengan notifikasi, gunakan NotificationPayloadHandler, yang menyediakan metode untuk mengekstrak pesan dari notifikasi dan menulis membalas pesan ke maksud tertunda yang sesuai dari notifikasi. Setelah asisten suara membaca pesan, asisten suara harus mengaktifkan Tanda sebagai intent Baca.

Memenuhi prasyarat Ketuk untuk Baca

Suara default hanya VoiceInteractionSession Asisten diberi tahu saat pengguna memicu voice action untuk membaca dan membalas pesan. Seperti disebutkan di atas, asisten suara {i>default<i} ini juga harus memiliki izin pemroses notifikasi.

Diagram urutan

Gambar ini menampilkan alur logika CarVoiceInteractionSession actions:

VOICE_ACTION_READ_NOTIFICATION

Gambar 2. Diagram urutan untuk VOICE_ACTION_READ_NOTIFICATION.

Dalam kasus Gambar 3, aplikasi pembatasan kapasitas pada permintaan izin direkomendasikan:

VOICE_ACTION_REPLY_NOTIFICATION

Gambar 3. Diagram urutan untuk VOICE_ACTION_REPLY_NOTIFICATION.

VOICE_ACTION_HANDLE_EXCEPTION

Gambar 4. Diagram urutan untuk VOICE_ACTION_HANDLE_EXCEPTION.

Baca nama aplikasi

Jika Anda ingin asisten suara membacakan nama aplikasi pesan dengan lantang selama pembacaan pesan (misalnya, "Sam dari Hangouts berkata..."), 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;
}