Membuat notifikasi di Wear OS

Halaman ini menjelaskan cara membuat notifikasi untuk jam tangan. Halaman ini juga menjelaskan cara menyediakan konten tambahan bagi setiap notifikasi yang dihubungkan ke jam tangan dari ponsel pendamping.

Notifikasi di jam tangan memiliki struktur yang sama dengan notifikasi di ponsel. Selain itu, untuk memberikan pengalaman terbaik kepada pengguna, Wear OS by Google menyediakan API untuk menambahkan fitur spesifik wearable ke notifikasi.

Saat dikirimkan dari aplikasi, setiap notifikasi akan muncul sebagai kartu pada Aliran Notifikasi.

Gambar 1. Notifikasi yang sama ditampilkan di ponsel dan jam tangan.

Baik jam tangan maupun ponsel dapat menjadi sumber notifikasi. Gunakan class NotificationCompat.Builder untuk membuat notifikasi bagi wearable. Ketika Anda membuat notifikasi dengan class ini, sistem akan menangani tampilan notifikasi dengan benar.

Catatan: Notifikasi yang menggunakan RemoteViews tidak memiliki tata letak kustom dan perangkat wearable hanya menampilkan teks serta ikon. Namun, Anda dapat membuat notifikasi kustom yang menggunakan tata letak kartu kustom dengan membuat aplikasi wearable yang berjalan pada jam tangan.

Mengimpor class yang diperlukan

Untuk mengimpor paket yang diperlukan, tambahkan baris ini ke file build.gradle Anda:

    compile "com.android.support:support-v13:27.0.2"
    

Sekarang, setelah proyek memiliki akses ke paket yang diperlukan, impor class yang diperlukan dari support library:

Kotlin

    import android.support.v4.app.NotificationCompat
    import android.support.v4.app.NotificationManagerCompat
    import android.support.v4.app.NotificationCompat.WearableExtender
    

Java

    import android.support.v4.app.NotificationCompat;
    import android.support.v4.app.NotificationManagerCompat;
    import android.support.v4.app.NotificationCompat.WearableExtender;
    

Membuat notifikasi menggunakan builder notifikasi

v4 support library memungkinkan Anda membuat notifikasi menggunakan fitur notifikasi terbaru, seperti ikon dan tombol tindakan, yang tetap kompatibel dengan Android 1.6 (API level 4) dan lebih tinggi.

Catatan: Mulai dari Android 8.0 (API level 26), Anda harus membuat saluran notifikasi untuk setiap tipe notifikasi yang ingin ditampilkan.

Untuk membuat notifikasi dengan support library:

  1. Buat instance NotificationCompat.Builder.

    Kotlin

        val notificationId = 1
        // The channel ID of the notification.
        val id = "my_channel_01"
        // Build intent for notification content
        val viewPendingIntent = Intent(this, ViewEventActivity::class.java).let { viewIntent ->
            viewIntent.putExtra(EXTRA_EVENT_ID, eventId)
            PendingIntent.getActivity(this, 0, viewIntent, 0)
        }
    
        // Notification channel ID is ignored for Android 7.1.1
        // (API level 25) and lower.
        val notificationBuilder = NotificationCompat.Builder(this, id)
                .setSmallIcon(R.drawable.ic_event)
                .setContentTitle(eventTitle)
                .setContentText(eventLocation)
                .setContentIntent(viewPendingIntent)
        

    Java

        int notificationId = 001;
        // The channel ID of the notification.
        String id = "my_channel_01";
        // Build intent for notification content
        Intent viewIntent = new Intent(this, ViewEventActivity.class);
        viewIntent.putExtra(EXTRA_EVENT_ID, eventId);
        PendingIntent viewPendingIntent =
                PendingIntent.getActivity(this, 0, viewIntent, 0);
    
        // Notification channel ID is ignored for Android 7.1.1
        // (API level 25) and lower.
        NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(this, id)
                .setSmallIcon(R.drawable.ic_event)
                .setContentTitle(eventTitle)
                .setContentText(eventLocation)
                .setContentIntent(viewPendingIntent);
        
  2. Kirim notifikasi dengan meneruskan objek Notification menggunakan ID notifikasi ke notify().

    Kotlin

        NotificationManagerCompat.from(this).apply {
            notify(notificationId, notificationBuilder.build())
        }
        

    Java

        // Get an instance of the NotificationManager service
        NotificationManagerCompat notificationManager =
                NotificationManagerCompat.from(this);
    
        // Issue the notification with notification manager.
        notificationManager.notify(notificationId, notificationBuilder.build());
        

