Menjadwalkan alarm

Alarm (berdasarkan class AlarmManager ) memberi Anda cara untuk melakukan operasi berbasis waktu di luar masa aktif aplikasi. Misalnya, Anda dapat menggunakan alarm untuk memulai operasi yang berjalan lama, seperti memulai layanan sekali sehari untuk mendownload perkiraan cuaca.

Alarm memiliki karakteristik berikut:

  • Alarm memungkinkan Anda memicu Intent pada waktu/interval yang ditentukan.

  • Anda dapat menggunakannya bersama dengan penerima siaran untuk menjadwalkan tugas atau WorkRequest untuk melakukan operasi lainnya.

  • Keduanya beroperasi di luar aplikasi, sehingga Anda dapat menggunakannya untuk memicu peristiwa atau tindakan bahkan saat aplikasi tidak berjalan, dan meskipun perangkat itu sendiri dalam mode tidur.

  • Membantu Anda meminimalkan kebutuhan resource aplikasi. Anda dapat menjadwalkan operasi tanpa mengandalkan timer atau layanan yang terus berjalan.

Menyetel alarm yang tidak tepat

Jika aplikasi menyetel alarm yang tidak tepat, sistem akan mengirimkan alarm pada waktu tertentu di masa mendatang. Alarm yang tidak tepat memberikan beberapa jaminan terkait waktu pengiriman alarm sekaligus tetap mematuhi batasan penghematan baterai seperti Istirahatkan.

Developer dapat memanfaatkan jaminan API berikut untuk menyesuaikan pengaturan waktu pengiriman alarm yang tidak tepat.

Mengirim alarm setelah waktu tertentu

Jika aplikasi Anda memanggil set(), setInexactRepeating(), atau setAndAllowWhileIdle(), alarm tidak akan berbunyi sebelum waktu pemicu yang disediakan.

Di Android 12 (level API 31) dan yang lebih tinggi, sistem akan memanggil alarm dalam waktu satu jam dari waktu pemicu yang disediakan, kecuali jika ada pembatasan penghematan baterai yang berlaku seperti penghemat baterai atau Istirahatkan.

Mengirim alarm selama jangka waktu tertentu

Jika aplikasi Anda memanggil setWindow(), alarm tidak akan pernah berbunyi sebelum waktu pemicu yang diberikan. Jika ada batasan penghematan baterai yang diberlakukan, alarm akan dikirimkan dalam jangka waktu yang ditentukan, mulai dari waktu pemicu yang diberikan.

Jika aplikasi Anda menargetkan Android 12 atau yang lebih tinggi, sistem dapat menunda pemanggilan alarm yang tidak tepat berjangka waktu setidaknya 10 menit. Karena alasan ini, parameter value windowLengthMillis pada 600000 terpotong menjadi 600000.

Mengirimkan alarm berulang dengan interval yang kira-kira teratur

Jika aplikasi Anda memanggil setInexactRepeating(), sistem akan memanggil beberapa alarm:

  1. Alarm pertama akan berbunyi dalam periode waktu yang ditentukan, mulai dari waktu pemicu tertentu.
  2. Alarm berikutnya biasanya berbunyi setelah jangka waktu yang ditentukan berlalu. Waktu antara dua pemanggilan alarm yang berurutan dapat bervariasi.

Menyetel alarm yang tepat

Sistem memanggil alarm yang tepat pada waktu yang tepat di masa mendatang.

Sebagian besar aplikasi dapat menjadwalkan tugas dan peristiwa menggunakan alarm yang tidak tepat untuk menyelesaikan beberapa kasus penggunaan umum. Jika fungsi inti aplikasi Anda bergantung pada alarm dengan waktu yang tepat—seperti untuk aplikasi jam alarm atau aplikasi kalender—Anda dapat menggunakan alarm yang tepat sebagai gantinya.

Kasus penggunaan yang mungkin tidak memerlukan alarm yang tepat

Daftar berikut menunjukkan alur kerja umum yang mungkin tidak memerlukan alarm yang tepat:

