Menggunakan Notifikasi Android

Codelab ini adalah bagian dari kursus Android Lanjutan di Kotlin. Anda akan mendapatkan manfaat maksimal dari kursus ini jika menyelesaikan codelab secara berurutan, tetapi ini tidak bersifat wajib. Semua codelab kursus tercantum di halaman landing codelab Android Lanjutan di Kotlin.

Pengantar

Notifikasi adalah pesan yang ditampilkan kepada pengguna di luar UI aplikasi Anda. Notifikasi ditampilkan di bagian atas layar jika perangkat tidak terkunci atau, bergantung pada setelan keamanan, di layar kunci saat perangkat terkunci.

Notifikasi standar terdiri dari judul, deskripsi, dan ikon. Notifikasi juga dapat memiliki tindakan yang dapat diklik, balasan cepat, konten yang dapat diperluas, dan gambar.

Notifikasi dapat menyampaikan materi tepat waktu, dan dapat memiliki tombol untuk memungkinkan pengguna melakukan tindakan cepat, seperti mengirim balasan atau menunda alarm. Dengan mengklik notifikasi, pengguna akan diarahkan ke tampilan di aplikasi Anda yang terkait dengan konten notifikasi.

Notifikasi adalah cara yang berguna untuk mengingatkan pengguna tentang tugas penting, memberi tahu mereka bahwa sesuatu telah terjadi, atau menyampaikan informasi penting yang mereka butuhkan segera saat aplikasi Anda berada di latar belakang. Gunakan notifikasi seperlunya. Tindakan ini tidak hanya menghargai pengguna, tetapi juga membuat notifikasi aplikasi Anda lebih mungkin mendapatkan perhatian yang layak.

Dalam codelab ini, Anda akan mempelajari cara membuat dan menggunakan notifikasi di aplikasi Android.

Yang harus sudah Anda ketahui

Anda harus memahami:

  • Cara membuat aplikasi Android di Kotlin. Khususnya, bekerja dengan Android SDK.
  • Cara merancang aplikasi menggunakan Komponen Arsitektur dan data binding.
  • Pemahaman dasar tentang BroadcastReceiver
  • Pemahaman dasar tentang AlarmManager

Yang akan Anda pelajari

  • Cara membuat, menata gaya, dan mengirim notifikasi.
  • Cara membatalkan notifikasi.
  • Cara membuat saluran notifikasi.
  • Cara menambahkan tindakan cepat ke notifikasi.
  • Cara menampilkan badge notifikasi di ikon aplikasi.

Yang akan Anda lakukan

  • Tambahkan notifikasi ke aplikasi starter.
  • Membatalkan notifikasi yang Anda kirim sebelumnya.
  • Buat saluran untuk berbagai jenis notifikasi.
  • Sesuaikan notifikasi di aplikasi starter.
  • Tambahkan Tindakan Cepat untuk membuat notifikasi Anda interaktif.
  • Nonaktifkan badge notifikasi.

Memasak telur itu mudah, tetapi bisa menjadi tugas yang menantang jika Anda tidak melacak waktu. Dalam codelab ini, Anda akan mengerjakan aplikasi timer telur dan membuatnya sempurna, seperti telur Anda di masa mendatang. Anda akan memulai dengan aplikasi timer telur yang berfungsi dan memungkinkan pengguna menyetel setelan waktu memasak yang berbeda untuk berbagai gaya telur. Timer menghitung mundur dari interval waktu yang dipilih dan menampilkan pesan toast saat telur sudah siap.

Mungkin terlihat berfungsi, tetapi jauh dari sempurna, dan tidak benar-benar mudah digunakan. Sebagai permulaan, pesan toast hanya ditampilkan dalam waktu singkat, sehingga mudah terlewatkan. Selain itu, jika aplikasi tidak berada di latar depan atau perangkat terkunci, tidak ada indikator visual untuk status timer setelah pesan toast menghilang.

Idealnya, timer telur harus menggunakan notifikasi untuk memberi tahu pengguna saat waktu habis. Pengguna benar-benar perlu mengetahui bahwa telur sudah matang, jika tidak, telur akan terlalu matang. Notifikasi bersifat visual, dapat menyertakan suara, dan dapat membuat perangkat bergetar—semua cara untuk menarik perhatian pengguna. Dengan begitu, Anda bisa mendapatkan telur yang sempurna dan pengguna yang puas serta kenyang.

Untuk mendapatkan aplikasi contoh, Anda dapat:

Clone repositori dari GitHub dan alihkan ke cabang starter.

$  git clone https://github.com/googlecodelabs/android-kotlin-notifications


Atau, Anda dapat mendownload repositori sebagai file ZIP, mengekstraknya, dan membukanya di Android Studio.

Download Zip

  1. Buka dan jalankan aplikasi di Android Studio.

