Aplikasi yang selalu aktif dan mode standby sistem

Panduan ini menjelaskan cara membuat aplikasi Anda selalu aktif, cara bereaksi terhadap transisi status daya, dan cara mengelola perilaku aplikasi untuk memberikan pengalaman pengguna yang baik sekaligus menghemat baterai.

Membuat aplikasi terus terlihat akan berdampak signifikan pada masa pakai baterai, jadi pertimbangkan dampak daya saat menambahkan fitur ini.

Konsep Utama

Saat aplikasi Wear OS ditampilkan di layar penuh, aplikasi tersebut berada dalam salah satu dari dua status daya:

  • Interaktif: Status daya tinggi saat layar berada pada kecerahan penuh, sehingga memungkinkan interaksi pengguna penuh.
  • Standby: Status daya rendah saat layar diredupkan untuk menghemat daya. Dalam status ini, UI aplikasi Anda masih menempati layar penuh, tetapi sistem mungkin mengubah tampilannya dengan memburamkannya atau menempatkan konten seperti waktu. Hal ini juga disebut sebagai Mode Standby.

Sistem operasi mengontrol transisi antar-status ini.

Aplikasi Selalu Aktif adalah aplikasi yang menampilkan konten dalam status Interaktif dan Standby.

Jika aplikasi always-on terus menampilkan UI-nya sendiri saat perangkat berada dalam status Standby daya rendah, aplikasi tersebut dijelaskan sebagai berada dalam mode ambiaktif.

Transisi sistem dan perilaku default

Saat aplikasi berada di latar depan, sistem akan mengelola transisi status daya berdasarkan dua waktu tunggu yang dipicu oleh ketidakaktifan pengguna.

  • Waktu tunggu #1: Status Interaktif ke Standby: Setelah periode tidak ada aktivitas pengguna, perangkat akan memasuki status Standby.
  • Waktu tunggu #2: Kembali ke tampilan jam: Setelah periode tidak aktif lebih lanjut, sistem dapat menyembunyikan aplikasi saat ini dan menampilkan tampilan jam.

Segera setelah sistem melewati transisi pertama ke status Ambient, perilaku default bergantung pada versi Wear OS dan konfigurasi aplikasi Anda:

  • Di Wear OS 5 dan yang lebih lama, sistem akan menampilkan screenshot buram dari aplikasi yang dijeda, dengan waktu yang ditumpangkan di atasnya.
  • Di Wear OS 6 dan yang lebih baru, jika aplikasi menargetkan SDK 36 atau yang lebih baru, aplikasi tersebut dianggap selalu aktif. Layar meredup, tetapi aplikasi terus berjalan dan tetap terlihat. (Pembaruan mungkin jarang dilakukan, yaitu sekali per menit.)

Menyesuaikan perilaku untuk status Standby

Terlepas dari perilaku sistem default, di semua versi Wear OS, Anda dapat menyesuaikan tampilan atau perilaku aplikasi saat dalam status Ambient dengan menggunakan AmbientLifecycleObserver untuk memproses callback pada transisi status.

Menggunakan AmbientLifecycleObserver

Untuk bereaksi terhadap peristiwa mode pencahayaan sinematik, gunakan class AmbientLifecycleObserver:

  1. Terapkan antarmuka AmbientLifecycleObserver.AmbientLifecycleCallback. Gunakan metode onEnterAmbient() untuk menyesuaikan UI Anda untuk status daya rendah, dan onExitAmbient() untuk memulihkannya ke layar interaktif penuh.

    val ambientCallback = object : AmbientLifecycleObserver.AmbientLifecycleCallback {
        override fun onEnterAmbient(ambientDetails: AmbientLifecycleObserver.AmbientDetails) {
            // ... Called when moving from interactive mode into ambient mode.
            // Adjust UI for low-power state: dim colors, hide non-essential elements.
        }
    
        override fun onExitAmbient() {
            // ... Called when leaving ambient mode, back into interactive mode.
            // Restore full UI.
        }
    
        override fun onUpdateAmbient() {
            // ... Called by the system periodically (typically once per minute)
            // to allow the app to update its display while in ambient mode.
        }
    }
    
  2. Buat AmbientLifecycleObserver dan daftarkan dengan siklus proses aktivitas atau composable Anda.

    private val ambientObserver = AmbientLifecycleObserver(activity, ambientCallback)
    
    override fun onCreate(savedInstanceState: Bundle) {
        super.onCreate(savedInstanceState)
        lifecycle.addObserver(ambientObserver)
    
        // ...
    }
    
  3. Panggil removeObserver() untuk menghapus observer di onDestroy().

Untuk developer yang menggunakan Jetpack Compose, library Horologist menyediakan utilitas yang berguna, composable AmbientAware, yang menyederhanakan penerapan pola ini.

TimeText yang peka terhadap kondisi sekitar

Sebagai pengecualian untuk mewajibkan observer kustom, di Wear OS 6, widget TimeText bersifat aware standby. Status ini otomatis diperbarui sekali per menit saat perangkat berada dalam status Ambient tanpa kode tambahan.

Mengontrol durasi layar menyala

Bagian berikut menjelaskan cara mengelola durasi aplikasi Anda berada di layar.

Mencegah kembali ke tampilan jam dengan Aktivitas yang Sedang Berlangsung