Menjadwalkan operasi pengaturan waktu selama masa aktif aplikasi Anda
Class Handler mencakup beberapa metode yang baik untuk menangani operasi pengaturan waktu, seperti melakukan beberapa pekerjaan setiap n detik, saat aplikasi Anda masih aktif: postAtTime() dan postDelayed(). Perlu diperhatikan bahwa API ini mengandalkan waktu beroperasi sistem dan bukan real time.
Pekerjaan latar belakang terjadwal, seperti mengupdate aplikasi dan mengupload log
WorkManager menyediakan cara untuk menjadwalkan pekerjaan berkala yang sensitif terhadap waktu. Anda dapat memberikan interval pengulangan dan flexInterval (minimal 15 menit) untuk menentukan runtime terperinci bagi tugas.
Tindakan yang ditentukan pengguna yang akan terjadi setelah waktu tertentu (meskipun jika sistem dalam status tidak ada aktivitas)
Menggunakan alarm yang tidak tepat. Secara khusus, panggil setAndAllowWhileIdle().
Tindakan yang ditentukan pengguna yang akan terjadi setelah waktu tertentu
Menggunakan alarm yang tidak tepat. Secara khusus, panggil set().
Tindakan yang ditentukan pengguna yang dapat terjadi dalam jangka waktu tertentu
Menggunakan alarm yang tidak tepat. Secara khusus, panggil setWindow(). Perhatikan bahwa, jika aplikasi Anda menargetkan Android 12 atau yang lebih baru, durasi periode terkecil yang diizinkan adalah 10 menit.

Cara menyetel alarm yang tepat

Aplikasi Anda dapat menyetel alarm yang tepat menggunakan salah satu metode berikut. Metode ini diurutkan sehingga metode yang lebih dekat ke bagian bawah daftar melayani tugas yang lebih mendesak dari segi waktu, tetapi memerlukan resource sistem yang lebih banyak.

setExact()

Memanggil alarm pada waktu yang hampir tepat di masa mendatang, selama langkah penghematan baterai lainnya tidak berlaku.

Gunakan metode ini untuk menyetel alarm yang tepat, kecuali jika pekerjaan aplikasi Anda sangat bergantung pada waktu bagi pengguna.

setExactAndAllowWhileIdle()

Memanggil alarm pada waktu yang hampir tepat di masa mendatang, meskipun tindakan hemat baterai sedang diterapkan.

setAlarmClock()

Memanggil alarm pada waktu yang tepat di masa mendatang. Karena alarm ini sangat terlihat oleh pengguna, sistem tidak pernah menyesuaikan waktu pengirimannya. Sistem mengidentifikasi alarm ini sebagai alarm yang paling penting dan membiarkan mode daya rendah jika diperlukan untuk mengirimkan alarm.

Konsumsi resource sistem

Saat sistem memicu alarm yang tepat yang disetel aplikasi Anda, perangkat akan menghabiskan banyak resource, seperti masa pakai baterai, terutama jika dalam mode hemat daya. Selain itu, sistem tidak dapat dengan mudah mengelompokkan permintaan ini untuk menggunakan resource dengan lebih efisien.

Sebaiknya Anda membuat alarm yang tidak tepat jika memungkinkan. Untuk melakukan pekerjaan yang lebih lama, jadwalkan menggunakan WorkManager atau JobScheduler dari BroadcastReceiver alarm Anda. Untuk melakukan pekerjaan saat perangkat berada dalam mode Istirahatkan, buat alarm yang tidak tepat menggunakan setAndAllowWhileIdle(), dan mulai tugas dari alarm.

Mendeklarasikan izin alarm yang tepat dan tepat

Jika aplikasi menargetkan Android 12 atau yang lebih baru, Anda harus mendapatkan akses aplikasi khusus "Alarm & pengingat". Untuk melakukannya, deklarasikan izin SCHEDULE_EXACT_ALARM dalam file manifes aplikasi Anda, seperti ditunjukkan dalam cuplikan kode berikut:

<manifest ...>
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
    <application ...>
        ...
    </application>
</manifest>

Jika aplikasi menargetkan Android 13 (API level 33) atau yang lebih baru, Anda memiliki opsi untuk mendeklarasikan izin SCHEDULE_EXACT_ALARM atau USE_EXACT_ALARM.

<manifest ...>
    <uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
    <application ...>
        ...
    </application>
