Membuat aplikasi Anda tetap terlihat di Wear

Beberapa aplikasi Wear OS terlihat terus-menerus oleh pengguna.

Perangkat Wear OS yang menjalankan Android versi 5.1 atau lebih tinggi memungkinkan aplikasi tetap berjalan di latar depan dengan tetap menghemat daya baterai. Aplikasi Wear OS dapat mengontrol apa yang ditampilkan di jam tangan selagi berada dalam mode rendah daya (standby). Aplikasi Wear yang berjalan baik dalam mode standby maupun interaktif disebut aplikasi always-on.

Dengan aplikasi semacam ini, pengguna yang melakukan jogging dapat melihat sekilas jam tangan mereka dan mengetahui jarak yang ditempuh serta waktu yang telah berlalu. Beberapa pengguna mencatat daftar belanja dan dapat melihat dengan cepat item dalam daftar saat berbelanja.

Membuat aplikasi yang terus terlihat akan berdampak pada masa pakai baterai, jadi Anda harus mempertimbangkan dengan cermat dampak tersebut saat menambahkan fitur ini ke aplikasi Anda.

Penting: Android Support Library versi 27.1.0 menyediakan cara baru untuk mendukung mode standby yang menggunakan class AmbientModeSupport, bukan class WearableActivity. Anda dapat menentukan apakah Anda ingin menggunakan cara baru yang lebih disukai untuk mendukung mode standby atau memperluas class WearableActivity.

Catatan: Class AmbientMode tidak digunakan lagi dan diganti dengan class AmbientModeSupport.

Lihat referensi terkait berikut ini:

Mengonfigurasi project Anda

Untuk mendukung mode standby, Anda harus mengupdate Android SDK dan mengonfigurasi project pengembangan Anda. Ikuti langkah-langkah berikut untuk membuat perubahan yang diperlukan:

  1. Buat atau update project Anda berdasarkan konfigurasi pada halaman Membuat dan Menjalankan Aplikasi Wearable.
  2. Tambahkan izin WAKE_LOCK ke file Manifes Android:
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    

Mode standby menggunakan class AmbientModeSupport

Penggunaan class AmbientModeSupport untuk mendukung mode standby memungkinkan Anda mendapat manfaat dari:

Untuk menggunakan class AmbientModeSupport, perluas salah satu subclass FragmentActivity atau FragmentActivity itu sendiri dan implementasikan antarmuka penyedia, yang selanjutnya dapat digunakan untuk mendeteksi update mode standby.

Catatan: Metode AmbientModeSupport.attach(FragmentActivity) menambahkan fragmen headless ke class FragmentActivity atau subclass yang Anda sediakan, dan panggilan selanjutnya ke FragmentManager.getFragments() akan menampilkan referensi ke fragmen ini (yang tidak dimaksudkan untuk digunakan dengan cara apa pun).