Anda akan melihat gambar telur dan menu dropdown dengan daftar interval waktu standar untuk memasak telur. Klik segitiga untuk menu drop-down Setengah Matang. Opsi pertama dalam daftar diberikan untuk tujuan pengujian dan menyetel alarm hanya 10 detik. Di samping daftar terdapat tombol yang memulai timer telur. Anda dapat menggunakan tombol ini untuk memulai dan menghentikan penghitung waktu telur kapan saja. Kode awal berfungsi sepenuhnya, yang berarti Anda dapat menyetel timer telur dan melihatnya menghitung mundur hingga 0. Setelah timer selesai, pesan toast akan ditampilkan, seperti yang ditunjukkan di bawah.

  1. Periksa kode sumber. Aplikasi starter terdiri dari satu aktivitas bernama MainActivity. Ada tiga subpaket bernama receiver, ui, dan util.

  • /receiver—Paket receiver berisi dua penerima siaran bernama AlarmReceiver dan SnoozeReceiver. AlarmReceiver dipicu oleh AlarmManager untuk mengirim notifikasi saat timer yang ditentukan pengguna berakhir. SnoozeReceiver menangani klik pengguna untuk menunda notifikasi.
  • /ui—Direktori ini berisi EggTimerFragment yang merupakan bagian UI aplikasi. EggTimerViewModel bertanggung jawab untuk memulai dan membatalkan timer serta tugas aplikasi terkait siklus proses lainnya.
  • /util—Dalam paket ini ada dua file. BindingUtils.kt memiliki adaptor binding untuk mengaktifkan data binding antara UI aplikasi dan ViewModel. NotificationUtils.kt memiliki metode ekstensi di NotificationManager.

Menggunakan notifikasi adalah cara yang bagus untuk mendapatkan perhatian pengguna terhadap aplikasi Anda. Baik aplikasi Anda tidak berjalan atau berjalan di latar depan, notifikasi akan menampilkan jendela pop-up di bagian atas layar dan dapat menyertakan suara atau getaran. Untuk membuat notifikasi, Anda perlu menggunakan pembuat notifikasi dan memberikan teks judul, teks konten, dan ikon. Setelah builder memiliki semua kolom yang diperlukan, NotificationManager, yang merupakan layanan sistem, akan membantu Anda menampilkan konten ini sebagai notifikasi. NotificationManager bertanggung jawab untuk mengirim notifikasi, memperbarui kontennya, dan membatalkan notifikasi. Pada langkah-langkah berikut, Anda akan menambahkan metode ekstensi ke NotificationManager. Dengan begitu, setiap kali Anda perlu menggunakan NotificationManager, Anda akan dapat menggunakan fungsi ekstensi ini untuk mendapatkan fungsionalitas yang perlu Anda gunakan.

Langkah 1: Buat Notifikasi dasar

Dalam tugas ini, Anda akan membuat notifikasi baru, menetapkan pesan untuk pengguna, dan mengirim notifikasi.

  1. Buka class NotificationUtils.kt dan temukan TODO: Step 1.1. Anda akan menemukan todo yang cocok dalam codelab ini dan kode aplikasi.
  2. Periksa fungsi sendNotification() yang diberikan. Anda akan memperluas fungsi ekstensi ini ke NotificationManager untuk mengirim notifikasi.
//NotificationUtils.kt
// TODO: Step 1.1 extension function to send messages (GIVEN)
/**
 * Builds and delivers a notification.
 *
 * @param messageBody, notification text.
 * @param context, activity context.
 */
fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
  1. Dapatkan instance builder notifikasi, teruskan konteks aplikasi dan ID saluran. ID saluran adalah nilai string untuk saluran.

Saluran Notifikasi adalah cara untuk mengelompokkan notifikasi. Dengan mengelompokkan jenis notifikasi yang serupa, developer dan pengguna dapat mengontrol semua notifikasi di saluran. Setelah dibuat, saluran dapat digunakan untuk mengirimkan sejumlah notifikasi.

//NotificationUtils.kt
// TODO: Step 1.2 get an instance of NotificationCompat.Builder
val builder = NotificationCompat.Builder(
        applicationContext,
        applicationContext.getString(R.string.egg_notification_channel_id)
)
  1. Tetapkan ikon notifikasi untuk merepresentasikan aplikasi Anda, judul, dan teks konten untuk pesan yang ingin Anda berikan kepada pengguna. Anda akan melihat lebih banyak opsi untuk menyesuaikan notifikasi lebih lanjut dalam codelab, tetapi ini adalah jumlah minimum data yang perlu Anda tetapkan untuk mengirim notifikasi.
//NotificationUtils.kt
   // TODO: Step 1.3 set title, text and icon to builder
   .setSmallIcon(R.drawable.cooked_egg)
   .setContentTitle(applicationContext.getString(R.string.notification_title))
   .setContentText(messageBody)
  1. Selanjutnya, Anda perlu memanggil notify() dengan ID unik untuk notifikasi dan dengan objek Notification dari builder Anda.

ID ini mewakili instance notifikasi saat ini dan diperlukan untuk memperbarui atau membatalkan notifikasi ini. Karena aplikasi Anda hanya akan memiliki satu notifikasi aktif dalam waktu tertentu, Anda dapat menggunakan ID yang sama untuk semua notifikasi. Anda sudah diberi konstanta untuk tujuan ini yang disebut NOTIFICATION_ID di NotificationUtils.kt. Perhatikan bahwa Anda dapat langsung memanggil notify() karena Anda melakukan panggilan dari fungsi ekstensi pada class yang sama.