</manifest>

Meskipun izin SCHEDULE_EXACT_ALARM dan USE_EXACT_ALARM menandakan kemampuan yang sama, izin tersebut diberikan secara berbeda dan mendukung kasus penggunaan yang berbeda. Aplikasi Anda harus menggunakan alarm yang tepat, dan mendeklarasikan izin SCHEDULE_EXACT_ALARM atau USE_EXACT_ALARM, hanya jika fungsi yang ditampilkan kepada pengguna di aplikasi Anda memerlukan tindakan tepat waktu.

USE_EXACT_ALARM

SCHEDULE_EXACT_ALARM

  • Diberikan oleh pengguna
  • Kumpulan kasus penggunaan yang lebih luas
  • Aplikasi harus mengonfirmasi bahwa izin belum dicabut

Menggunakan izin SCHEDULE_EXACT_ALARM

Tidak seperti USE_EXACT_ALARM, izin SCHEDULE_EXACT_ALARM harus diberikan oleh pengguna. Pengguna dan sistem dapat mencabut izin SCHEDULE_EXACT_ALARM.

Untuk memeriksa apakah izin diberikan ke aplikasi Anda, panggil canScheduleExactAlarms() sebelum mencoba menyetel alarm yang tepat. Jika izin SCHEDULE_EXACT_ALARM dicabut untuk aplikasi, aplikasi akan berhenti, dan semua alarm berikutnya akan dibatalkan. Hal ini juga berarti bahwa nilai yang ditampilkan oleh canScheduleExactAlarms() tetap valid selama seluruh siklus proses aplikasi Anda.

Setelah izin SCHEDULE_EXACT_ALARMS diberikan ke aplikasi Anda, sistem akan mengirimkannya siaran ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED. Aplikasi harus menerapkan penerima siaran yang melakukan hal berikut:

  1. Mengonfirmasi bahwa aplikasi Anda masih memiliki akses aplikasi khusus. Untuk melakukannya, panggil canScheduleExactAlarms() Pemeriksaan ini melindungi aplikasi Anda dari kasus ketika pengguna memberikan izin ke aplikasi, lalu segera mencabutnya.
  2. Menjadwal ulang alarm apa pun yang tepat yang diperlukan aplikasi Anda, berdasarkan statusnya saat ini. Logika ini harus mirip dengan yang dilakukan aplikasi Anda saat menerima siaran ACTION_BOOT_COMPLETED.

Minta pengguna untuk memberikan izin SCHEDULE_EXACT_ALARM

Opsi ini disebut &#39;Izinkan setelan alarm dan pengingat&#39;
Gambar 1. Halaman akses aplikasi khusus "Alarm & pengingat" di setelan sistem, tempat pengguna dapat mengizinkan aplikasi Anda untuk menyetel alarm yang tepat.

Jika perlu, Anda dapat mengarahkan pengguna ke layar Alarm & pengingat di setelan sistem, seperti yang ditunjukkan pada Gambar 1. Caranya, selesaikan langkah-langkah berikut:

  1. Di UI aplikasi, jelaskan kepada pengguna alasan aplikasi Anda perlu menjadwalkan alarm yang tepat.
  2. Panggil intent yang menyertakan tindakan intent ACTION_REQUEST_SCHEDULE_EXACT_ALARM.

Menyetel alarm berulang

Alarm berulang memungkinkan sistem memberi tahu aplikasi Anda tentang jadwal berulang.

Alarm yang tidak dirancang dengan baik dapat menyebabkan kehabisan baterai dan memberikan beban yang signifikan pada server. Karena alasan ini, di Android 4.4 (API level 19) dan yang lebih tinggi, semua alarm berulang adalah alarm yang tidak tepat.

Alarm berulang memiliki karakteristik berikut:

  • Jenis alarm. Untuk pembahasan lebih lanjut, buka Memilih jenis alarm.

  • Waktu pemicu. Jika waktu pemicu yang Anda tentukan berada di masa lalu, alarm akan langsung dipicu.

  • Interval alarm. Misalnya, sekali sehari, setiap jam, atau setiap 5 menit.

  • Intent tertunda yang terpicu saat alarm dipicu. Saat Anda menyetel alarm kedua yang menggunakan intent tertunda yang sama, alarm tersebut akan menggantikan alarm asli.