Setelah jangka waktu tertentu dalam status Standby (Waktu tunggu #2), sistem biasanya akan kembali ke tampilan jam. Pengguna dapat mengonfigurasi durasi waktu tunggu di setelan sistem. Untuk kasus penggunaan tertentu, seperti pengguna yang melacak olahraga, aplikasi mungkin perlu tetap terlihat untuk waktu yang lebih lama.

Di Wear OS 5 dan yang lebih baru, Anda dapat mencegah hal ini dengan menerapkan Aktivitas Berkelanjutan. Jika aplikasi menampilkan informasi tentang tugas pengguna yang sedang berlangsung, seperti sesi olahraga, Anda dapat menggunakan Ongoing Activity API agar aplikasi tetap terlihat hingga tugas berakhir. Jika pengguna kembali ke tampilan jam secara manual, indikator aktivitas yang sedang berlangsung akan memberikan cara sekali ketuk bagi mereka untuk kembali ke aplikasi Anda

Untuk menerapkannya, intent sentuh notifikasi yang sedang berlangsung harus mengarah ke aktivitas yang selalu aktif, seperti yang ditunjukkan dalam cuplikan kode berikut:

private fun createNotification(): Notification {
    val activityIntent =
        Intent(this, AlwaysOnActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
        }

    val pendingIntent =
        PendingIntent.getActivity(
            this,
            0,
            activityIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
        )

    val notificationBuilder =
        NotificationCompat.Builder(this, CHANNEL_ID)
            // ...
            // ...
            .setOngoing(true)

    // ...

    val ongoingActivity =
        OngoingActivity.Builder(applicationContext, NOTIFICATION_ID, notificationBuilder)
            // ...
            // ...
            .setTouchIntent(pendingIntent)
            .build()

    ongoingActivity.apply(applicationContext)

    return notificationBuilder.build()
}

Menjaga layar tetap menyala dan mencegah status Standby

Dalam kasus yang jarang terjadi, Anda mungkin perlu sepenuhnya mencegah perangkat memasuki status Standby. Artinya, untuk menghindari Timeout #1. Untuk melakukannya, Anda dapat menggunakan flag jendela FLAG_KEEP_SCREEN_ON. Fungsi ini berfungsi sebagai kunci layar aktif, yang mempertahankan perangkat dalam status Interaktif. Gunakan fitur ini dengan sangat hati-hati karena sangat memengaruhi masa pakai baterai.

Rekomendasi untuk Mode pencahayaan sinematik

Untuk memberikan pengalaman pengguna terbaik dan menghemat daya dalam mode Standby, ikuti panduan desain ini.

  • Menggunakan layar minimalis dengan daya rendah
    • Biarkan setidaknya 85% layar tetap hitam.
    • Gunakan garis batas untuk ikon atau tombol besar, bukan isian solid.
    • Hanya tampilkan informasi yang paling penting, dengan memindahkan detail sekunder ke layar interaktif.
    • Hindari blok besar warna solid dan branding atau gambar latar belakang yang tidak berfungsi.
  • Memastikan konten diperbarui dengan tepat
    • Untuk data yang sering berubah seperti stopwatch, jarak olahraga, atau waktu, tampilkan konten placeholder seperti -- untuk menghindari kesan bahwa konten tersebut baru.
    • Hapus indikator progres yang terus diperbarui, seperti untuk dering hitung mundur dan sesi media.
    • Callback onUpdateAmbient() hanya boleh digunakan untuk update penting, biasanya sekali per menit.
  • Mempertahankan tata letak yang konsisten
    • Pastikan elemen berada di posisi yang sama di seluruh mode Interaktif dan Standby untuk menciptakan transisi yang lancar.
    • Selalu tampilkan waktu.
  • Pahami konteks
    • Jika pengguna berada di layar setelan atau konfigurasi saat perangkat memasuki mode standby, pertimbangkan untuk menampilkan layar yang lebih relevan dari aplikasi Anda, bukan tampilan setelan.
  • Menangani persyaratan khusus perangkat
    • Dalam objek AmbientDetails yang diteruskan ke onEnterAmbient():
      • Jika deviceHasLowBitAmbient adalah true, nonaktifkan anti-aliasing jika memungkinkan.
      • Jika burnInProtectionRequired adalah true, geser elemen UI secara berkala dan hindari area putih yang menyala terus untuk mencegah burn-in layar.

Proses debug dan pengujian

Perintah adb ini mungkin berguna saat mengembangkan atau menguji perilaku aplikasi Anda saat perangkat dalam mode standby:

# put device in ambient mode if the always on display is enabled in settings
# (and not disabled by other settings, such as theatre mode)
$ adb shell input keyevent KEYCODE_SLEEP

# put device in interactive mode
$ adb shell input keyevent KEYCODE_WAKEUP

Contoh: Aplikasi olahraga

Pertimbangkan aplikasi olahraga yang perlu menampilkan metrik kepada pengguna selama seluruh durasi sesi olahraga mereka. Aplikasi harus tetap terlihat melalui transisi status Standby dan tidak diganti oleh tampilan jam.

Untuk melakukannya, developer harus melakukan hal berikut:

  1. Terapkan AmbientLifecycleObserver untuk menangani perubahan UI antara status Interaktif dan Standby, seperti meredupkan layar dan menghapus data yang tidak penting.
  2. Buat tata letak baru dengan daya rendah untuk status Standby yang mengikuti praktik terbaik.
  3. Gunakan Ongoing Activity API selama durasi olahraga untuk mencegah sistem kembali ke tampilan jam.

Untuk implementasi lengkap, lihat Contoh latihan berbasis compose di GitHub. Contoh ini juga menunjukkan penggunaan composable AmbientAware dari library Horologist untuk menyederhanakan penanganan mode standby di Compose.