//NotificationUtils.kt
   // TODO: Step 1.4 call notify to send the notification
    // Deliver the notification
    notify(NOTIFICATION_ID, builder.build())
  1. Buka ui/EggTimerViewModel.kt dan temukan fungsi startTimer(). Fungsi ini membuat alarm dengan interval waktu yang dipilih saat pengguna mengaktifkan timer telur.
  2. Anda akan memicu notifikasi dalam fungsi ini saat pengguna memulai timer. Untuk memanggil fungsi sendNotification() yang sebelumnya Anda terapkan, Anda memerlukan instance NotificationManager. NotificationManager adalah layanan sistem yang menyediakan semua fungsi yang diekspos untuk notifikasi API, termasuk fungsi ekstensi yang Anda tambahkan. Setiap kali Anda ingin mengirim, membatalkan, atau memperbarui notifikasi, Anda harus meminta instance NotificationManager dari sistem. Panggil fungsi sendNotification()| dengan pesan notifikasi dan dengan konteks.
// EggTimerViewModel.kt
// TODO: Step 1.5 get an instance of NotificationManager 
// and call sendNotification

val notificationManager = ContextCompat.getSystemService(
    app, 
    NotificationManager::class.java
) as NotificationManager
                notificationManager.sendNotification(app.getString(R.string.timer_running), app)

Anda hampir selesai. Namun, jika Anda menjalankan aplikasi sekarang dan menyetel timer, Anda tidak akan mendapatkan notifikasi.

  1. Buka logcat dan cari "No Channel found". Anda akan melihat pesan error bahwa egg_channel tidak ada. Pada langkah-langkah berikut, Anda akan mempelajari lebih lanjut Saluran Notifikasi dan memperbaikinya.

Langkah 2: Saluran Notifikasi

Mulai dari level API 26, semua notifikasi harus ditetapkan ke suatu saluran. Jika Anda menyentuh lama ikon peluncur aplikasi, memilih info aplikasi, dan mengetuk notifikasi, Anda akan melihat daftar saluran notifikasi yang terkait dengan aplikasi. Saat ini, daftar tersebut kosong karena aplikasi Anda belum membuat saluran apa pun.

Channel merepresentasikan "jenis" notifikasi—misalnya, timer telur Anda dapat mengirim notifikasi saat telur matang, dan juga menggunakan channel lain untuk mengirim notifikasi harian untuk mengingatkan Anda agar makan telur saat sarapan. Semua notifikasi dalam saluran dikelompokkan bersama, dan pengguna dapat mengonfigurasi setelan notifikasi untuk seluruh saluran. Dengan begitu, pengguna dapat mempersonalisasi setelan notifikasi berdasarkan jenis notifikasi yang mereka minati. Misalnya, pengguna Anda dapat menonaktifkan notifikasi sarapan, tetapi tetap memilih untuk melihat notifikasi dari timer.

Developer menetapkan setelan awal, tingkat kepentingan, dan perilaku yang akan diterapkan ke semua notifikasi di suatu saluran. Setelah Anda menetapkan setelan awal, pengguna dapat mengganti setelan ini.

Pada Langkah 1.1, Anda menggunakan egg_notification_channel_id sebagai saluran notifikasi, jadi sekarang Anda perlu membuat dan menyesuaikan setelan notifikasi serta perilaku saluran ini.

  1. Buka EggTimerFragment.kt dan temukan fungsi createChannel().
  2. Teruskan ID channel unik ke konstruktor NotificationChannel.
  3. Teruskan nama saluran notifikasi, yang juga akan dilihat pengguna di layar Setelan mereka.
  4. Sebagai parameter terakhir, teruskan tingkat kepentingan untuk saluran notifikasi. Tingkat kepentingan akan dibahas nanti dalam codelab ini, jadi untuk saat ini Anda dapat menggunakan NotificationManager.IMPORTANCE_LOW.
  5. Pada objek notificationChannel, tetapkan enableLights ke benar (true). Setelan ini akan mengaktifkan lampu saat notifikasi ditampilkan.
  6. Pada objek notificationChannel, tetapkan lightColor ke merah untuk menampilkan lampu merah saat notifikasi ditampilkan.
  7. Pada objek notificationChannel, tetapkan enableVibration ke benar (true) untuk mengaktifkan getaran.
  8. Pada objek notificationChannel, tetapkan deskripsi channel ke ‘Time for breakfast'.
  9. Dapatkan instance NotificationManager dengan memanggil getSystemService().
  10. Panggil createNotificationChannel() di NotificationManager dan teruskan objek notificationChannel yang Anda buat di langkah sebelumnya.