Berikut ini menjelaskan penggunaan umum class AmbientModeSupport:

  1. Buat subclass dari salah satu class FragmentActivity.
  2. Implementasikan antarmuka AmbientCallbackProvider, seperti pada contoh di bawah. Ganti metode getAmbientCallback() guna menyediakan callback yang diperlukan untuk bereaksi terhadap peristiwa standby dari sistem Android. Pada Langkah 4, kita akan membuat class callback kustom.

    Kotlin

        class MainActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider {
            …
            override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback = MyAmbientCallback()
            …
        }
        

    Java

        public class MainActivity extends AppCompatActivity implements AmbientModeSupport.AmbientCallbackProvider {
            …
            @Override
            public AmbientModeSupport.AmbientCallback getAmbientCallback() {
                return new MyAmbientCallback();
            }
            …
        }
        
  3. Dalam metode onCreate(), aktifkan mode Standby dengan memanggil AmbientModeSupport.attach(FragmentActivity). Metode ini menampilkan AmbientModeSupport.AmbientController. Pengontrol ini memungkinkan Anda untuk memeriksa status standby di luar callback; Anda mungkin perlu mempertahankan referensi ke objek AmbientModeSupport.AmbientController:

    Kotlin

        class MainActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider {
            ...
            /*
             * Declare an ambient mode controller, which will be used by
             * the activity to determine if the current mode is ambient.
             */
            private lateinit var ambientController: AmbientModeSupport.AmbientController
            ...
            override fun onCreate(savedInstanceState: Bundle?) {
                super.onCreate(savedInstanceState)
                setContentView(R.layout.activity_main)
                ...
                ambientController = AmbientModeSupport.attach(this)
            }
            ...
        }
        

    Java

        public class MainActivity extends AppCompatActivity implements AmbientModeSupport.AmbientCallbackProvider {
            ...
            /*
             * Declare an ambient mode controller, which will be used by
             * the activity to determine if the current mode is ambient.
             */
            private AmbientModeSupport.AmbientController ambientController;
            ...
            @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
                ...
                ambientController = AmbientModeSupport.attach(this);
            }
            ...
        }
        
  4. Buat class dalam yang memperluas class AmbientCallback untuk melakukan tindakan pada peristiwa standby. Class ini menjadi objek yang ditampilkan dari metode yang Anda buat di Langkah 2:

    Kotlin

        private class MyAmbientCallback : AmbientModeSupport.AmbientCallback() {
    
            override fun onEnterAmbient(ambientDetails: Bundle?) {
              // Handle entering ambient mode
            }
    
            override fun onExitAmbient() {
              // Handle exiting ambient mode
            }
    
            override fun onUpdateAmbient() {
              // Update the content
            }
        }
        

    Java

        private class MyAmbientCallback extends AmbientModeSupport.AmbientCallback {
            @Override
            public void onEnterAmbient(Bundle ambientDetails) {
              // Handle entering ambient mode
            }
    
            @Override
            public void onExitAmbient() {
              // Handle exiting ambient mode
             }
    
            @Override
            public void onUpdateAmbient() {
              // Update the content
            }
        }
        

Pastikan untuk mempelajari Sampel AlwaysOn untuk informasi lebih lanjut dan praktik terbaik.

Mode standby menggunakan class WearableActivity

Untuk project baru dan yang sudah ada, Anda dapat menambahkan dukungan mode standby ke aplikasi Wear dengan mengupdate konfigurasi project.

Membuat aktivitas yang mendukung mode standby

Anda dapat mengaktifkan mode standby dalam aktivitas Anda dengan menggunakan class WearableActivity:

  1. Buat aktivitas yang memperluas WearableActivity.
  2. Dalam metode onCreate() aktivitas Anda, panggil metode setAmbientEnabled().

Aktifkan mode standby dalam aktivitas Anda sebagai berikut:

Kotlin

    class MainActivity : WearableActivity() {

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)

            setAmbientEnabled()
        ...
        }
    }

Java

    public class MainActivity extends WearableActivity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            setAmbientEnabled();
            ...
        }
    

Menangani transisi antarmode

Jika pengguna tidak berinteraksi dengan aplikasi Anda selama jangka waktu tertentu selagi aplikasi ditampilkan, atau jika pengguna menutupi layar dengan telapak tangan, sistem akan mengalihkan aktivitasnya ke mode standby. Setelah aplikasi beralih ke mode standby, update UI aktivitas ke tata letak yang lebih sederhana untuk mengurangi konsumsi daya. Sebaiknya gunakan latar belakang hitam dengan sedikit gambar dan teks warna putih. Untuk memudahkan pengguna bertransisi dari mode interaktif ke standby, coba pertahankan penempatan yang serupa untuk item yang ada di layar. Untuk informasi selengkapnya tentang cara menyajikan konten di layar standby, lihat panduan desain Tampilan Jam untuk Wear OS.

Perhatikan bahwa ketika aplikasi berjalan di perangkat tanpa tombol fisik, menutup layar dengan telapak tangan tidak akan membuat aplikasi beralih ke mode standby. Sebaliknya, hal itu akan menyebabkan aplikasi keluar dan layar utama muncul. Perilaku ini dimaksudkan untuk memastikan bahwa pengguna dapat keluar dari aplikasi dengan lancar. Namun, perangkat tetap memasuki mode standby saat waktu pemakaian perangkat habis.

