Menjadwalkan alarm

Alarm (berdasarkan AlarmManager ) memberi Anda cara untuk melakukan operasi berbasis waktu di luar masa pakai aplikasi Anda. Misalnya, Anda bisa menggunakan alarm untuk memulai operasi yang berjalan lama, seperti saat memulai layanan sekali sehari untuk mengunduh prakiraan cuaca.

Alarm memiliki karakteristik berikut:

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

  • Anda dapat menggunakannya bersama penerima siaran untuk menjadwalkan jobs atau WorkRequests untuk melakukan operasional bisnis.

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

  • Membantu Anda meminimalkan kebutuhan resource aplikasi. Anda dapat menjadwalkan operasi tanpa bergantung pada {i>timer<i} atau layanan yang terus berjalan.

Menyetel alarm yang tidak tepat

Saat aplikasi menyetel alarm yang tidak tepat, sistem akan mengeluarkan alarm pada waktu tertentu di masa mendatang. Alarm yang tidak tepat memberikan beberapa jaminan mengenai waktu pengiriman alarm dengan tetap mematuhi batasan penghematan baterai seperti Istirahatkan.

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

Mengirimkan alarm setelah waktu tertentu

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

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

Mengirimkan alarm selama jangka waktu tertentu

Jika aplikasi Anda memanggil setWindow(), alarm tidak akan pernah berbunyi sebelum alarm yang disediakan waktu pemicu. Alarm akan diaktifkan kecuali jika pembatasan penghematan baterai diberlakukan yang dikirim dalam jangka waktu yang ditentukan, mulai dari pemicu yang diberikan baik.

Jika aplikasi Anda menargetkan Android 12 atau yang lebih baru, sistem dapat menunda pemanggilan alarm tidak tepat berjangka waktu minimal selama 10 menit. Sebagai karena alasan ini, nilai parameter windowLengthMillis di bawah 600000 terpotong untuk 600000.

Mengirimkan alarm berulang pada interval yang kurang teratur

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

  1. Alarm pertama berbunyi dalam jangka waktu yang ditentukan, mulai dari waktu pemicu tertentu.
  2. Alarm berikutnya biasanya berbunyi setelah jangka waktu yang ditentukan yang telah berlalu. Waktu antara dua pemanggilan alarm berturut-turut dapat bervariasi.

Menyetel alarm yang tepat

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

Sebagian besar aplikasi dapat menjadwalkan tugas dan acara menggunakan alarm yang tidak tepat untuk menyelesaikan beberapa kasus penggunaan umum. Jika aplikasi Anda fungsionalitas bergantung pada alarm yang waktunya tepat—misalnya untuk aplikasi jam alarm atau aplikasi kalender—sebaiknya gunakan alarm yang tepat.

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 menyertakan beberapa item metode untuk menangani operasi pengaturan waktu, seperti melakukan beberapa pekerjaan setiap n detik, saat aplikasi Anda aktif: postAtTime() dan postDelayed(). Perlu diperhatikan bahwa API ini mengandalkan waktu beroperasi sistem dan bukan secara real time.
Pekerjaan latar belakang terjadwal, seperti mengupdate aplikasi dan mengupload log
WorkManager menyediakan cara untuk menjadwalkan waktu yang terikat waktu secara berkala Anda. Anda dapat memberikan interval pengulangan dan flexInterval (minimum 15 menit) untuk menentukan runtime terperinci untuk 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 jangka waktu tertentu
Menggunakan alarm yang tidak tepat. Secara khusus, panggil setWindow() Perhatikan bahwa, jika aplikasi Anda menargetkan Android 12 atau yang lebih tinggi, aplikasi terkecil panjang jendela 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 yang lebih dekat ke bagian bawah daftar menayangkan lebih banyak tugas yang sangat mendesak tetapi membutuhkan lebih banyak sumber daya sistem.

setExact()

Panggil alarm pada waktu yang hampir tepat di masa mendatang, asalkan penghematan baterai tidak berlangsung.

Gunakan metode ini untuk menyetel alarm yang tepat, kecuali jika tugas aplikasi Anda waktu yang sangat penting bagi pengguna.

setExactAndAllowWhileIdle()

Panggil alarm pada waktu yang hampir tepat di masa mendatang, meskipun sedang menghemat baterai tindakan tersebut berlaku.

setAlarmClock()

Panggil alarm pada waktu yang tepat di masa mendatang. Karena alarm ini sangat terlihat oleh pengguna, sistem tidak pernah menyesuaikan waktu pengiriman mereka. Tujuan sistem mengidentifikasi alarm ini sebagai yang paling penting dan membiarkan alarm berdaya rendah jika diperlukan untuk mengirimkan alarm.

Konsumsi resource sistem

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