//EggTimerFragment.kt
private fun createChannel(channelId: String, channelName: String) {
    // TODO: Step 1.6 START create a channel
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val notificationChannel = NotificationChannel(
            channelId,
            channelName,
            // TODO: Step 2.4 change importance
            NotificationManager.IMPORTANCE_LOW
        )
        // TODO: Step 2.6 disable badges for this channel

        notificationChannel.enableLights(true)
        notificationChannel.lightColor = Color.RED
        notificationChannel.enableVibration(true)
        notificationChannel.description = "Time for breakfast"

        val notificationManager = requireActivity().getSystemService(
            NotificationManager::class.java
        )
        notificationManager.createNotificationChannel(notificationChannel)
    }
    // TODO: Step 1.6 END create channel
}
  1. Selanjutnya, untuk membuat saluran, Anda perlu memanggil fungsi createChannel() yang baru saja Anda tulis (Langkah 1.7). Fungsi ini menggunakan dua parameter, ID channel dan nama channel. Anda perlu mencari ID channel dan nama channel dari resource string yang sudah diberikan di project Anda.
// EggTimerFragment.kt
    // TODO: Step 1.7 call createChannel
    createChannel(
          getString(R.string.egg_notification_channel_id),
          getString(R.string.egg_notification_channel_name)
    )
  1. Anda harus meneruskan ID saluran ke builder notifikasi. Anda sudah melakukannya di Langkah 1.2. Menetapkan nilai yang salah sebagai ID saluran akan menyebabkan notifikasi gagal. Buka NotificationUtils.kt untuk memverifikasi bahwa ID channel yang sebelumnya Anda tetapkan sudah benar.
// NotificationUtils.kt
val builder = NotificationCompat.Builder(
        applicationContext,
       // TODO: Step 1.8 verify the notification channel name
        applicationContext.getString(R.string.egg_notification_channel_id)
)
  1. Jalankan aplikasi, dan Anda akan melihat aplikasi mengirim notifikasi setiap kali Anda memulai timer.
  2. Tarik status bar dan amati bahwa judul, konten, dan ikon notifikasi sesuai dengan yang Anda tetapkan pada langkah-langkah sebelumnya.
  3. Untuk memverifikasi channel yang baru dibuat, tutup aplikasi dan temukan ikon aplikasi. Tekan lama ikon aplikasi, lalu pilih Info aplikasi.

  1. Pilih Notifikasi dari daftar setelan. Anda akan melihat saluran baru bernama Egg, tepat di bawah setelan Show notifications.

Saat Anda menjalankan aplikasi, notifikasi akan ditampilkan. Anda sebagai developer aplikasi dan pengguna dapat menyesuaikan setelan dan perilaku untuk semua notifikasi yang dikirim di saluran ini. Selamat, Anda telah membuat notifikasi.

Langkah 3: Tambahkan notifikasi ke aplikasi Anda

Sejauh ini, contoh ini menunjukkan penggunaan dasar API notifikasi, tetapi mengirim notifikasi tepat setelah memulai timer tidak terlalu masuk akal. Pengguna mungkin lebih suka diberi tahu saat telur sudah siap. Di bagian codelab berikutnya, Anda akan memperbaiki hal ini dan mengubah pesan toast menjadi notifikasi.

Anda telah mengirim notifikasi dan mengamati cara notifikasi ditampilkan kepada pengguna, tetapi ini hanyalah langkah pertama untuk membuat notifikasi yang efektif. Pada langkah ini, Anda akan mengubah notifikasi agar dikirim pada waktu yang lebih tepat.

Aplikasi Anda menggunakan AlarmManager untuk menyetel alarm. Kode yang terkait dengan AlarmManager sudah diberikan dalam kode awal dan digunakan untuk menampilkan pesan toast. AlarmManager melacak pilihan waktu yang diinginkan dan akan memicu fungsi onReceive() dari AlarmReceiver.kt saat waktunya tiba. Jika Anda membuka AlarmReceiver.kt dan membuka onReceive(), Anda akan melihat pesan toast yang ditampilkan setiap kali Anda menyetel timer telur.

  1. Buka AlarmReceiver.kt, instance NotificationManager, dan panggil fungsi sendNotification() dengan parameter konteks dan teks pesan.
// AlarmReceiver.kt
   // TODO: Step 1.9 add call to sendNotification
   val notificationManager = ContextCompat.getSystemService(
       context, 
       NotificationManager::class.java
   ) as NotificationManager
             
   notificationManager.sendNotification(
       context.getText(R.string.eggs_ready).toString(), 
       context
   )
  1. Secara opsional, hapus toast karena aplikasi Anda akan mengirimkan notifikasi saat timer selesai.
// AlarmReceiver.kt
     // TODO: Step 1.10 [Optional] remove toast
//   Toast.makeText(
//       context, 
//       context.getText(R.string.eggs_ready),
//       Toast.LENGTH_SHORT
//   ).show()
  1. Jalankan aplikasi Anda . Anda akan melihat notifikasi setiap kali Anda memulai timer dan setiap kali timer selesai.

Hal ini tidak ideal. Anda tidak ingin mengirim terlalu banyak notifikasi kepada pengguna. Anda dapat menghapus notifikasi pertama yang dikirim saat pengguna memulai timer.

  1. Buka EggTimerFragment.kt dan hapus kode notifikasi untuk Langkah 1.5.
// EggTimeViewModel.kt

// TODO: Step 1.5 get an instance of NotificationManager 
// and call sendNotification
// val notificationManager = ContextCompat.getSystemService(
//      app,
//      NotificationManager::class.java
// ) as NotificationManager
// notificationManager.sendNotification(app.getString(R.string.eggs_ready), app)
  1. Jalankan aplikasi Anda lagi.
  2. Setel timer, letakkan di latar belakang, dan tunggu hingga waktu selesai. Anda akan melihat notifikasi. Ini adalah notifikasi yang jauh lebih berguna.