Catatan: Dalam mode standby, nonaktifkan semua elemen interaktif di layar, seperti tombol. Untuk informasi lebih lanjut tentang cara mendesain interaksi pengguna pada aplikasi always-on, lihat panduan desain Struktur Aplikasi untuk Wear OS.

Setelah aktivitas beralih ke mode standby, sistem akan memanggil metode onEnterAmbient() pada aktivitas wearable Anda. Cuplikan kode berikut menunjukkan cara mengubah warna teks menjadi putih dan menonaktifkan anti-aliasing setelah sistem beralih ke mode standby:

Kotlin

    override fun onEnterAmbient(ambientDetails: Bundle?) {
        super.onEnterAmbient(ambientDetails)

        stateTextView.setTextColor(Color.WHITE)
        stateTextView.paint.isAntiAlias = false
    }
    

Java

    @Override
    public void onEnterAmbient(Bundle ambientDetails) {
        super.onEnterAmbient(ambientDetails);

        stateTextView.setTextColor(Color.WHITE);
        stateTextView.getPaint().setAntiAlias(false);
    }
    

Saat pengguna mengetuk layar atau mengangkat pergelangan tangan, aktivitas akan beralih dari mode standby ke mode interaktif. Sistem memanggil metode onExitAmbient(). Ganti metode ini untuk mengupdate tata letak UI sehingga aplikasi Anda ditampilkan dalam keadaan interaktif dan berwarna.

Cuplikan kode berikut menunjukkan cara mengubah warna teks menjadi hijau dan mengaktifkan anti-aliasing ketika sistem beralih ke mode interaktif:

Kotlin

    override fun onExitAmbient() {
        super.onExitAmbient()

        stateTextView.setTextColor(Color.GREEN)
        stateTextView.paint.isAntiAlias = true
    }
    

Java

    @Override
    public void onExitAmbient() {
        super.onExitAmbient();

        stateTextView.setTextColor(Color.GREEN);
        stateTextView.getPaint().setAntiAlias(true);
    }
    

Mengupdate konten dalam mode standby

Mode standby memungkinkan Anda mengupdate layar dengan informasi baru bagi pengguna, tetapi Anda harus cermat dalam menyeimbangkan update tampilan dengan masa pakai baterai. Anda harus benar-benar mempertimbangkan penggantian metode onUpdateAmbient() untuk memperbarui layar sekali dalam satu menit pada mode standby. Jika aplikasi Anda memerlukan update lebih sering, ingatlah bahwa frekuensi update berdampak pada masa pakai baterai. Untuk menghemat baterai, update tidak boleh lebih dari sekali dalam 10 detik. Namun, dalam praktiknya, Anda harus mengupdate aplikasi kurang dari itu.

Mengupdate sekali dalam satu menit

Guna menghemat daya baterai, sebagian besar aplikasi Wear sebaiknya tidak sering mengupdate layar saat dalam mode standby. Dalam mode ini, sebaiknya Anda mendesain aplikasi untuk mengupdate layar satu kali per menit. Sistem menyediakan metode callback, onUpdateAmbient(), yang memungkinkan Anda mengupdate layar pada frekuensi yang direkomendasikan ini.

Untuk mengupdate konten aplikasi Anda, ganti metode onUpdateAmbient() dalam aktivitas wearable:

Kotlin

    override fun onUpdateAmbient() {
        super.onUpdateAmbient()
        // Update the content
    }
    

Java

    @Override
    public void onUpdateAmbient() {
        super.onUpdateAmbient();
        // Update the content
    }
    

Mengupdate lebih sering

Meskipun tidak disarankan, Anda dapat mengupdate aplikasi Wear dalam mode standby lebih dari sekali dalam satu menit. Untuk aplikasi yang memang membutuhkan update lebih sering, Anda dapat menggunakan objek AlarmManager untuk mengaktifkan prosesor dan mengupdate layar lebih sering.

Untuk menerapkan alarm yang mengupdate konten lebih sering dalam mode standby, ikuti langkah-langkah berikut:

  1. Siapkan pengelola alarm.
  2. Tetapkan frekuensi update.
  3. Jadwalkan update berikutnya saat aktivitas beralih ke mode standby atau saat sedang dalam mode standby.
  4. Batalkan alarm saat aktivitas beralih ke mode interaktif atau jika aktivitas dihentikan.