Ketika notifikasi ini muncul di ponsel, pengguna dapat memanggil PendingIntent yang ditetapkan oleh metode setContentIntent() dengan menyentuh notifikasi. Ketika muncul di perangkat wearable, notifikasi ini muncul dalam aliran notifikasi. Untuk notifikasi terhubung, pengguna dapat mengklik notifikasi guna melihat notifikasi yang diperluas dan memicu tindakan yang ditentukan, seperti tindakan buka. Biasanya, tindakan ini akan membuka Aktivitas pada aplikasi ponsel Anda.

Membuat notifikasi yang diperluas

Notifikasi yang diperluas menyediakan tindakan dan konten tambahan yang signifikan untuk setiap notifikasi. Saat Anda menetapkan tindakan dan halaman konten tambahan bagi notifikasi, semuanya akan tersedia bagi pengguna dalam notifikasi yang diperluas. Setiap notifikasi yang diperluas mengikuti Desain Material untuk Wear OS sehingga pengguna mendapatkan pengalaman seperti aplikasi.

Jika tindakan pertama dalam notifikasi yang diperluas memiliki RemoteInput (misalnya, tindakan Balas), pilihan yang Anda tetapkan dengan setChoices() akan muncul dalam notifikasi yang diperluas di bawah tindakan pertama.

Pengguna dapat melihat notifikasi yang diperluas dengan mengetuk notifikasi ketika salah satu dari persyaratan berikut benar:

  • Notifikasi dibuat oleh aplikasi pada ponsel yang tersambung, serta dihubungkan ke Wear.
  • Notifikasi tidak memiliki contentIntent.

Catatan: Warna latar belakang khusus aplikasi yang ditetapkan untuk notifikasi dengan metode setColor() hanya ditampilkan ketika Anda memperluas notifikasi.

Praktik terbaik untuk notifikasi yang diperluas

Untuk menentukan kapan harus menggunakan notifikasi yang diperluas, ikuti panduan berikut:

  • Semua notifikasi yang dihubungkan dari ponsel yang tersambung ke perangkat Wear akan menggunakan notifikasi yang diperluas.
  • Jika notifikasi dibuat oleh aplikasi yang berjalan secara lokal di Wear, Anda harus mengatur agar target sentuh notifikasi Anda meluncurkan objek Notification dengan ID notifikasi dalam aplikasi dengan memanggil setContentIntent(). Sebaiknya, jangan gunakan notifikasi yang diperluas untuk notifikasi yang dihasilkan oleh aplikasi yang berjalan secara lokal di Wear.

Menambahkan notifikasi yang diperluas

Notifikasi yang diperluas memungkinkan Anda menyertakan tindakan dan konten tambahan bagi notifikasi. Anda dapat menentukan tingkat detail yang disediakan oleh notifikasi aplikasi. Namun, bijaklah dengan banyaknya detail yang disertakan dalam notifikasi.

Menambahkan konten tambahan

Untuk menampilkan teks tambahan dalam notifikasi yang diperluas, gunakan BigTextStyle.

Untuk menambahkan gambar dalam notifikasi yang diperluas, gunakan BigPictureStyle. Jika ingin menambahkan lebih dari satu gambar dalam notifikasi yang diperluas, gunakan metode addPage() beserta BigPictureStyle.

Tindakan utama

Notifikasi yang diperluas akan memuat satu tindakan utama, yaitu tindakan pertama dalam notifikasi kecuali tindakan lainnya ditetapkan menggunakan setContentAction().

Tindakan tambahan

Untuk menentukan tindakan tambahan, gunakan addAction() atau addActions(). Panel samping tindakan pada notifikasi yang diperluas berisi semua tindakan yang tersedia.

Menambahkan tindakan notifikasi

Selain tindakan konten utama yang ditentukan oleh setContentIntent(), Anda dapat menambahkan tindakan lainnya dengan meneruskan PendingIntent ke metode addAction().

Misalnya, kode berikut menunjukkan tipe notifikasi yang sama seperti di atas, tetapi menambahkan tindakan untuk melihat lokasi acara pada peta.