Langkah 4: Tambahkan maksud konten

  1. Jalankan aplikasi lagi, jika belum berjalan.
  2. Klik notifikasi. Tidak ada yang terjadi.

Menampilkan notifikasi dan memberi tahu pengguna adalah hal yang bagus, tetapi saat pengguna mengklik notifikasi, mereka berharap untuk kembali ke aplikasi yang sesuai. Di bagian codelab ini, Anda akan menambahkan intent ke notifikasi untuk membawa pengguna kembali ke layar timer.

Intent adalah objek pesan yang dapat Anda gunakan untuk meminta tindakan dari komponen aplikasi lain. Intent dapat digunakan untuk memulai aktivitas, layanan, atau mengirimkan siaran. Dalam hal ini, Anda menggunakan intent ini untuk memberi tahu sistem agar membuka MainActivity saat pengguna mengetuk notifikasi. Karena aplikasi Anda hanya terdiri dari satu tampilan, Anda tidak memiliki banyak opsi di sini. Namun, di aplikasi yang lebih besar, notifikasi harus menciptakan pengalaman yang lancar dengan mengarahkan pengguna ke layar yang sesuai saat mereka berinteraksi dengan notifikasi.

  1. Buka NotificationUtils.kt dan temukan fungsi ekstensi sendNotification().
  2. Buat Intent dengan applicationContext dan aktivitas yang akan diluncurkan, MainActivity::class.java.
// NotificationUtils.kt

fun NotificationManager.sendNotification(messageBody: String, applicationContext: Context) {
    // Create the content intent for the notification, which launches
    // this activity
   // TODO: Step 1.11 create intent
    val contentIntent = Intent(applicationContext, MainActivity::class.java)

Anda telah membuat intent, tetapi notifikasi ditampilkan di luar aplikasi Anda. Agar intent berfungsi di luar aplikasi Anda, Anda perlu membuat PendingIntent baru.

PendingIntent memberikan hak ke aplikasi lain atau sistem untuk melakukan operasi atas nama aplikasi Anda. PendingIntent itu sendiri hanyalah referensi ke token yang dikelola oleh sistem yang menjelaskan data asli yang digunakan untuk mengambilnya. Artinya, meskipun proses aplikasi pemiliknya dihentikan, PendingIntent itu sendiri akan tetap dapat digunakan dari proses lain yang telah diberikan kepadanya. Dalam hal ini, sistem akan menggunakan intent tertunda untuk membuka aplikasi atas nama Anda, terlepas dari apakah aplikasi timer sedang berjalan atau tidak.

  1. Buat PendingIntent dengan applicationContext, NOTIFICATION_ID, contentIntent yang Anda buat pada langkah sebelumnya, dan flag PendingIntent. Flag PendingIntent menentukan opsi untuk membuat PendingIntent baru atau menggunakan yang sudah ada. Anda perlu menetapkan PendingIntent.FLAG_UPDATE_CURRENT sebagai tanda karena Anda tidak ingin membuat notifikasi baru jika sudah ada notifikasi. Dengan begitu, Anda akan mengubah PendingIntent saat ini yang dikaitkan dengan maksud yang Anda berikan.
// NotificationUtils.kt
   // TODO: Step 1.12 create PendingIntent
    val contentPendingIntent = PendingIntent.getActivity(
        applicationContext, 
        NOTIFICATION_ID,
        contentIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
    )
  1. Teruskan PendingIntent ke notifikasi Anda. Anda dapat melakukannya dengan memanggil setContentIntent() di NotificationBuilder. Sekarang, saat Anda mengklik notifikasi, PendingIntent akan dipicu, sehingga membuka MainActivity Anda.
  2. Setel juga setAutoCancel() ke true, sehingga saat pengguna mengetuk notifikasi, notifikasi akan ditutup sendiri saat pengguna diarahkan ke aplikasi.
// NotificationUtils.kt
    // TODO: Step 1.13 set content intent
    .setContentIntent(contentPendingIntent)
    .setAutoCancel(true)
  1. Jalankan kembali aplikasi.
  2. Setel timer, letakkan aplikasi di latar belakang, dan tunggu hingga notifikasi muncul.
  3. Setelah melihat notifikasi, klik notifikasi dengan menarik status bar ke bawah, dan amati bagaimana aplikasi dibawa ke latar depan.

Langkah 5: Batalkan notifikasi

Anda memiliki timer telur yang berfungsi dengan notifikasi, tetapi ada sedikit masalah. Jika Anda menyetel timer, mendapatkan notifikasi, dan menyetel timer lagi, notifikasi sebelumnya akan tetap berada di status bar saat timer baru berjalan. Hal ini dapat membingungkan pengguna Anda jika aplikasi berada di latar belakang, dan dapat menyebabkan telur tidak matang.

Untuk memperbaikinya, Anda harus menghapus notifikasi sebelumnya saat memulai timer baru. Mulai dengan membuat fungsi ekstensi lain di NotificationUtils.kt. NotificationManager memiliki API untuk membatalkan semua notifikasi aktif yang disebut cancelAll().

  1. Buka NotificationsUtil.kt.
  2. Tambahkan fungsi ekstensi di NotificationManager yang memanggil cancelAll().
// NotificationUtils.kt

// TODO: Step 1.14 Cancel all notifications
/**
 * Cancels all notifications.
 *
 */
fun NotificationManager.cancelNotifications() {
    cancelAll()
}
  1. Buka EggTimerViewModel.kt dan buka fungsi startTimer().
  2. Di dalam startTimer(), Dapatkan instance NotificationManager dari sistem dan panggil cancelNotifications().
//  EggTimerViewModel.kt
   //TODO Step 1.15 call cancel notification
    val notificationManager =
       ContextCompat.getSystemService(
            app,
            NotificationManager::class.java
        ) as NotificationManager
    notificationManager.cancelNotifications()       
  1. Jalankan aplikasi dan mulai timer.
  2. Setelah melihat notifikasi, mulai ulang timer dan amati cara aplikasi kami menghapus notifikasi sebelumnya secara otomatis dari status bar.

Framework notifikasi memberikan berbagai opsi penyesuaian bagi developer untuk menetapkan tindakan kustom dan menata gaya notifikasi sesuai kebutuhan. Selama tugas ini, Anda akan mempelajari cara menyesuaikan notifikasi penghitung waktu telur.

Langkah 1: Atur gaya notifikasi Anda

Memberi gaya pada notifikasi sesuai kebutuhan dan konten notifikasi akan membuat notifikasi Anda terlihat lebih menonjol dan lebih seperti ekstensi aplikasi Anda. Framework notifikasi dilengkapi dengan beberapa gaya bawaan untuk membantu, dan Anda selalu dapat membuat gaya Anda sendiri.

NotificationCompat menawarkan gaya bawaan untuk:

  • BigTextStyle, yang dapat menampilkan blok teks besar, seperti menampilkan isi email saat diperluas.
  • BigPictureStyle, yang menampilkan notifikasi format besar yang menyertakan lampiran gambar besar.
  • InboxStyle, yang menampilkan konten teks gaya percakapan.
  • MediaStyle, yang menampilkan kontrol untuk pemutaran media.
  • MessagingStyle, yang menampilkan notifikasi format besar yang mencakup beberapa pesan antara sejumlah orang.

Anda dapat menemukan info selengkapnya tentang gaya lain dalam dokumentasi Membuat Notifikasi yang Dapat Diluaskan. Pada langkah ini, Anda akan menggunakan NotificationCompat.BigPictureStyle untuk membuat notifikasi yang dapat diperluas yang menampilkan gambar telur besar saat diperluas.

  1. Buka NotificationUtils.kt dan temukan fungsi sendNotification().
  2. Mulai dengan memuat gambar dari resources menggunakan BitmapFactory.
// NotificationUtils.kt

// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
     applicationContext.resources, 
     R.drawable.cooked_egg
)
  1. Buat BigPictureStyle baru dan tetapkan gambar Anda.
  2. Tetapkan bigLargeIcon() ke null agar ikon besar hilang saat notifikasi diperluas.
