Aktivitas yang Sedang Berlangsung

Di Wear OS, penyambungan aktivitas yang sedang berlangsung dengan notifikasi yang sedang berlangsung akan menambahkan notifikasi tersebut ke platform tambahan dalam antarmuka pengguna Wear OS. Hal ini memungkinkan pengguna untuk lebih intens berinteraksi dengan aktivitas yang berjalan lama.

Notifikasi yang sedang berlangsung biasanya digunakan untuk menunjukkan bahwa notifikasi memiliki tugas latar belakang yang secara aktif dijalankan pengguna atau tertunda dengan cara tertentu sehingga memenuhi perangkat.

Misalnya, pengguna Wear OS mungkin menggunakan aplikasi olahraga untuk merekam lari dari suatu aktivitas, lalu keluar dari aplikasi tersebut untuk memulai beberapa tugas lain. Saat pengguna keluar dari aplikasi olahraga, aplikasi biasanya akan beralih ke notifikasi yang sedang berlangsung yang terikat dengan beberapa tugas latar belakang (misalnya layanan atau pengelola alarm) untuk terus memberi tahu pengguna selama berlari. Notifikasi ini menyediakan update dan cara mudah untuk mengakses kembali aplikasi kepada pengguna.

Namun, untuk melihat notifikasi, pengguna harus menggeser ke dalam baki notifikasi di bawah tampilan jam dan menemukan notifikasi yang tepat. Cara ini tidak senyaman platform lainnya.

Dengan Ongoing Activity API, notifikasi aplikasi yang sedang berlangsung dapat menampilkan informasi ke beberapa platform baru yang nyaman di Wear OS agar pengguna tetap berinteraksi.

Misalnya, dalam aplikasi olahraga ini, informasi dapat muncul di tampilan jam pengguna sebagai ikon lari yang dapat diketuk:

ikon lari

Gambar 1. Indikator aktivitas

Bagian Terbaru pada peluncur aplikasi global juga mencantumkan aktivitas yang sedang berlangsung:

peluncur

Gambar 2. Peluncur global

Berikut ini adalah situasi yang tepat untuk menggunakan notifikasi yang sedang berlangsung yang terikat dengan aktivitas yang sedang berlangsung:

timer

Gambar 3. Timer: Aktif menghitung waktu mundur, dan berakhir saat timer dijeda/dihentikan.

peta

Gambar 4. Navigasi belokan demi belokan Menginformasikan rute ke tujuan. Berakhir saat pengguna mencapai tujuan atau menghentikan navigasi.

musik

Gambar 5. Media: Memutar musik sepanjang sesi. Berakhir seketika setelah pengguna menjeda sesi.

Wear akan otomatis membuat aktivitas yang sedang berlangsung untuk aplikasi Media. Lihat codelab Aktivitas yang Sedang Berlangsung di GitHub untuk mengetahui contoh detail cara membuat aktivitas yang sedang berlangsung untuk jenis aplikasi lain.

Penyiapan

Untuk mulai menggunakan Ongoing Activity API di aplikasi, tambahkan dependensi berikut ke file build.gradle aplikasi:

dependencies {
  implementation "androidx.wear:wear-ongoing:1.0.0"
  // Includes LocusIdCompat and new Notification categories for Ongoing Activity.
  implementation "androidx.core:core:1.6.0"
}

Memulai aktivitas yang sedang berlangsung

Mulai dengan aktivitas yang sedang berlangsung.

Notifikasi yang sedang berlangsung

Seperti yang disebutkan sebelumnya, Aktivitas yang sedang berlangsung terkait erat dengan Notifikasi yang Sedang Berlangsung.

Keduanya bekerja sama untuk memberi tahu pengguna tentang tugas yang secara aktif dijalankan pengguna, atau tertunda dengan cara tertentu sehingga memenuhi perangkat.

Anda harus menyambungkan aktivitas yang sedang berlangsung dengan notifikasi yang sedang berlangsung.

Ada banyak manfaat dengan menautkan aktivitas yang sedang berlangsung ke notifikasi, termasuk hal berikut ini:

  • Notifikasi berfungsi sebagai pengganti di perangkat yang tidak mendukung aktivitas yang sedang berlangsung. Notifikasi adalah satu-satunya platform yang akan ditampilkan aplikasi saat berjalan di latar belakang.
  • Pada Android 11 dan versi lebih tinggi, Wear OS akan menyembunyikan notifikasi dalam baki notifikasi jika aplikasi terlihat sebagai aktivitas yang sedang berlangsung di platform tambahan.
  • Implementasi saat ini menggunakan Notification itu sendiri sebagai mekanisme komunikasi.