Kotlin

    // Build an intent for an action to view a map
    val mapIntent = Intent(Intent.ACTION_VIEW)
    // The channel ID of the notification.
    val id = "my_channel_01"
    val mapPendingIntent = Intent(Intent.ACTION_VIEW).let { mapIntent ->
        mapIntent.data = Uri.parse("geo:0,0?q=" + Uri.encode(location))
        PendingIntent.getActivity(this, 0, mapIntent, 0)
    }

    val notificationBuilder = NotificationCompat.Builder(this, id)
            .setSmallIcon(R.drawable.ic_event)
            .setContentTitle(eventTitle)
            .setContentText(eventLocation)
            .setContentIntent(viewPendingIntent)
            .addAction(R.drawable.ic_map, getString(R.string.map), mapPendingIntent)
    

Java

    // Build an intent for an action to view a map
    Intent mapIntent = new Intent(Intent.ACTION_VIEW);
    // The channel ID of the notification.
    String id = "my_channel_01";
    Uri geoUri = Uri.parse("geo:0,0?q=" + Uri.encode(location));
    mapIntent.setData(geoUri);
    PendingIntent mapPendingIntent =
            PendingIntent.getActivity(this, 0, mapIntent, 0);

    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(this, id)
            .setSmallIcon(R.drawable.ic_event)
            .setContentTitle(eventTitle)
            .setContentText(eventLocation)
            .setContentIntent(viewPendingIntent)
            .addAction(R.drawable.ic_map,
                    getString(R.string.map), mapPendingIntent);
    

Pada ponsel, tindakan ini muncul sebagai tombol tambahan yang tersemat pada notifikasi. Pada perangkat wearable, tindakan muncul dalam notifikasi yang diperluas setelah teks konten. Ketika pengguna mengetuk tindakan, intent yang terkait akan dipanggil pada ponsel.

Tips: Jika notifikasi menyertakan tindakan "Balas" (seperti untuk aplikasi messaging), Anda dapat menyempurnakan perilakunya dengan memungkinkan balasan masukan suara langsung dari perangkat wearable. Untuk informasi selengkapnya, baca Menambahkan Masukan Suara sebagai tindakan notifikasi.

Menambahkan tindakan inline

Tindakan inline memungkinkan pengguna mengambil tindakan pada notifikasi dari kartu aliran notifikasi. Di Wear, tindakan inline muncul sebagai tombol tambahan yang ditampilkan di bagian bawah notifikasi.

Tindakan inline bersifat opsional, tetapi disarankan ketika pengguna kemungkinan akan melakukan sesuatu pada notifikasi setelah melihat kontennya dalam kartu aliran notifikasi (tanpa harus membuka notifikasi yang diperluas). Contoh kasus penggunaan yang tepat untuk tindakan inline pada notifikasi termasuk membalas pesan teks, menghentikan aktivitas kebugaran, serta mengarsipkan pesan email.

Satu notifikasi hanya dapat menyediakan satu tindakan inline. Untuk menampilkan tindakan inline sebagai tombol tambahan dalam notifikasi, setel metode setHintDisplayActionInline() ke true. Ketika pengguna mengetuk tindakan inline, sistem akan memanggil intent yang telah ditetapkan dalam tindakan notifikasi.

Cuplikan kode berikut menambahkan petunjuk untuk menampilkan tindakan inline, dan menggunakan metode addAction untuk menambahkan tindakan inline pada notifikasi.

Kotlin

    //Wear OS requires a hint to display the reply action inline.
    val actionExtender = NotificationCompat.Action.WearableExtender()
            .setHintLaunchesActivity(true)
            .setHintDisplayActionInline(true)
    wearableExtender.addAction(actionBuilder.extend(actionExtender).build())
    

Java

    //Wear OS requires a hint to display the reply action inline.
    Action.WearableExtender actionExtender =
        new Action.WearableExtender()
            .setHintLaunchesActivity(true)
            .setHintDisplayActionInline(true);
    wearableExtender.addAction(actionBuilder.extend(actionExtender).build());
    

Menambahkan fitur spesifik wearable ke notifikasi

Jika perlu menambahkan fitur spesifik wearable pada notifikasi, seperti menyembunyikan ikon aplikasi dari notifikasi wearable atau memungkinkan pengguna mendikte respons teks dengan masukan suara, Anda dapat menggunakan class NotificationCompat.WearableExtender untuk menetapkan opsinya. Untuk menggunakan API ini:

  1. Buat instance WearableExtender, yang menyetel opsi spesifik wearable untuk notifikasi.
  2. Buat instance NotificationCompat.Builder, yang menyetel properti yang diinginkan untuk notifikasi seperti yang dijelaskan sebelumnya dalam tutorial ini.
  3. Panggil extend() pada notifikasi dan teruskan WearableExtender. Hal ini akan menerapkan opsi wearable pada notifikasi.
  4. Panggil build() untuk membuat notifikasi.