// NotificationUtils.kt

// TODO: Step 2.0 add style
val eggImage = BitmapFactory.decodeResource(
     applicationContext.resources, 
     R.drawable.cooked_egg
)
val bigPicStyle = NotificationCompat.BigPictureStyle()
        .bigPicture(eggImage)
        .bigLargeIcon(null)
  1. Tetapkan gaya dengan setStyle() ke bigPicStyle.
  2. Tetapkan ikon besar dengan setLargeIcon() ke eggImage, sehingga gambar akan ditampilkan sebagai ikon yang lebih kecil saat notifikasi diciutkan.
// NotificationUtils.kt
// TODO: Step 2.1 add style to builder
.setStyle(bigPicStyle)
.setLargeIcon(eggImage)
  1. Jalankan aplikasi dan setel timer. Saat pertama kali ditampilkan, notifikasi berada dalam status diciutkan di panel samping notifikasi. Jika Anda meluaskan notifikasi, gambar besar akan ditampilkan di area notifikasi yang diperluas.

Langkah 2: Tindakan notifikasi

Tindakan notifikasi adalah penyesuaian lain yang dapat Anda tambahkan ke notifikasi. Notifikasi Anda saat ini mengalihkan ke aplikasi Anda saat pengguna mengkliknya. Selain tindakan notifikasi default ini, Anda dapat menambahkan tombol tindakan yang menyelesaikan tugas terkait aplikasi dari notifikasi.

Notifikasi dapat menawarkan hingga tiga tombol tindakan yang memungkinkan pengguna merespons dengan cepat, seperti menunda pengingat atau membalas pesan teks. Tombol tindakan ini tidak boleh menduplikasi tindakan yang dilakukan saat pengguna mengetuk notifikasi.