Aktivitas yang Sedang Berlangsung

Sangat mudah untuk memulai aktivitas yang sedang berlangsung setelah Anda mendapatkan notifikasi yang sedang berlangsung.

Contoh kode berikut berisi komentar untuk membantu Anda memahami arti setiap properti:

Kotlin

var builder = NotificationCompat.Builder(this, CHANNEL_ID)
      …
      .setSmallIcon(..)
      .setOngoing(true)

val ongoingActivityStatus = Status.Builder()
    // Sets the text used across various surfaces.
    .addTemplate(mainText)
    .build()

val ongoingActivity =
    OngoingActivity.Builder(
        applicationContext, NOTIFICATION_ID, notificationBuilder
    )
        // Sets the animated icon that will appear on the watch face in
        // active mode.
        // If it isn't set, the watch face will use the static icon in
        // active mode.
        .setAnimatedIcon(R.drawable.ic_walk)
        // Sets the icon that will appear on the watch face in ambient mode.
        // Falls back to Notification's smallIcon if not set.
        // If neither is set, an Exception is thrown.
        .setStaticIcon(R.drawable.ic_walk)
        // Sets the tap/touch event, so users can re-enter your app from the
        // other surfaces.
        // Falls back to Notification's contentIntent if not set.
        // If neither is set, an Exception is thrown.
        .setTouchIntent(activityPendingIntent)
        // In our case, sets the text used for the Ongoing Activity (more
        // options are available for timers and stopwatches).
        .setStatus(ongoingActivityStatus)
        .build()

ongoingActivity.apply(applicationContext)

notificationManager.notify(NOTIFICATION_ID, builder.build())

Java

NotificationCompat.Builder builder = NotificationCompat.Builder(this, CHANNEL_ID)
      …
      .setSmallIcon(..)
      .setOngoing(true);

OngoingActivityStatus ongoingActivityStatus = OngoingActivityStatus.Builder()
    // Sets the text used across various surfaces.
    .addTemplate(mainText)
    .build();

OngoingActivity ongoingActivity =
    OngoingActivity.Builder(
        applicationContext, NOTIFICATION_ID, notificationBuilder
    )
        // Sets the animated icon that will appear on the watch face in
        // active mode.
        // If it isn't set, the watch face will use the static icon in
        // active mode.
        .setAnimatedIcon(R.drawable.ic_walk)
        // Sets the icon that will appear on the watch face in ambient mode.
        // Falls back to Notification's smallIcon if not set.
        // If neither is set, an Exception is thrown.
        .setStaticIcon(R.drawable.ic_walk)
        // Sets the tap/touch event, so users can re-enter your app from the
        // other surfaces.
        // Falls back to Notification's contentIntent if not set.
        // If neither is set, an Exception is thrown.
        .setTouchIntent(activityPendingIntent)
        // In our case, sets the text used for the Ongoing Activity (more
        // options are available for timers and stopwatches).
        .setStatus(ongoingActivityStatus)
        .build();

ongoingActivity.apply(applicationContext);

notificationManager.notify(NOTIFICATION_ID, builder.build());

Langkah-langkah berikut akan memanggil bagian yang paling penting dari contoh sebelumnya:

  1. Panggil .setOngoing(true) pada NotificationCompat.Builder lalu tetapkan kolom opsional.

  2. Buat OngoingActivityStatus untuk merepresentasikan teks. (Opsi status lainnya akan dibahas di bagian berikutnya.)

  3. Buat OngoingActivity, lalu tetapkan ID notifikasi (wajib).

  4. Panggil apply() di OngoingActivity dengan konteks.

  5. Panggil notificationManager.notify(), lalu teruskan ID notifikasi yang sama dengan aktivitas yang sedang berlangsung untuk mengikatnya menjadi satu.

Status

Status memungkinkan developer menampilkan status aktif OngoingActivity saat ini kepada pengguna di platform baru, seperti bagian Terbaru peluncur. Untuk menggunakan fitur ini, gunakan Status.Builder.

Pada umumnya, developer hanya perlu menambahkan template yang mewakili teks yang ingin ditampilkan di bagian Terbaru peluncur aplikasi.