Untuk membatalkan PendingIntent(), teruskan FLAG_NO_CREATE ke PendingIntent.getService() untuk mendapatkan instance intent (jika ada), lalu teruskan intent tersebut ke AlarmManager.cancel()

Kotlin

val alarmManager =
    context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
val pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE)
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent)
}

Java

AlarmManager alarmManager =
    (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent);
}

Memilih jenis alarm

Salah satu pertimbangan pertama dalam menggunakan alarm berulang adalah jenisnya.

Ada dua jenis jam umum untuk alarm: "elapsed real time" dan "real time clock" (RTC). Elapsed real time menggunakan "time since system boot" sebagai referensi, dan real time clock menggunakan waktu UTC (jam dinding). Artinya, elapse real time cocok untuk menyetel alarm berdasarkan waktu yang berlalu (misalnya, alarm yang dipicu setiap 30 detik) karena tidak terpengaruh oleh zona waktu atau lokalitas. Jenis real time clock lebih cocok untuk alarm yang bergantung pada lokalitas saat ini.

Kedua jenis tersebut memiliki versi "bangun", yang memberi tahu untuk mengaktifkan CPU perangkat jika layar nonaktif. Hal ini memastikan bahwa alarm akan dipicu pada waktu yang dijadwalkan. Hal ini berguna jika aplikasi Anda memiliki dependensi waktu. Misalnya, jika memiliki jendela terbatas untuk melakukan operasi tertentu. Jika Anda tidak menggunakan versi bangun dari jenis alarm, semua alarm berulang akan terpicu saat perangkat Anda bangun berikutnya.

Jika Anda hanya ingin alarm dipicu pada interval tertentu (misalnya, setiap setengah jam), gunakan salah satu jenis elapsed real time. Secara umum, ini adalah pilihan yang lebih baik.

Jika Anda perlu alarm menyala pada waktu tertentu, pilih salah satu jenis jam real time berbasis jam. Namun, perlu diketahui bahwa pendekatan ini memiliki beberapa kelemahan. Aplikasi mungkin tidak diterjemahkan dengan baik ke lokalitas lain, dan jika pengguna mengubah setelan waktu perangkat, hal ini dapat menyebabkan perilaku yang tidak diharapkan di aplikasi Anda. Penggunaan jenis alarm real time juga tidak diskalakan dengan baik, seperti yang dibahas di atas. Sebaiknya gunakan alarm "elapsed real time" jika memungkinkan.

Berikut daftar jenis alarm:

  • ELAPSED_REALTIME: Mengaktifkan intent tertunda berdasarkan jumlah waktu sejak perangkat di-booting, tetapi tidak mengaktifkan perangkat. Waktu berlalu termasuk kapan saja saat perangkat sedang tidur.

  • ELAPSED_REALTIME_WAKEUP: Mengaktifkan perangkat dan mengaktifkan intent tertunda setelah jangka waktu yang ditentukan telah berlalu sejak perangkat di-booting.

  • RTC: Mengaktifkan intent tertunda pada waktu yang ditentukan, tetapi tidak mengaktifkan perangkat.

  • RTC_WAKEUP: Mengaktifkan perangkat untuk memicu intent tertunda pada waktu yang ditentukan.

Contoh alarm elapsed real time

Berikut beberapa contoh penggunaan ELAPSED_REALTIME_WAKEUP

Mengaktifkan perangkat untuk memicu alarm dalam 30 menit, dan setiap 30 menit setelahnya:

Kotlin

// Hopefully your alarm will have a lower frequency than this!
alarmMgr?.setInexactRepeating(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
        AlarmManager.INTERVAL_HALF_HOUR,
        alarmIntent
)

Java

// Hopefully your alarm will have a lower frequency than this!
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
        AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);

Mengaktifkan perangkat untuk memicu alarm satu kali (tidak berulang) dalam satu menit:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

alarmMgr?.set(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + 60 * 1000,
        alarmIntent
)

Java

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() +
        60 * 1000, alarmIntent);

Contoh alarm real time clock