Untuk menambahkan tombol tindakan, teruskan PendingIntent ke fungsi addAction() di builder. Cara ini mirip dengan menyiapkan tindakan ketuk default notifikasi dengan memanggil setContentIntent(), tetapi bukannya meluncurkan aktivitas, melainkan melakukan hal lain, misalnya, memulai BroadcastReceiver yang akan menjalankan tugas di latar belakang sehingga tindakan tersebut tidak mengganggu aplikasi yang sudah terbuka.

Dalam codelab ini, Anda sudah diberi BoadcastReceiver bernama SnoozeReceiver. Anda akan menggunakan SnoozeReceiver untuk menerima klik pengguna pada tindakan Notifikasi. Pada langkah-langkah berikut, Anda akan menambahkan kode untuk menunda notifikasi timer telur selama 60 detik saat pengguna mengklik tombol tindakan tunda. Saat tindakan tunda diklik, SnoozeReceiver akan menerima intent dan membuat alarm baru untuk mengirim notifikasi baru setelah 60 detik.

  1. Buka SnoozeReceiver.kt. Class ini mirip dengan AlarmReceiver yang Anda gunakan sebelumnya. Pada langkah-langkah berikut, Anda akan menambahkan kode yang akan memicu fungsi onReceive() dari SnoozeReceiver. Singkatnya, kode di SnoozeReceiver akan membuat alarm baru untuk mengirim notifikasi baru satu menit kemudian. Scroll ke bawah fungsi onReceive, dapatkan instance notificationManager dari sistem, lalu panggil cancelAll.
// SnoozeReceiver.kt
        val notificationManager = ContextCompat.getSystemService(
            context,
            NotificationManager::class.java
        ) as NotificationManager
        notificationManager.cancelAll()
  1. Untuk menggunakan SnoozeReceiver, buka NotificationUtils.kt.
  2. Buat Intent snoozeIntent baru untuk SnoozeReceiver tepat setelah gaya dalam fungsi sendNotification().
  3. Buat intent tertunda dengan memanggil metode getBroadcast() di PendingIntent yang mengharapkan parameter dalam langkah-langkah berikut. PendingIntent ini akan digunakan oleh sistem untuk menyiapkan alarm baru guna memposting notifikasi baru setelah 60 detik saat tombol tunda diketuk oleh pengguna.
  4. Parameter pertama adalah konteks aplikasi tempat PendingIntent ini harus memulai aktivitas.
  5. Parameter kedua adalah kode permintaan, yang merupakan kode permintaan untuk intent tertunda ini. Jika Anda perlu memperbarui atau membatalkan maksud tertunda ini, Anda harus menggunakan kode ini untuk mengakses maksud tertunda.
  6. Selanjutnya, tambahkan objek snoozeIntent, yang merupakan intent aktivitas yang akan diluncurkan.
  7. Terakhir, tambahkan nilai flag #FLAG_ONE_SHOT karena intent hanya akan digunakan satu kali. Tindakan cepat dan notifikasi akan hilang setelah ketukan pertama, sehingga maksud hanya dapat digunakan satu kali.
// NotificationUtils.kt

// TODO: Step 2.2 add snooze action
val snoozeIntent = Intent(applicationContext, SnoozeReceiver::class.java)
val snoozePendingIntent: PendingIntent = PendingIntent.getBroadcast(
    applicationContext, 
    REQUEST_CODE, 
    snoozeIntent, 
    FLAGS
)
  1. Selanjutnya, panggil fungsi addAction() di notificationBuilder. Fungsi ini memerlukan ikon dan teks untuk mendeskripsikan tindakan Anda kepada pengguna. Anda juga perlu menambahkan snoozeIntent. Intent ini akan digunakan untuk memicu boadcastReceiver yang tepat saat tindakan Anda diklik.
// NotificationUtils.kt
// TODO: Step 2.3 add snooze action
.addAction(
    R.drawable.egg_icon, 
    applicationContext.getString(R.string.snooze),
    snoozePendingIntent
)
  1. Jalankan aplikasi pengatur waktu telur untuk menguji tindakan tunda.
  2. Jalankan timer dan pindahkan aplikasi ke latar belakang. Setelah timer habis, perluas notifikasi dan Anda akan melihat bahwa notifikasi kini memiliki tombol tindakan tunda yang menunda timer telur selama satu menit lagi.

Langkah 3: Nilai penting notifikasi

Nilai penting menentukan seberapa mengganggu notifikasi bagi pengguna secara visual dan audio. Notifikasi dengan nilai penting yang lebih tinggi akan lebih mengganggu pengguna.

Anda harus menentukan tingkat kepentingan dalam konstruktor NotificationChannel. Anda awalnya menyetel kepentingan rendah untuk aplikasi timer telur. Anda dapat menggunakan salah satu dari lima tingkat kepentingan, mulai dari IMPORTANCE_NONE(0) hingga IMPORTANCE_HIGH(4). Tingkat kepentingan yang Anda tetapkan ke suatu saluran akan berlaku untuk semua pesan notifikasi yang Anda posting ke saluran tersebut.

Tingkat Kepentingan Channel

Tingkat kepentingan yang terlihat oleh pengguna

Tingkat kepentingan (Android 8.0 dan versi lebih tinggi)

Prioritas (Android 7.1 dan yang lebih rendah)

Berbunyi dan muncul sebagai notifikasi pendahuluan (muncul di bagian atas layar)

