CategoriesAndroidProgramming

Task Scheduler di Android dengan AlarmManager

Task Scheduler di Android adalah cara untuk menjalankan tugas-tugas tertentu di latar belakang aplikasi secara terjadwal atau sesuai kebutuhan. Android menyediakan beberapa API yang dapat digunakan untuk mengelola dan menjadwalkan tugas-tugas latar belakang, sehingga aplikasi bisa berjalan lebih efisien, terutama dalam mengelola daya dan konektivitas. salah satunya adalah AlarmManager

AlarmManager memungkinkan aplikasi untuk menjadwalkan tugas yang akan berjalan pada waktu tertentu, bahkan jika aplikasi dalam keadaan tertutup atau perangkat sedang tidur. Ini cocok untuk tugas-tugas yang harus dieksekusi pada waktu yang pasti, seperti mengirimkan pengingat kepada pengguna pada waktu tertentu.

Penerapan AlarmManager

AlarmManager memerlukan Function untuk mengatur waktu pemicu Alarm nya dan class Receiver sebagai tempat kode task yang akan dijalankan saat alarm terpicu.

Berikut adalah contoh Function untuk mengatur waktu pemicu Alarm :

fun setAlarm(context:Context) {
  val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as   AlarmManagerval intent = Intent(context, MyAlarmReceiver::class.java)
  val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0)
  val triggerTime = System.currentTimeMillis() + 60 * 1000 
// 1 menit dari sekarang
  alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent)
}

Setelah itu buat class Receiver nya. contoh class Receiver nya adalah sebagai berikut

class MyAlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent?) {
        // Lakukan tugas yang diperlukan ketika alarm dipicu
    }
}

Daftarkan class Receiver nya di AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
...
 <application 
  ...>
  <receiver
     android:name=".MyAlarmReceiver"
     android:enabled="true"
     android:exported="true" />
 </application>
  ...
</manifest>

Dengan setExact, AlarmManager akan menjalankan alarm pada waktu yang tepat. Namun, jika tugas Anda tidak membutuhkan ketepatan waktu, setInexactRepeating dapat digunakan untuk mengurangi beban daya. selain setExact, bisa juga menggunakan setAlarmClock & setExactAndAllowWhileIdle untuk dapat menjalankan tugas tepat waktu.

setInexactRepeating bisa menjalankan tugas berulang tiap hari namun tidak tepat waktu. Jika anda ingin membuat tugas yang berulang tiap hari dengan waktu yang tepat anda bisa menggunakan setExact, setAlarmClock, dan setExactAndAllowWhileIdle dengan menambahkan kode untuk mengatur trigger AlarmManager dalam class Receiver nya setelah kode task selesai dijalankan.

Alarm Manager memerlukan Schedule & Alarm Permission di Android 14 ke atas jika ingin menggunakan AlarmManager yang memerlukan ketepatan waktu.

Langkah Mengatur izin Akses Schedule & Alarm :

Tambahkan SCHEDULE_EXACT_ALARM di AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest
....>

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

Buat kode untuk mengecek apakah Schedule Alarm bisa dilakukan

fun isCanSetAlarm(): Boolean {
    val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
            return alarmManager.canScheduleExactAlarms()
    }

    return true
}

Jika versi Android 14 keatas maka panggil function canScheduleExactAlarms() dari alarmManager untuk mengetahui apakah akses Schedule & Alarm sudah di izinkan.

Contoh penerapan pengecekan izin nya adalah sebagai berikut :

fun checkAlarm() {
  if (isCanSetAlarm()) {  
   // Jalankan kode untuk menyetel alarm
  } else {  
   // Akses tidak diizinkan, pergi ke pengaturan aplikasi  
   schedulePermissionLauncher.launch(
     Intent(
      Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM,     
      Uri.parse("package:com.yourapp.packagename")    
     )  
   )
  }
}

@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
private val schedulePermissionLauncher = registerForActivityResult(
    ActivityResultContracts.StartActivityForResult()
) { _ ->
    val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager    
    if (!alarmManager.canScheduleExactAlarms()) {
        // Akses tidak diizinkan
    }
}

Ketika perangkat Android melakukan reboot, semua alarm yang dijadwalkan dengan AlarmManager otomatis terhapus. Untuk memastikan alarm tetap berjalan setelah perangkat melakukan reboot, Anda harus menggunakan BroadcastReceiver yang mendengarkan BOOT_COMPLETED, lalu menjadwalkan ulang alarm setelah reboot.

Langkah-langkah Mengatur AlarmManager untuk Berfungsi Setelah Reboot

Tambahkan Izin BOOT_COMPLETED
Di Android, aplikasi harus memiliki izin RECEIVE_BOOT_COMPLETED untuk dapat menerima broadcast BOOT_COMPLETED. Tambahkan izin ini di file AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest
....>

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

Daftarkan Receiver untuk BOOT_COMPLETED
Tambahkan sebuah BroadcastReceiver di manifest untuk mendengarkan BOOT_COMPLETED. Dengan begitu, aplikasi dapat merespon ketika perangkat dihidupkan kembali dan menjadwalkan ulang alarm yang diperlukan.

<application ...>
    <receiver android:name=".BootReceiver" android:enabled="true" android:exported="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
</application>

Implementasi BootReceiver
BootReceiver akan menerima broadcast ketika perangkat dihidupkan kembali. Dalam kode ini, Anda dapat menjadwalkan ulang alarm menggunakan AlarmManager.

class BootReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent?) {
        if (intent?.action == Intent.ACTION_BOOT_COMPLETED) {
            // Panggil fungsi untuk menjadwalkan ulang alarm
            scheduleAlarm(context)
        }
    }

    private fun scheduleAlarm(context: Context) {
        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val intent = Intent(context, MyAlarmReceiver::class.java)
        val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)

        // Contoh menjadwalkan alarm ineksak dengan interval harian
        alarmManager.setInexactRepeating(
            AlarmManager.RTC_WAKEUP,
            System.currentTimeMillis() + AlarmManager.INTERVAL_DAY, // Alarm pertama dimulai besok
            AlarmManager.INTERVAL_DAY, // Ulangi setiap hari
            pendingIntent
        )
    }
}

Dengan penerapan di atas, alarm akan dijadwalkan ulang setiap kali perangkat reboot, sehingga aplikasi dapat tetap menjalankan tugas secara teratur sesuai dengan jadwal yang diinginkan.

Selain menggunakan AlarmManager, kita juga bisa menggunakan JobScheduler dan WorkManager untuk menjadwalkan tugas. namun jika anda ingin ketepatan waktu dalam menjalankan tugas, AlarmManager adalah pilihan yang tepat.
Namun perlu diperhatikan AlarmManager dengan tugas tepat waktu dapat mengurangi daya perangkat karena hal ini mengabaikan opsi penghematan baterai dari perangkat.

Published by Ahmad Saifur Ridlo

Android Developer at Algostudio.net