Catatan: Jika menggunakan NotificationManager framework, beberapa fitur dari NotificationCompat.WearableExtender tidak akan berfungsi, jadi, pastikan untuk menggunakan NotificationCompat.

Anda dapat menyinkronkan penutupan (pembatalan) notifikasi di seluruh perangkat pengguna. Untuk memungkinkan sinkronisasi penutupan, gunakan metode setDismissalId(). Untuk setiap notifikasi, teruskan ID yang unik secara global sebagai string ketika Anda memanggil metode setDismissalId(). Ketika notifikasi ditutup, semua notifikasi lain dengan ID penutupan yang sama akan ditutup di jam tangan dan ponsel pendamping. Untuk mendapatkan ID penutupan, gunakan getDismissalId().

Catatan: Metode setBackground() tidak didukung di Wear 2.0. Anda dapat menggunakan NotificationCompat.BigPictureStyle untuk notifikasi yang menyertakan gambar.

Metode setHintHideIcon() juga tidak didukung di Wear 2.0.

Menetapkan tindakan khusus wearable

Jika ingin membedakan tindakan yang tersedia di perangkat wearable dengan yang ada di ponsel, gunakan WearableExtender.addAction(). Setelah menambahkan tindakan dengan metode ini, perangkat wearable tidak akan menampilkan tindakan lain yang ditambahkan dengan NotificationCompat.Builder.addAction(). Tindakan yang ditambahkan dengan WearableExtender.addAction() hanya akan muncul di perangkat wearable dan tidak muncul di ponsel.

Menambahkan masukan suara sebagai tindakan notifikasi

Masukan suara adalah bagian yang penting dalam pengalaman wearable. Untuk membuat tindakan yang mendukung masukan suara, buat instance RemoteInput.Builder yang dapat Anda tambahkan ke tindakan notifikasi. Pembuat class ini menerima string yang digunakan sistem sebagai kunci untuk masukan suara, yang nantinya akan digunakan untuk memperoleh teks masukan dalam aplikasi ponsel.

Misalnya, berikut cara untuk membuat objek RemoteInput yang menyediakan label kustom untuk permintaan masukan suara:

Kotlin

    // Key for the string that's delivered in the action's intent
    const val EXTRA_VOICE_REPLY = "extra_voice_reply"
    ...
    val remoteInput = resources.getString(R.string.reply_label).let { replyLabel ->
        RemoteInput.Builder(EXTRA_VOICE_REPLY)
                .setLabel(replyLabel)
                .build()
    }
    

Java

    // Key for the string that's delivered in the action's intent
    private static final String EXTRA_VOICE_REPLY = "extra_voice_reply";

    String replyLabel = getResources().getString(R.string.reply_label);

    RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
            .setLabel(replyLabel)
            .build();
    

Menambahkan respons teks yang telah ditentukan

Selain memungkinkan masukan suara, Anda juga dapat menyediakan hingga lima respons teks yang dapat dipilih pengguna untuk balasan cepat. Panggil setChoices() dan teruskan sebagai array string.

Misalnya, Anda dapat menentukan beberapa respons dalam satu array resource:

res/values/strings.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string-array name="reply_choices">
            <item>Yes</item>
            <item>No</item>
            <item>Maybe</item>
        </string-array>
    </resources>
    

Kemudian, perluas array string dan tambahkan ke RemoteInput:

Kotlin

    // Key for the string that's delivered in the action's intent
    const val EXTRA_VOICE_REPLY = "extra_voice_reply"
    ...
    val remoteInput = resources.getString(R.string.reply_label).let { replyLabel ->
        resources.getStringArray(R.array.reply_choices).let { replyChoices ->
            RemoteInput.Builder(EXTRA_VOICE_REPLY)
                    .setLabel(replyLabel)
                    .setChoices(replyChoices)
                    .build()
        }
    }
    

Java

    public static final String EXTRA_VOICE_REPLY = "extra_voice_reply";
    ...
    String replyLabel = getResources().getString(R.string.reply_label);
    String[] replyChoices = getResources().getStringArray(R.array.reply_choices);

    RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY)
            .setLabel(replyLabel)
            .setChoices(replyChoices)
            .build();
    

Menerima masukan suara sebagai string