Berikut beberapa contoh penggunaan RTC_WAKEUP.

Mengaktifkan perangkat untuk memicu alarm sekitar pukul 14.00, dan mengulangi sekali sehari pada waktu yang sama:

Kotlin

// Set the alarm to start at approximately 2:00 p.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 14)
}

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr?.setInexactRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        AlarmManager.INTERVAL_DAY,
        alarmIntent
)

Java

// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_DAY, alarmIntent);

Mengaktifkan perangkat untuk memicu alarm tepat pada pukul 08.30, dan setiap 20 menit sesudahnya:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

// Set the alarm to start at 8:30 a.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 8)
    set(Calendar.MINUTE, 30)
}

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr?.setRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        1000 * 60 * 20,
        alarmIntent
)

Java

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000 * 60 * 20, alarmIntent);

Menentukan seberapa tepat alarm Anda seharusnya

Seperti yang dijelaskan sebelumnya, memilih jenis alarm sering kali menjadi langkah pertama dalam membuat alarm. Perbedaan lebih lanjut adalah seberapa tepat alarm yang Anda inginkan. Untuk sebagian besar aplikasi, setInexactRepeating() adalah pilihan yang tepat. Saat Anda menggunakan metode ini, Android akan menyinkronkan beberapa alarm berulang yang tidak tepat dan memicunya secara bersamaan. Ini akan mengurangi pemborosan baterai.

Jika memungkinkan, hindari penggunaan alarm yang tepat. Namun, untuk aplikasi langka yang memiliki persyaratan waktu yang ketat, Anda dapat menyetel alarm yang tepat dengan memanggil setRepeating().

Dengan setInexactRepeating(), Anda tidak dapat menentukan interval kustom seperti yang dapat Anda lakukan dengan setRepeating(). Anda harus menggunakan salah satu konstanta interval, seperti INTERVAL_FIFTEEN_MINUTES, INTERVAL_DAY, dan seterusnya. Lihat AlarmManager untuk mengetahui daftar lengkapnya.

Membatalkan alarm

Bergantung pada aplikasi, Anda mungkin ingin menyertakan kemampuan membatalkan alarm. Untuk membatalkan alarm, panggil cancel() di Alarm Manager, dengan meneruskan PendingIntent yang tidak ingin Anda aktifkan lagi. Contoh:

Kotlin

// If the alarm has been set, cancel it.
alarmMgr?.cancel(alarmIntent)

Java

// If the alarm has been set, cancel it.
if (alarmMgr!= null) {
    alarmMgr.cancel(alarmIntent);
}

Memulai alarm saat perangkat dimulai ulang

Secara default, semua alarm dibatalkan setelah perangkat nonaktif. Untuk mencegah hal ini terjadi, Anda dapat mendesain aplikasi agar otomatis memulai ulang alarm berulang jika pengguna memulai ulang perangkat. Hal ini memastikan bahwa AlarmManager akan terus melakukan tugasnya tanpa pengguna perlu memulai ulang alarm secara manual.

Berikut langkah-langkahnya:

  1. Tetapkan izin RECEIVE_BOOT_COMPLETED dalam manifes aplikasi Anda. Hal ini memungkinkan aplikasi Anda menerima ACTION_BOOT_COMPLETED yang disiarkan setelah sistem selesai melakukan booting (ini hanya berfungsi jika aplikasi telah diluncurkan oleh pengguna minimal satu kali):

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  2. Implementasikan BroadcastReceiver untuk menerima siaran:

    Kotlin

    class SampleBootReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == "android.intent.action.BOOT_COMPLETED") {
                // Set the alarm here.
            }
        }
    }
    

    Java

    public class SampleBootReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
                // Set the alarm here.
            }
        }
    }
    
  3. Tambahkan penerima ke file manifes aplikasi Anda dengan filter intent yang memfilter tindakan ACTION_BOOT_COMPLETED:

    <receiver android:name=".SampleBootReceiver"
            android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
    </receiver>

    Perhatikan bahwa di manifes, penerima booting disetel ke android:enabled="false". Artinya, penerima tidak akan dipanggil kecuali aplikasi mengaktifkannya secara eksplisit. Tindakan ini akan mencegah penerima booting dipanggil jika tidak diperlukan. Anda dapat mengaktifkan penerima (misalnya, jika pengguna menyetel alarm) seperti berikut:

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
    )
    

    Java

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
    

    Setelah diaktifkan, penerima dengan cara ini akan tetap diaktifkan, meskipun pengguna memulai ulang perangkat. Dengan kata lain, mengaktifkan penerima secara terprogram akan menggantikan setelan manifes, bahkan saat memulai ulang. Penerima akan tetap diaktifkan hingga aplikasi Anda menonaktifkannya. Anda dapat menonaktifkan penerima (misalnya, jika pengguna membatalkan alarm) seperti berikut:

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
    )
    

    Java

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);
    