Developer dapat menyesuaikan tampilan teks dengan Span menggunakan metode addTemplate() dan menentukan setiap bagian dinamis teks sebagai Status.Part

Contoh berikut menunjukkan cara membuat kata "waktu" muncul dalam warna merah. Contoh ini menggunakan Status.TimerPart yang memungkinkan kita merepresentasikan timer atau Status.StopwatchPart untuk mewakili stopwatch di bagian Terbaru peluncur aplikasi.

Kotlin

val htmlStatus =
        "<p>The <font color=\"red\">time</font> on your current #type# is #time#.</p>"

val statusTemplate =
        Html.fromHtml(
                htmlStatus,
                Html.FROM_HTML_MODE_COMPACT
        )

// Creates a 5 minute timer.
// Note the use of SystemClock.elapsedRealtime(), not System.currentTimeMillis()
val runStartTime = SystemClock.elapsedRealtime() + TimeUnit.MINUTES.toMillis(5)

val status = new Status.Builder()
   .addTemplate(statusTemplate)
   .addPart("type", Status.TextPart("run"))
   .addPart("time", Status.StopwatchPart(runStartTime)
   .build()

Java

String htmlStatus =
        "<p>The <font color=\"red\">time</font> on your current #type# is #time#.</p>";

Spanned statusTemplate =
        Html.fromHtml(
                htmlStatus,
                Html.FROM_HTML_MODE_COMPACT
        );

// Creates a 5 minute timer.
// Note the use of SystemClock.elapsedRealtime(), not System.currentTimeMillis()
Long runStartTime = SystemClock.elapsedRealtime() + TimeUnit.MINUTES.toMillis(5);

Status status = new Status.Builder()
   .addTemplate(statusTemplate)
   .addPart("type", new Status.TextPart("run"))
   .addPart("time", new Status.StopwatchPart(runStartTime)
   .build();

Untuk mereferensikan bagian dari template, gunakan nama yang diapit oleh '#'. Untuk membuat '#' dalam output, gunakan '##' di template.

Contoh sebelumnya menggunakan HTMLCompat untuk menghasilkan CharSequence yang akan diteruskan ke template, dan cara ini lebih mudah daripada menentukan objek Spannable secara manual.

Penyesuaian tambahan

Selain Status, developer dapat menyesuaikan aktivitas atau notifikasi yang sedang berlangsung dengan cara berikut. Penyesuaian ini mungkin digunakan atau tidak digunakan berdasarkan penerapan OEM.

Notifikasi yang Sedang Berlangsung

  • Kumpulan kategori menentukan prioritas aktivitas yang sedang berlangsung.
    • CATEGORY_CALL: Panggilan masuk (suara atau video) atau permintaan komunikasi sinkron yang serupa
    • CATEGORY_NAVIGATION: Peta atau navigasi belokan demi belokan.
    • CATEGORY_TRANSPORT: Kontrol transport media untuk pemutaran
    • CATEGORY_ALARM: Alarm atau timer
    • CATEGORY_WORKOUT: Olahraga (baru)
    • CATEGORY_LOCATION_SHARING: Berbagi lokasi sementara (baru)
    • CATEGORY_STOPWATCH: Stopwatch (baru) \

Aktivitas yang Sedang Berlangsung

  • Ikon Animasi: Vektor hitam putih, sebaiknya dengan latar belakang transparan. Ditampilkan di tampilan jam selama mode aktif. Jika tidak diberikan, ikon notifikasi default akan digunakan.

  • Ikon statis: Ikon vektor dengan latar belakang transparan. Ditampilkan di tampilan jam dalam mode standby. Jika ikon animasi tidak disetel, ikon statis akan digunakan pada tampilan jam untuk mode aktif. Jika tidak disediakan, ikon notifikasi akan digunakan. Jika keduanya tidak ditetapkan, pengecualian akan ditampilkan. (Ikon yang digunakan pada peluncur aplikasi akan tetap menggunakan ikon aplikasi.)

  • OngoingActivityStatus: Teks biasa atau Chronometer. Ditampilkan di bagian Terbaru dari peluncur aplikasi. Jika tidak disediakan, notifikasi “teks konteks” akan digunakan.

  • Intent Sentuh: PendingIntent yang digunakan untuk beralih kembali ke aplikasi jika pengguna mengetuk ikon aktivitas yang sedang berlangsung. Ditampilkan di tampilan jam atau di item peluncur. Mungkin berbeda dengan intent asli yang digunakan untuk meluncurkan aplikasi. Jika tidak disediakan, intent konten notifikasi akan digunakan, jika tidak ada yang ditetapkan, pengecualian akan ditampilkan. \

  • LocusId: ID yang menetapkan pintasan peluncur yang terkait dengan aktivitas yang sedang berlangsung. Ditampilkan pada peluncur di bagian Terbaru saat aktivitas sedang berlangsung. Jika tidak disediakan, peluncur akan menyembunyikan semua item aplikasi di bagian Terbaru dari paket yang sama dan hanya menampilkan aktivitas yang sedang berlangsung. \

  • ID Aktivitas yang Sedang Berlangsung, ID yang digunakan untuk membedakan panggilan ke fromExistingOngoingActivityfromExistingOngoingActivity() jika aplikasi memiliki lebih dari satu aktivitas yang sedang berlangsung.

Mengupdate aktivitas yang sedang berlangsung

Pada umumnya, developer akan membuat notifikasi yang sedang berlangsung dan aktivitas yang sedang berlangsung yang baru jika mereka perlu mengupdate data di layar. Namun, Ongoing Activity API juga menawarkan metode pembantu untuk mengupdate OngoingActivity jika Anda ingin mempertahankan instance, bukan membuatnya kembali.

Jika berjalan di latar belakang, aplikasi dapat mengirimkan update ke Ongoing Activity API, tetapi hal ini jarang terjadi. Metode update mungkin akan mengabaikan panggilan yang terlalu berdekatan satu sama lain. Beberapa update per menit adalah hal wajar.

Untuk mengupdate aktivitas yang sedang berlangsung dan notifikasi yang diposting, gunakan objek yang Anda buat sebelumnya, lalu panggil update() seperti yang ditunjukkan dalam contoh berikut:

Kotlin

ongoingActivity.update(context, newStatus)

Java

ongoingActivity.update(context, newStatus);

Untuk memudahkan, ada metode statis untuk membuat aktivitas yang sedang berlangsung.

Kotlin

OngoingActivity.recoverOngoingActivity(context)
               .update(context, newStatus)

Java

OngoingActivity.recoverOngoingActivity(context)
               .update(context, newStatus);

Menghentikan aktivitas yang sedang berlangsung

Setelah selesai berjalan sebagai aktivitas yang sedang berlangsung, aplikasi hanya perlu membatalkan notifikasi yang sedang berlangsung.

Aplikasi dapat memilih untuk membatalkan notifikasi atau aktivitas yang sedang berlangsung saat aplikasi itu masuk ke latar depan, lalu membuatnya kembali saat kembali ke latar belakang.

Menjeda aktivitas yang sedang berlangsung

Jika aplikasi Anda memiliki tindakan berhenti yang eksplisit, lanjutkan aktivitas yang sedang berlangsung setelah dilanjutkan. Namun, aplikasi tanpa tindakan berhenti yang eksplisit harus mengakhiri aktivitas saat dijeda.

Praktik terbaik

Perhatikan hal-hal berikut saat menggunakan Ongoing Activity API:

  • Selalu panggil ongoingActivity.apply(context) sebelum memanggil notificationManager.notify(...).
  • Selalu tetapkan ikon statis untuk Aktivitas yang Sedang Berlangsung secara eksplisit atau sebagai pengganti melalui notifikasi. Jika tidak, Anda akan mendapatkan IllegalArgumentException.

  • Ikon harus berupa vektor hitam dan putih dengan latar belakang transparan.

  • Selalu tetapkan intent sentuh untuk aktivitas yang sedang berlangsung secara eksplisit atau sebagai fallback menggunakan notifikasi. Jika tidak, Anda akan menerima IllegalArgumentException.

  • Untuk NotificationCompat, gunakan library androidx inti core:1.5.0-alpha05+ yang menyertakan LocusIdCompat dan kategori baru (olahraga, stopwatch, atau berbagi lokasi).

  • Jika aplikasi Anda memiliki lebih dari satu aktivitas MAIN LAUNCHER yang dideklarasikan dalam manifes, publikasikan pintasan dinamis dan kaitkan dengan aktivitas yang sedang berlangsung menggunakan LocusId.