Sangat disarankan agar Anda membuat alarm yang tidak tepat setiap kali sebaik mungkin. Untuk melakukan pekerjaan yang lebih lama, jadwalkan menggunakan WorkManager atau JobScheduler dari alarm BroadcastReceiver. Melakukan pekerjaan sambil perangkat dalam Istirahatkan, buat alarm yang tidak tepat menggunakan setAndAllowWhileIdle(), dan memulai tugas dari alarm.

Mendeklarasikan izin alarm yang tepat yang tepat

Jika aplikasi menargetkan Android 12 atau yang lebih tinggi, Anda harus mendapatkan "Alarm & pengingat" akses aplikasi khusus. Untuk melakukannya, deklarasikan atribut 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 menargetkan Android 13 (API level 33) atau yang lebih baru, Anda memiliki opsi untuk mendeklarasikan SCHEDULE_EXACT_ALARM atau USE_EXACT_ALARM izin akses.

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

Meskipun izin SCHEDULE_EXACT_ALARM dan USE_EXACT_ALARM memberikan sinyal kemampuan yang sama, mereka diberikan secara berbeda dan mendukung berbagai kasus penggunaan. Aplikasi Anda harus menggunakan alarm yang tepat, dan mendeklarasikan Izin SCHEDULE_EXACT_ALARM atau USE_EXACT_ALARM, hanya jika dilihat oleh pengguna di aplikasi Anda memerlukan tindakan dengan waktu yang tepat.

USE_EXACT_ALARM

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 sebelumnya ke penginstalan baru aplikasi yang menargetkan Android 13 (API level 33) dan yang lebih tinggi. Jika pengguna mentransfer 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 sudah ada sudah memiliki izin ini, izin tersebut akan diberikan sebelumnya ketika upgrade perangkat ke Android 14.

Catatan: Jika alarm yang tepat disetel menggunakan OnAlarmListener , seperti dengan setExact API, izin SCHEDULE_EXACT_ALARM tidak diperlukan.

Menggunakan izin SCHEDULE_EXACT_ALARM

Tidak seperti USE_EXACT_ALARM, izin akses SCHEDULE_EXACT_ALARM harus yang diberikan oleh pengguna. Baik pengguna maupun 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 Anda, aplikasi Anda akan berhenti, dan semua alarm yang tepat pada masa mendatang dibatalkan. Ini juga berarti bahwa nilai yang dikembalikan oleh canScheduleExactAlarms() tetap valid untuk seluruh siklus proses aplikasi Anda.

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

  1. Mengonfirmasi bahwa aplikasi Anda masih memiliki akses aplikasi khusus. Untuk melakukannya, panggil canScheduleExactAlarms() Pemeriksaan ini melindungi aplikasi Anda dari situasi ketika pengguna memberikan izin kepada aplikasi izin akses jaringan, lalu mencabutnya segera setelahnya.
  2. Menjadwalkan ulang alarm 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 tab Alarm & pengingat di 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 secara berulang jadwal proyek.

Alarm yang tidak dirancang dengan baik dapat menyebabkan kehabisan baterai dan memberikan beban yang signifikan pada server web. Karena alasan ini, pada 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 adalah di masa lalu, alarm akan langsung terpicu.

  • 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, maka akan menggantikan alarm asli.

Untuk membatalkan PendingIntent(), kartu 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 seharusnya.

Ada dua jenis jam umum untuk alarm: "elapsed real time" dan "jam real time" (RTC). Elapsed real time menggunakan "waktu sejak booting sistem" sebagai aktual, dan jam aktual menggunakan waktu UTC (jam dinding). Hal ini berarti bahwa waktu riil telah disesuaikan untuk mengatur alarm berdasarkan perjalanan waktu (untuk misalnya, alarm yang menyala setiap 30 detik) karena tidak terpengaruh oleh zona waktu atau lokalitas tertentu. Jenis jam waktu nyata lebih cocok untuk alarm yang bergantung pada lokalitas saat ini.

Kedua jenis memiliki tanda "bangun" yang mengatakan untuk membangunkan CPU perangkat jika layarnya mati. Hal ini memastikan alarm akan berbunyi pada waktu yang dijadwalkan. Hal ini berguna jika aplikasi Anda memiliki dependensi waktu. Misalnya, jika memiliki periode terbatas untuk melakukan operasi tertentu. Jika Anda tidak menggunakan versi bangun dari jenis alarm Anda, lalu semua alarm berulang akan menyala saat perangkat bangun pada waktu berikutnya.

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

