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 prakiraan 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.
Alarm beroperasi di luar aplikasi, sehingga Anda dapat menggunakannya untuk memicu peristiwa atau tindakan meskipun aplikasi tidak berjalan, dan meskipun perangkat sedang dalam mode tidur.
Hal ini membantu Anda meminimalkan persyaratan resource aplikasi. Anda dapat menjadwalkan operasi tanpa mengandalkan timer atau layanan yang berjalan terus-menerus.
Menyetel alarm tidak tepat
Saat aplikasi menyetel alarm tidak akurat, sistem akan mengirimkan alarm pada suatu waktu di masa mendatang. Alarm tidak akurat memberikan beberapa jaminan terkait pengaturan waktu pengiriman alarm sekaligus mematuhi batasan penghematan baterai seperti Doze.
Developer dapat memanfaatkan jaminan API berikut untuk menyesuaikan waktu pengiriman alarm tidak akurat.
Mengirimkan alarm setelah waktu tertentu
Jika aplikasi Anda memanggil set(),
setInexactRepeating(),
atau setAndAllowWhileIdle(),
alarm tidak akan pernah berbunyi sebelum waktu pemicu yang diberikan.
Di Android 12 (API level 31) dan yang lebih tinggi, sistem akan memanggil alarm dalam waktu satu jam dari waktu pemicu yang diberikan, kecuali jika ada batasan penghematan baterai yang berlaku seperti penghemat baterai atau Istirahatkan.
Mengirimkan alarm selama rentang waktu
Jika aplikasi Anda memanggil setWindow(), alarm tidak akan pernah berbunyi sebelum waktu pemicu yang diberikan. Kecuali jika ada batasan penghematan baterai yang berlaku, 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 tidak akurat dengan periode waktu minimal selama 10 menit. Oleh karena itu, parameter value windowLengthMillis di bawah 600000 biasanya dipotong menjadi 600000. Sistem mungkin mengakomodasi periode yang lebih kecil, terutama jika
alarm dijadwalkan untuk dipicu dalam waktu dekat.
Mengirimkan alarm berulang dengan interval yang kurang lebih teratur
Jika aplikasi Anda memanggil setInexactRepeating(),
sistem akan memanggil beberapa alarm:
- Alarm pertama berbunyi dalam periode waktu yang ditentukan, mulai dari waktu pemicu yang diberikan.
- Alarm berikutnya biasanya berbunyi setelah jangka waktu yang ditentukan berlalu. Waktu antara dua pemanggilan alarm berturut-turut dapat bervariasi.
Menyetel alarm presisi
Sistem memanggil alarm presisi pada waktu yang tepat di masa mendatang.
Sebagian besar aplikasi dapat menjadwalkan tugas dan acara menggunakan alarm tidak akurat untuk menyelesaikan beberapa kasus penggunaan umum. Jika fungsi inti aplikasi Anda bergantung pada alarm yang tepat waktu—seperti untuk aplikasi jam alarm atau aplikasi kalender—maka tidak masalah untuk menggunakan alarm presisi.
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
Handlermenyertakan beberapa metode yang baik untuk menangani operasi pengaturan waktu, seperti melakukan beberapa pekerjaan setiap n detik, saat aplikasi Anda aktif:postAtTime()danpostDelayed(). Perhatikan bahwa API ini mengandalkan waktu beroperasi sistem, bukan real time. - Pekerjaan latar belakang terjadwal, seperti mengupdate aplikasi dan mengupload log
WorkManagermenyediakan cara untuk menjadwalkan pekerjaan berkala yang terikat waktu. Anda dapat memberikan interval pengulangan danflexInterval(minimum 15 menit) untuk menentukan runtime terperinci bagi tugas.- Tindakan yang ditentukan pengguna yang akan terjadi setelah waktu tertentu (meskipun 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 satu periode waktu yang ditentukan
- Menggunakan alarm yang tidak tepat. Secara khusus, panggil
setWindow(). Perhatikan bahwa, jika aplikasi Anda menargetkan Android 12 atau yang lebih tinggi, panjang periode terkecil yang diizinkan adalah 10 menit.
Cara menyetel alarm presisi
Aplikasi Anda dapat menyetel alarm presisi menggunakan salah satu metode berikut. Metode ini diurutkan sedemikian rupa sehingga metode yang lebih dekat ke bagian bawah daftar melayani lebih banyak tugas yang mendesak, tetapi memerlukan lebih banyak resource sistem.
setExact()Memanggil alarm pada waktu yang hampir tepat di masa mendatang, selama langkah-langkah penghematan baterai lainnya tidak berlaku.
Gunakan metode ini untuk menyetel alarm presisi, kecuali jika pekerjaan aplikasi Anda sangat penting bagi pengguna.
setExactAndAllowWhileIdle()Panggil alarm pada waktu yang hampir tepat di masa mendatang, meskipun langkah-langkah penghematan 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 keluar dari mode daya rendah jika diperlukan untuk mengirimkan alarm.
Konsumsi resource sistem
Saat sistem memicu alarm presisi yang disetel aplikasi Anda, perangkat akan menggunakan banyak resource, seperti daya tahan baterai, terutama jika perangkat berada dalam mode hemat daya. Selain itu, sistem tidak dapat dengan mudah mengelompokkan permintaan ini untuk menggunakan resource secara lebih efisien.
Sangat disarankan agar Anda membuat alarm tidak akurat jika
memungkinkan. Untuk melakukan pekerjaan yang lebih lama, jadwalkan menggunakan
WorkManager atau
JobScheduler dari
BroadcastReceiver alarm Anda. Untuk melakukan pekerjaan saat
perangkat dalam mode Istirahatkan, buat alarm tidak tepat menggunakan
setAndAllowWhileIdle(),
dan mulai tugas dari alarm.
Menyatakan izin alarm presisi yang sesuai
Jika aplikasi Anda menargetkan Android 12 atau yang lebih tinggi, Anda harus mendapatkan
akses aplikasi khusus "Alarm & pengingat". Untuk melakukannya, deklarasikan izin
SCHEDULE_EXACT_ALARM
dalam file manifes aplikasi Anda, seperti yang ditunjukkan dalam cuplikan kode berikut:
<manifest ...> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/> <application ...> ... </application> </manifest>
Jika aplikasi Anda menargetkan Android 13 (API level 33) atau yang lebih tinggi, 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, keduanya diberikan secara berbeda dan mendukung kasus penggunaan
yang berbeda. Aplikasi Anda harus menggunakan alarm presisi, 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
- Diberikan secara otomatis
- Tidak dapat dicabut oleh pengguna
- Tunduk pada kebijakan Google Play mendatang
- Kasus penggunaan terbatas
SCHEDULE_EXACT_ALARM
- Diberikan oleh pengguna
- Kumpulan kasus penggunaan yang lebih luas
- Aplikasi harus mengonfirmasi bahwa izin belum dicabut
Izin SCHEDULE_EXACT_ALARM tidak diberikan kepada penginstalan baru aplikasi yang menargetkan Android 13 (level API 33) dan yang lebih tinggi. Jika pengguna mentransfer data aplikasi
ke perangkat yang menjalankan Android 14 melalui operasi pencadangan dan pemulihan, izin
SCHEDULE_EXACT_ALARM akan ditolak di perangkat baru. Namun, jika
aplikasi yang ada sudah memiliki izin ini, izin tersebut akan diberikan sebelumnya saat
perangkat diupgrade ke Android 14.
Catatan: Jika alarm presisi disetel menggunakan objek
OnAlarmListener, seperti dengan API
setExact, izin SCHEDULE_EXACT_ALARM tidak diperlukan.
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 presisi. Jika izin SCHEDULE_EXACT_ALARM
dicabut untuk aplikasi Anda, aplikasi akan berhenti, dan semua alarm presisi
yang akan datang akan dibatalkan. Ini juga berarti bahwa nilai yang ditampilkan oleh
canScheduleExactAlarms() tetap valid selama seluruh siklus proses aplikasi Anda.
Saat izin SCHEDULE_EXACT_ALARMS diberikan ke aplikasi Anda, sistem akan mengirimkan siaran ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED ke aplikasi tersebut. Aplikasi Anda harus mengimplementasikan penerima
siaran yang melakukan
hal berikut:
- Mengonfirmasi bahwa aplikasi Anda masih memiliki akses aplikasi khusus. Untuk melakukannya,
panggil
canScheduleExactAlarms()Pemeriksaan ini melindungi aplikasi Anda dari kasus saat pengguna memberikan izin ke aplikasi Anda, lalu mencabutnya segera setelah itu. - Menjadwalkan ulang alarm presisi yang diperlukan aplikasi Anda, berdasarkan statusnya saat ini.
Logika ini harus mirip dengan yang dilakukan aplikasi Anda saat menerima
siaran
ACTION_BOOT_COMPLETED.
Meminta pengguna untuk memberikan izin SCHEDULE_EXACT_ALARM
Jika perlu, Anda dapat mengarahkan pengguna ke layar Alarm & pengingat di setelan sistem, seperti yang ditunjukkan pada Gambar 1. Caranya, selesaikan langkah-langkah berikut:
- Di UI aplikasi, jelaskan kepada pengguna alasan aplikasi Anda perlu menjadwalkan alarm yang tepat.
- Panggil intent yang menyertakan
tindakan intent
ACTION_REQUEST_SCHEDULE_EXACT_ALARM.
Menyetel alarm berulang
Alarm berulang memungkinkan sistem memberi tahu aplikasi Anda sesuai jadwal berulang.
Alarm yang dirancang dengan buruk dapat menyebabkan baterai habis dan memberikan beban yang signifikan pada server. Oleh karena itu, di Android 4.4 (level API 19) dan yang lebih tinggi, semua alarm berulang adalah alarm 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 sudah berlalu, 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: "waktu berlalu" dan "jam real-time" (RTC). Waktu nyata yang berlalu menggunakan "waktu sejak booting sistem" sebagai referensi, dan jam real-time menggunakan waktu UTC (jam dinding). Artinya, waktu berlalu yang sebenarnya cocok untuk menyetel alarm berdasarkan berlalunya waktu (misalnya, alarm yang diaktifkan setiap 30 detik) karena tidak terpengaruh oleh zona waktu atau lokalitas. Jenis jam real-time lebih cocok untuk alarm yang bergantung pada lokalitas saat ini.
Kedua jenis memiliki versi "wakeup", yang memberi tahu untuk mengaktifkan CPU perangkat jika layar nonaktif. Hal ini memastikan bahwa alarm akan diaktifkan pada waktu yang dijadwalkan. Hal ini berguna jika aplikasi Anda memiliki dependensi waktu. Misalnya, jika aplikasi memiliki jendela terbatas untuk melakukan operasi tertentu. Jika Anda tidak menggunakan versi bangun dari jenis alarm, semua alarm berulang akan diaktifkan saat perangkat Anda bangun berikutnya.
Jika Anda hanya memerlukan alarm untuk diaktifkan pada interval tertentu (misalnya, setiap setengah jam), gunakan salah satu jenis waktu nyata yang berlalu. Secara umum, ini adalah pilihan yang lebih baik.
Jika Anda memerlukan alarm untuk diaktifkan pada waktu tertentu, pilih salah satu jenis jam real-time berbasis jam. Namun, perlu diperhatikan bahwa pendekatan ini dapat 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 terduga di aplikasi Anda. Menggunakan jenis alarm jam real-time juga tidak dapat diskalakan dengan baik, seperti yang dibahas di atas. Sebaiknya gunakan alarm "waktu berlalu" jika memungkinkan.
Berikut daftar jenis alarm:
ELAPSED_REALTIME: Mengaktifkan intent tertunda berdasarkan jumlah waktu sejak perangkat di-booting, tetapi tidak mengaktifkan perangkat. Waktu yang berlalu mencakup waktu saat perangkat dalam mode tidur.ELAPSED_REALTIME_WAKEUP: Membangunkan perangkat dan mengaktifkan intent tertunda setelah durasi waktu yang ditentukan berlalu sejak booting perangkat.RTC: Mengaktifkan intent tertunda pada waktu yang ditentukan, tetapi tidak mengaktifkan perangkat.RTC_WAKEUP: Membangunkan perangkat untuk mengaktifkan intent tertunda pada waktu yang ditentukan.
Contoh alarm elapsed real time
Berikut beberapa contoh penggunaan ELAPSED_REALTIME_WAKEUP
Bangunkan perangkat untuk mengaktifkan 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.
Bangunkan perangkat untuk mengaktifkan alarm sekitar pukul 14.00, dan ulangi 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);
Bangunkan perangkat untuk mengaktifkan alarm tepat pukul 08.30, dan setiap 20 menit setelahnya:
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 merupakan langkah pertama dalam
membuat alarm. Perbedaan lebih lanjut adalah seberapa akurat alarm yang Anda perlukan. Untuk sebagian besar aplikasi,
setInexactRepeating()
adalah pilihan yang tepat. Saat Anda menggunakan metode ini, Android akan menyinkronkan beberapa alarm pengulangan tidak tepat dan mengaktifkannya
pada saat yang sama. Ini akan mengurangi pemborosan baterai.
Hindari penggunaan alarm presisi jika memungkinkan. Namun, untuk aplikasi langka yang memiliki persyaratan waktu yang ketat, Anda dapat menyetel alarm presisi 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 Pengelola Alarm, 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
untuk 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:
Tetapkan izin
RECEIVE_BOOT_COMPLETEDdalam manifes aplikasi Anda. Hal ini memungkinkan aplikasi Anda menerimaACTION_BOOT_COMPLETEDyang disiarkan setelah sistem selesai melakukan booting (ini hanya berfungsi jika aplikasi telah diluncurkan oleh pengguna setidaknya sekali):<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>Terapkan
BroadcastReceiveruntuk 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. } } }
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 dalam manifes, penerima booting ditetapkan ke
android:enabled="false". Artinya, penerima tidak akan dipanggil kecuali jika aplikasi mengaktifkannya secara eksplisit. Tindakan ini mencegah penerima booting dipanggil tanpa perlu. Anda dapat mengaktifkan penerima (misalnya, jika pengguna menyetel alarm) sebagai 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 Anda mengaktifkan penerima dengan cara ini, penerima akan tetap aktif, meskipun pengguna memulai ulang perangkat. Dengan kata lain, mengaktifkan penerima secara terprogram akan mengganti setelan manifes, bahkan setelah perangkat dimulai ulang. Penerima akan tetap diaktifkan hingga aplikasi Anda menonaktifkannya. Anda dapat menonaktifkan penerima (misalnya, jika pengguna membatalkan alarm) sebagai 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 (level API 23) mendukung mode Doze, yang membantu memperpanjang masa pakai baterai perangkat. Alarm tidak diaktifkan saat perangkat berada dalam mode Istirahatkan Semua alarm terjadwal akan ditunda hingga perangkat keluar dari mode Istirahatkan. Jika Anda perlu menyelesaikan pekerjaan bahkan saat perangkat tidak ada aktivitas, ada beberapa opsi yang tersedia:
Setel alarm presisi.
Gunakan WorkManager API, yang dibuat untuk melakukan pekerjaan latar belakang. Anda dapat menunjukkan bahwa sistem harus mempercepat pekerjaan Anda sehingga pekerjaan tersebut selesai secepat mungkin. Untuk mengetahui informasi selengkapnya, lihat Menjadwalkan tugas dengan WorkManager
Praktik terbaik
Setiap pilihan yang Anda buat dalam mendesain alarm berulang dapat berdampak pada cara aplikasi Anda menggunakan (atau menyalahgunakan) resource sistem. Misalnya, bayangkan sebuah 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 mengakibatkan latensi tinggi atau bahkan "denial of service". Ikuti praktik terbaik penggunaan alarm berikut:
Tambahkan keacakan (jitter) ke permintaan jaringan apa pun yang dipicu sebagai akibat dari alarm berulang:
Lakukan semua pekerjaan lokal saat alarm terpicu. "Pekerjaan lokal" berarti apa pun yang tidak mengakses server atau memerlukan data dari server.
Pada saat yang sama, jadwalkan alarm yang berisi permintaan jaringan untuk diaktifkan pada jangka waktu acak.
Pertahankan agar frekuensi alarm Anda tetap minimum.
Jangan membangunkan perangkat jika tidak perlu (perilaku ini ditentukan oleh jenis alarm, seperti yang dijelaskan dalam Memilih jenis alarm).
Jangan membuat waktu pemicu alarm Anda lebih tepat daripada yang seharusnya.
Gunakan
setInexactRepeating(), bukansetRepeating(). Saat Anda menggunakansetInexactRepeating(), Android akan menyinkronkan alarm berulang dari beberapa aplikasi dan mengaktifkannya pada saat yang sama. Hal ini mengurangi frekuensi total sistem harus mengaktifkan perangkat, sehingga mengurangi penggunaan baterai. Mulai Android 4.4 (level API 19), semua alarm berulang adalah alarm tidak akurat. Perhatikan bahwa meskipunsetInexactRepeating()merupakan peningkatan darisetRepeating(), hal ini masih dapat membebani server jika setiap instance aplikasi mengakses server pada waktu yang hampir bersamaan. Oleh karena itu, untuk permintaan jaringan, tambahkan beberapa keacakan ke alarm Anda, seperti yang telah dibahas sebelumnya.Hindari mendasarkan alarm Anda pada waktu jam jika memungkinkan.
Alarm berulang yang didasarkan pada waktu pemicu yang tepat tidak akan diskalakan dengan baik. Gunakan
ELAPSED_REALTIMEjika bisa. Berbagai jenis alarm dijelaskan secara lebih mendetail di bagian berikut.