Untuk menerima pesan yang ditranskripsikan pengguna dalam aktivitas yang dideklarasikan dalam intent tindakan balasan, panggil getResultsFromIntent(), yang meneruskan intent tindakan "Balas". Metode ini mengembalikan Bundle yang berisi respons teks. Anda kemudian dapat meminta Bundle untuk mendapatkan respons.

Catatan: Jangan gunakan Intent.getExtras() untuk mendapatkan hasil suara karena masukan suara disimpan sebagai ClipData. Metode getResultsFromIntent() memberikan cara yang mudah untuk menerima rangkaian karakter tanpa harus memproses ClipData sendiri.

Kode berikut menunjukkan metode yang menerima intent dan mengembalikan respons suara, dan direferensikan dengan kunci EXTRA_VOICE_REPLY yang digunakan dalam contoh sebelumnya:

Kotlin

    /**
     * Obtain the intent that started this activity by calling
     * Activity.getIntent() and pass it into this method to
     * get the associated voice input string.
     */

    private fun getMessageText(intent: Intent): CharSequence? =
            RemoteInput.getResultsFromIntent(intent)?.run {
                getCharSequence(EXTRA_VOICE_REPLY)
            }
    

Java

    /**
     * Obtain the intent that started this activity by calling
     * Activity.getIntent() and pass it into this method to
     * get the associated voice input string.
     */

    private CharSequence getMessageText(Intent intent) {
        Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
        if (remoteInput != null) {
            return remoteInput.getCharSequence(EXTRA_VOICE_REPLY);
        }
        return null;
    }
    

Kotlin

    // Create an intent for the reply action
    val actionPendingIntent = Intent(this, ActionActivity::class.java).let { actionIntent ->
        PendingIntent.getActivity(this, 0, actionIntent,
                PendingIntent.FLAG_UPDATE_CURRENT)
    }
    // Create the action
    val action = NotificationCompat.Action.Builder(
            R.drawable.ic_action,
            getString(R.string.label),
            actionPendingIntent
    ).build()

    // Build the notification and add the action via WearableExtender
    var notification = NotificationCompat.Builder(context)
            .setSmallIcon(R.drawable.ic_message)
            .setContentTitle(getString(R.string.title))
            .setContentText(getString(R.string.content))
            .extend(NotificationCompat.WearableExtender().addAction(action))
            .build()
    

Java

    // Create an intent for the reply action
    Intent actionIntent = new Intent(this, ActionActivity.class);
    PendingIntent actionPendingIntent =
            PendingIntent.getActivity(this, 0, actionIntent,
                    PendingIntent.FLAG_UPDATE_CURRENT);

    // Create the action
    NotificationCompat.Action action =
            new NotificationCompat.Action.Builder(R.drawable.ic_action,
                    getString(R.string.label), actionPendingIntent)
                    .build();

    // Build the notification and add the action via WearableExtender
    Notification notification =
            new NotificationCompat.Builder(context)
                    .setSmallIcon(R.drawable.ic_message)
                    .setContentTitle(getString(R.string.title))
                    .setContentText(getString(R.string.content))
                    .extend(new WearableExtender().addAction(action))
                    .build();
    

Meluncurkan notifikasi dari aplikasi wearable mandiri

Cara membuat notifikasi dari aplikasi jam tangan mandiri sama dengan cara membuat notifikasi terhubung. Notifikasi yang berasal dari aplikasi Wear mandiri tampak mirip dengan notifikasi terhubung, tetapi berperilaku sedikit berbeda. Jika tidak ada contentIntent yang ditetapkan atau jika notifikasi dihubungkan dari ponsel yang tersambung, mengetuk notifikasi akan membuka notifikasi yang diperluas. Sedangkan, jika notifikasi berasal dari aplikasi jam tangan mandiri, mengetuknya akan mengaktifkan contentIntent untuk membuka aplikasi Wear. Untuk mempelajari cara membuat notifikasi dari aplikasi mandiri dan meniru perilaku notifikasi yang diperluas, lihat sampel Notifikasi Wear.

Secara default, notifikasi akan dihubungkan dari aplikasi di ponsel pendamping ke jam tangan yang tersambung. Jika Anda membuat aplikasi jam tangan mandiri dan memiliki aplikasi ponsel pendamping, aplikasi mungkin akan membuat notifikasi duplikat. Untuk informasi tentang menangani masalah notifikasi duplikat, lihat Mode Bridge untuk Notifikasi.