Memanggil alarm saat perangkat dalam mode Istirahatkan

Perangkat yang menjalankan Android 6.0 (API level 23) mendukung mode Istirahatkan, yang membantu memperpanjang masa pakai baterai perangkat. Alarm tidak akan berbunyi saat perangkat dalam mode Istirahat Semua alarm yang dijadwalkan akan ditunda hingga perangkat keluar dari mode Istirahatkan. Jika Anda perlu menyelesaikan pekerjaan meskipun perangkat sedang tidak ada aktivitas, ada beberapa opsi yang tersedia:

  • Menyetel alarm yang tepat.

  • Menggunakan WorkManager API, yang dibuat untuk melakukan pekerjaan latar belakang. Anda dapat menunjukkan bahwa sistem harus mempercepat pekerjaan agar pekerjaan selesai sesegera mungkin. Untuk mengetahui informasi selengkapnya, lihat Menjadwalkan tugas dengan WorkManager

Praktik terbaik

Setiap pilihan yang Anda buat dalam mendesain alarm berulang dapat memiliki konsekuensi pada cara aplikasi Anda menggunakan (atau menyalahgunakan) resource sistem. Misalnya, bayangkan aplikasi populer yang disinkronkan dengan server. Jika operasi sinkronisasi didasarkan pada waktu jam dan setiap instance aplikasi disinkronkan pada pukul 23.00, beban pada server dapat menyebabkan latensi tinggi atau bahkan "denial of service". Ikuti praktik terbaik penggunaan alarm berikut:

  • Tambahkan pengacakan (jitter) ke permintaan jaringan apa pun yang dipicu akibat alarm berulang:

    • Lakukan semua pekerjaan lokal saat alarm terpicu. "Pekerjaan lokal" berarti apa pun yang tidak mengenai server atau memerlukan data dari server.

    • Pada saat yang sama, jadwalkan alarm yang berisi permintaan jaringan untuk diaktifkan pada periode waktu yang acak.

  • Pertahankan agar frekuensi alarm Anda tetap minimum.

  • Jangan aktifkan perangkat jika tidak perlu (perilaku ini ditentukan oleh jenis alarm, seperti yang dijelaskan dalam Memilih jenis alarm).

  • Jangan membuat waktu pemicu alarm lebih tepat dari yang seharusnya.

    Gunakan setInexactRepeating(), bukan setRepeating(). Saat Anda menggunakan setInexactRepeating(), Android akan menyinkronkan alarm berulang dari beberapa aplikasi dan memicunya secara bersamaan. Tindakan ini akan mengurangi total berapa kali sistem harus mengaktifkan perangkat, sehingga mengurangi konsumsi baterai. Mulai Android 4.4 (API Level 19), semua alarm berulang adalah alarm yang tidak tepat. Perlu diketahui bahwa meskipun setInexactRepeating() merupakan peningkatan dari setRepeating(), hal ini masih dapat membebani server jika setiap instance aplikasi menjangkau server secara bersamaan. Oleh karena itu, untuk permintaan jaringan, tambahkan beberapa pengacakan ke alarm Anda, seperti yang telah dibahas sebelumnya.

  • Jika memungkinkan, hindari mendasarkan alarm pada waktu jam.

    Alarm berulang yang didasarkan pada waktu pemicu yang tepat tidak akan diskalakan dengan baik. Gunakan ELAPSED_REALTIME jika Anda bisa. Berbagai jenis alarm dijelaskan secara lebih mendetail di bagian berikut.