IMPORTANCE_HIGH

PRIORITY_HIGH / PRIORITY_MAX

Berbunyi

IMPORTANCE_DEFAULT

PRIORITY_DEFAULT

Tanpa suara

IMPORTANCE_LOW

PRIORITY_LOW

Tidak ada bunyi dan tidak muncul di status bar.

IMPORTANCE_MIN

PRIORITY_MIN

Untuk mengetahui informasi tentang pemilihan tingkat prioritas yang sesuai, lihat "Tingkat prioritas" dalam Panduan desain notifikasi. Anda harus berhati-hati saat memilih tingkat kepentingan untuk notifikasi di aplikasi Anda. Tingkat kepentingan saluran harus dipilih dengan mempertimbangkan waktu dan perhatian pengguna. Jika notifikasi yang tidak penting disamarkan sebagai notifikasi mendesak, hal ini dapat menimbulkan kekhawatiran yang tidak perlu dan mengganggu. Pengguna memiliki kontrol penuh atas tingkat kepentingan notifikasi mereka, jadi jika Anda membuat notifikasi yang mengganggu, mereka dapat menonaktifkan saluran notifikasi Anda sepenuhnya.

Saat Anda pertama kali membuat notifikasi di Langkah 1.6, timer telur disetel untuk mengirim notifikasi dengan prioritas rendah karena dirancang agar tidak mengganggu pengguna dengan notifikasi. Namun, sebaiknya tarik perhatian pengguna sebelum telur matang terlalu lama. Untuk mengubah tingkat kepentingan notifikasi, mulai dengan setelan saluran. Tingkat kepentingan saluran memengaruhi tingkat gangguan semua notifikasi yang diposting di saluran, dan harus ditentukan dalam konstruktor NotificationChannel.

  1. Untuk mengubah tingkat kepentingan saluran notifikasi aplikasi Anda, buka EggTimerFragment.kt dan buka createChannel(). Ubah tingkat kepentingan dari IMPORTANCE_LOW menjadi IMPORTANCE_HIGH.
// EggTimerFragment.kt
    val notificationChannel = NotificationChannel(
        channelId,
        channelName,
        // TODO: Step 2.4 change importance
        NotificationManager.IMPORTANCE_HIGH
    )

Untuk mendukung perangkat yang menjalankan Android 7.1 (level API 25) atau yang lebih rendah, Anda juga harus memanggil setPriority() untuk setiap notifikasi, menggunakan konstanta prioritas dari class NotificationCompat.

  1. Buka NotificationUtils.kt dan tambahkan kode berikut ke objek pembuat notifikasi.
// NotificationUtils.kt
   .addAction(
       R.drawable.common_google_signin_btn_icon_dark,
       applicationContext.getString(R.string.snooze),
       snoozePendingIntent
    )
   // TODO: Step 2.5 set priority
    .setPriority(NotificationCompat.PRIORITY_HIGH)
  1. Sebelum menjalankan aplikasi, klik lama ikon aplikasi di perangkat atau emulator Anda, lalu pilih uninstal untuk menghapus setelan saluran sebelumnya. Jika Anda gagal meng-uninstal aplikasi, setelan prioritas saluran tidak akan berubah, dan hal ini tidak akan menyebabkan perubahan perilaku saat notifikasi diposting.
  2. Sekarang jalankan aplikasi lagi dan mulai timer. Kali ini, saat notifikasi dikirimkan, Anda akan melihat pop-up muncul di bagian atas layar, terlepas dari apakah aplikasi Anda berjalan di latar depan atau latar belakang.

Langkah 4: Badge notifikasi

Badge notifikasi adalah titik kecil yang muncul pada ikon peluncur aplikasi terkait saat aplikasi memiliki notifikasi aktif. Pengguna dapat menekan lama ikon aplikasi untuk membuka notifikasi.

Titik-titik ini, yang disebut badge, muncul secara default, dan tidak ada yang perlu dilakukan aplikasi Anda. Namun, mungkin ada situasi di mana badge tidak relevan untuk notifikasi, jadi Anda dapat menonaktifkannya pada basis per saluran dengan memanggil setShowBadge(false) pada objek NotificationChannel Anda. Karena timer telur hanya memiliki satu notifikasi aktif dalam waktu tertentu, badge pada ikon aplikasi Anda tidak memberikan banyak manfaat bagi pengguna. Pada langkah-langkah berikut, Anda akan menonaktifkan badge dan hanya menampilkan notifikasi untuk timer telur.

  1. Tambahkan setShowBadge(false) ke kode pembuatan saluran untuk timer telur guna menonaktifkan badge.
// EggTimerFragment.kt

    ).apply {
        // TODO: Step 2.6 disable badges for this channel
        setShowBadge(false)
    }
  1. Jalankan aplikasi lagi, mulai timer, dan perhatikan ikon aplikasi. Anda tidak akan melihat badge apa pun di ikon aplikasi.

Kode solusi ada di cabang utama kode yang Anda download.

Kursus Udacity:

Dokumentasi developer Android:

Untuk mengetahui link ke codelab lain dalam kursus ini, lihat halaman landing codelab Android Lanjutan di Kotlin.