Catatan: Pengelola alarm dapat membuat instance baru aktivitas jika dipicu. Untuk mencegah situasi ini, pastikan bahwa aktivitas Anda dinyatakan dengan parameter android:launchMode="singleInstance" dalam manifes.

Bagian berikut menjelaskan langkah-langkah ini secara detail.

Menyiapkan pengelola alarm

Pengelola alarm meluncurkan intent tertunda yang mengupdate layar dan menjadwalkan alarm berikutnya. Contoh berikut menunjukkan cara menyatakan pengelola alarm dan intent tertunda dalam metode onCreate() aktivitas Anda:

Kotlin

    // Action for updating the display in ambient mode, per our custom refresh cycle.
    private const val AMBIENT_UPDATE_ACTION = "com.your.package.action.AMBIENT_UPDATE"
    ...
    private lateinit var ambientUpdateAlarmManager: AlarmManager
    private lateinit var ambientUpdatePendingIntent: PendingIntent
    private lateinit var ambientUpdateBroadcastReceiver: BroadcastReceiver

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setAmbientEnabled()

        ambientUpdateAlarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager

        ambientUpdatePendingIntent = Intent(AMBIENT_UPDATE_ACTION).let { ambientUpdateIntent ->
            PendingIntent.getBroadcast(this, 0, ambientUpdateIntent, PendingIntent.FLAG_UPDATE_CURRENT)
        }

        ambientUpdateBroadcastReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                refreshDisplayAndSetNextUpdate()
            }
        }
        ...
    }
    

Java

    // Action for updating the display in ambient mode, per our custom refresh cycle.
    private static final String AMBIENT_UPDATE_ACTION = "com.your.package.action.AMBIENT_UPDATE";

    private AlarmManager ambientUpdateAlarmManager;
    private PendingIntent ambientUpdatePendingIntent;
    private BroadcastReceiver ambientUpdateBroadcastReceiver;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setAmbientEnabled();

        ambientUpdateAlarmManager =
            (AlarmManager) getSystemService(Context.ALARM_SERVICE);

        Intent ambientUpdateIntent = new Intent(AMBIENT_UPDATE_ACTION);

        ambientUpdatePendingIntent = PendingIntent.getBroadcast(
            this, 0, ambientUpdateIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        ambientUpdateBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                refreshDisplayAndSetNextUpdate();
            }
        };
        ...
    }
    

Sekarang kita harus mendaftarkan dan membatalkan pendaftaran penerima siaran di onResume() dan onPause():

Kotlin

    override fun onResume() {
        super.onResume()
        IntentFilter(AMBIENT_UPDATE_ACTION).also { filter ->
            registerReceiver(ambientUpdateBroadcastReceiver, filter)
        }
    }

    override fun onPause() {
        super.onPause()
        unregisterReceiver(ambientUpdateBroadcastReceiver)
        ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent)
    }
    

Java

    @Override
    public void onResume() {
        super.onResume();
        IntentFilter filter = new IntentFilter(AMBIENT_UPDATE_ACTION);
        registerReceiver(ambientUpdateBroadcastReceiver, filter);
            ...
    }

    @Override
    public void onPause() {
        super.onPause();
        unregisterReceiver(ambientUpdateBroadcastReceiver);
        ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent);
        ...
    }
    
Mengupdate layar dan menjadwalkan update data

Dalam aktivitas contoh ini, pengelola alarm memicu intent setiap 20 detik dalam mode standby. Saat timer berdetak, alarm akan memicu intent untuk mengupdate layar, lalu menetapkan penundaan untuk update berikutnya.

Contoh berikut menunjukkan cara mengupdate informasi di layar dan menyetel alarm untuk update berikutnya:

Kotlin

    // Milliseconds between waking processor/screen for updates
    private val AMBIENT_INTERVAL_MS: Long = TimeUnit.SECONDS.toMillis(20)
    ...
    private fun refreshDisplayAndSetNextUpdate() {
        if (isAmbient) {
            // Implement data retrieval and update the screen for ambient mode
        } else {
            // Implement data retrieval and update the screen for interactive mode
        }
        val timeMs: Long = System.currentTimeMillis()
        // Schedule a new alarm
        if (isAmbient) {
            // Calculate the next trigger time
            val delayMs: Long = AMBIENT_INTERVAL_MS - timeMs % AMBIENT_INTERVAL_MS
            val triggerTimeMs: Long = timeMs + delayMs
            ambientUpdateAlarmManager.setExact(
                    AlarmManager.RTC_WAKEUP,
                    triggerTimeMs,
                    ambientUpdatePendingIntent)
        } else {
            // Calculate the next trigger time for interactive mode
        }
    }
    

Java

    // Milliseconds between waking processor/screen for updates
    private static final long AMBIENT_INTERVAL_MS = TimeUnit.SECONDS.toMillis(20);
    private void refreshDisplayAndSetNextUpdate() {
        if (isAmbient()) {
            // Implement data retrieval and update the screen for ambient mode
        } else {
            // Implement data retrieval and update the screen for interactive mode
        }
        long timeMs = System.currentTimeMillis();
        // Schedule a new alarm
        if (isAmbient()) {
            // Calculate the next trigger time
            long delayMs = AMBIENT_INTERVAL_MS - (timeMs % AMBIENT_INTERVAL_MS);
            long triggerTimeMs = timeMs + delayMs;
            ambientUpdateAlarmManager.setExact(
                AlarmManager.RTC_WAKEUP,
                triggerTimeMs,
                ambientUpdatePendingIntent);
        } else {
            // Calculate the next trigger time for interactive mode
        }
    }
    
Menjadwalkan alarm berikutnya

Jadwalkan alarm untuk mengupdate layar saat aktivitas memasuki mode standby atau saat aktivitas sudah berada dalam mode standby dengan mengganti metode onEnterAmbient() dan metode onUpdateAmbient():

Kotlin

    override fun onEnterAmbient(ambientDetails: Bundle?) {
        super.onEnterAmbient(ambientDetails)

        refreshDisplayAndSetNextUpdate()
    }

    override fun onUpdateAmbient() {
        super.onUpdateAmbient()
        refreshDisplayAndSetNextUpdate()
    }
    

Java

    @Override
    public void onEnterAmbient(Bundle ambientDetails) {
        super.onEnterAmbient(ambientDetails);
        refreshDisplayAndSetNextUpdate();
    }

    @Override
    public void onUpdateAmbient() {
        super.onUpdateAmbient();
        refreshDisplayAndSetNextUpdate();
    }
    

Catatan: Dalam contoh ini, metode refreshDisplayAndSetNextUpdate() dipanggil setiap kali layar perlu diupdate. Untuk contoh lain tentang cara memanggil metode ini, lihat Sampel AlwaysOn.

Membatalkan alarm

Saat perangkat beralih ke mode interaktif, batalkan alarm dengan metode onExitAmbient():

Kotlin

    override fun onExitAmbient() {
        super.onExitAmbient()

        ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent)
    }
    

Java

    @Override
    public void onExitAmbient() {
        super.onExitAmbient();
        ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent);
    }
    

Saat pengguna keluar atau menghentikan aktivitas, batalkan alarm dalam metode onDestroy() aktivitas Anda:

Kotlin

    override fun onDestroy() {
        ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent)
        super.onDestroy()
    }
    

Java

    @Override
    public void onDestroy() {
        ambientUpdateAlarmManager.cancel(ambientUpdatePendingIntent);
        super.onDestroy();
    }
    

Mempertahankan kompatibilitas dengan versi sebelumnya

Aktivitas yang mendukung mode standby otomatis kembali ke aktivitas normal pada perangkat Wear yang menjalankan Android versi di bawah 5.1 (level API 22). Tidak perlu kode aplikasi khusus apa pun untuk mendukung perangkat pada versi Android ini. Saat beralih ke mode standby, perangkat akan kembali ke layar utama dan keluar dari aktivitas.

Jika aplikasi Anda tidak boleh diinstal atau diupdate pada perangkat yang menjalankan versi Android sebelum 5.1, update manifes Anda dengan baris berikut:

    <uses-library android:name="com.google.android.wearable" android:required="true" />