Jika Anda perlu alarm berbunyi pada waktu tertentu, maka pilih salah satu jenis jam real time berbasis jam. Namun, perhatikan bahwa pendekatan ini dapat memiliki beberapa kelemahan. Aplikasi mungkin tidak diterjemahkan dengan baik ke lokal lain, dan jika pengguna mengubah setelan waktu perangkat, hal itu dapat menyebabkan perilaku yang tidak diharapkan dalam aplikasi Anda. Menggunakan jenis alarm jam {i>real time<i} juga tidak diskalakan dengan baik, karena yang telah dibahas di atas. Sebaiknya gunakan data "elapsed real time" alarm jika memungkinkan.

Berikut daftar jenis alarm:

  • ELAPSED_REALTIME: Mengaktifkan intent yang tertunda berdasarkan jumlah waktu sejak perangkat di-{i>booting<i}, tetapi tidak membangunkan perangkat. Tujuan waktu berlalu termasuk waktu saat perangkat sedang tidur.

  • ELAPSED_REALTIME_WAKEUP: Mengaktifkan perangkat dan mengaktifkan intent yang tertunda setelah durasi yang ditentukan waktu yang telah berlalu sejak perangkat {i>booting<i}.

  • RTC: Mengaktifkan intent yang tertunda pada waktu yang ditetapkan, tetapi tidak akan membangunkan perangkat.

  • RTC_WAKEUP: Bangun menyalakan perangkat untuk memicu intent yang 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 setelah itu:

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

Aktifkan perangkat untuk memicu 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);

Mengaktifkan perangkat untuk memicu alarm tepat pada 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 tepat alarm yang Anda butuhkan ini. Untuk sebagian besar aplikasi, setInexactRepeating() adalah pilihan yang tepat. Saat Anda menggunakan metode ini, Android akan menyinkronkan beberapa alarm dan kebakaran berulang yang tidak tepat secara bersamaan. Ini akan mengurangi pemborosan baterai.

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

Dengan setInexactRepeating(), Anda tidak dapat menentukan interval khusus 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 melihat daftar lengkapnya.

Membatalkan alarm

Bergantung pada aplikasi, Anda mungkin ingin menyertakan kemampuan membatalkan alarm. Untuk membatalkan alarm, panggil cancel() di Alarm Manager, yang meneruskan PendingIntent yang tidak Anda inginkan lagi untuk memicu. 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 memulai ulang alarm berulang secara otomatis jika pengguna memulai ulang perangkat. Ini memastikan bahwa AlarmManager akan terus melakukan tugasnya tanpa perlu menyalakan ulang alarm secara manual.

Berikut langkah-langkahnya:

  1. Setel 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 sudah diluncurkan oleh pengguna minimal satu kali):

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  2. Mengimplementasikan 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 filter di ACTION_BOOT_COMPLETED tindakan:

    <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 {i>booting<i} diatur ke android:enabled="false". Ini berarti bahwa penerima akan tidak dipanggil kecuali aplikasi secara eksplisit mengaktifkannya. Hal ini mencegah penerima {i>booting<i} agar tidak dipanggil. 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 Anda mengaktifkan penerima dengan cara ini, penerima akan tetap aktif, meskipun pengguna memulai ulang perangkat. Dengan kata lain, mengaktifkan penerima secara terprogram mengganti setelan manifes, bahkan saat reboot. Penerima akan tetap 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 dukungan Android 6.0 (level API 23) Istirahatkan mode, yang membantu memperpanjang daya tahan baterai perangkat. Alarm tidak berbunyi saat perangkat masuk Mode Istirahat Semua alarm terjadwal ditunda hingga perangkat keluar dari Istirahatkan. Jika Anda ingin untuk menyelesaikan pekerjaan bahkan ketika perangkat sedang tidak digunakan, ada beberapa opsi tersedia:

  • Setel alarm yang tepat.

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

Praktik terbaik

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

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

    • Lakukan semua pekerjaan lokal saat alarm terpicu. "Pekerjaan lokal" berarti segala sesuatu yang tidak mengenai server atau membutuhkan data dari server.

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

  • Pertahankan agar frekuensi alarm Anda tetap minimum.

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

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

    Gunakan setInexactRepeating() bukannya setRepeating(). Saat Anda menggunakan setInexactRepeating(), Android menyinkronkan alarm berulang dari beberapa aplikasi dan kebakaran secara bersamaan. Ini mengurangi jumlah total berapa kali sistem harus mengaktifkan perangkat seluler, sehingga mengurangi pemborosan baterai. Mulai Android 4.4 (API Level 19), semua alarm berulang adalah alarm yang tidak tepat. Catatan bahwa meski setInexactRepeating() merupakan peningkatan dari setRepeating(), tetapi masih dapat membebani server jika setiap {i>instance<i} aplikasi mencapai server di waktu yang sama. Oleh karena itu, untuk permintaan jaringan, tambahkan beberapa keacakan ke alarm Anda, seperti yang 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 melakukannya. Alarm yang berbeda jenis data akan dijelaskan secara lebih mendetail di bagian berikut.