AlarmManager — tətbiqlərə müəyyən vaxtda tapşırıqları yerinə yetirməyə imkan verən Android sistem xidmətidir, hətta tətbiq işə salınmasa və ya cihaz yuxu rejimində olsa belə. JobScheduler və ya WorkManager-dən fərqli olaraq, AlarmManager dəqiq işə düşməyə zəmanət verir ki, bu da onu siqnallar, təqvim xatırlatmaları və vaxt baxımından kritik tapşırıqlar üçün əvəzolunmaz edir. Android Developers, 2026 məlumatına görə, Android 4.4-dən etibarən setRepeating qeyri-dəqiq təkrarlama kimi davranır və dəqiq siqnallar üçün setExact və ya setAlarmClock tələb olunur.
Əsas məqamlar
AlarmManager — dəqiq və ya təxmini icra vaxtı ilə tapşırıqları planlaşdırmaq üçün API təmin edən Android sistem xidmətidir. Android-in ilk versiyasından mövcuddur və tətbiqin və cihazın vəziyyətindən asılı olmayaraq müəyyən bir zamanda kodu icra etməyin yeganə etibarlı yolu olaraq qalır.
İş prinsipi sadədir: tətbiq sistemə işə düşmə vaxtını göstərən PendingIntent göndərir. Lazımi an gəldikdə, sistem qeydiyyatdan keçmiş BroadcastReceiver-ə Intent göndərir və ya Service-i işə salır. Cihaz yuxu rejimində olsa belə, WakeLock prosessorun oyanmasına və hadisəni emal etməsinə imkan verir.
AlarmManager-in əsas tətbiq sahəsi — dəqiq vaxt tələb edən tapşırıqlar: siqnallar, təqvim xatırlatmaları, müəyyən saatda uzunmüddətli əməliyyatların başladılması. Dəqiqliyin kritik olmadığı tapşırıqlar üçün (gündə bir dəfə sinxronizasiya) Google WorkManager və ya JobScheduler tövsiyə edir, çünki onlar daha enerji effektivdir.
AlarmManager tətbiqdən PendingIntent və işə düşmə vaxtını alır. Sistem bu sorğunu öz daxili planlayıcısında saxlayır və Intent-i çatdırmaq üçün göstərilən vaxtda prosessoru oyadır. Tərtibatçı bu Intent-i emal edəcək BroadcastReceiver-i əvvəlcədən qeydiyyatdan keçirməlidir.
AlarmManager 4 növ siqnalı dəstəkləyir: ELAPSED_REALTIME (yüklənmədən vaxt, oyatmır), RTC (real vaxt, oyatmır), ELAPSED_REALTIME_WAKEUP (yüklənmədən vaxt, cihazı oyadır) və RTC_WAKEUP (real vaxt, oyadır). WAKEUP versiyaları tapşırıq cihaz yatarkən belə yerinə yetirilməlidirsə, lazımdır.
| Növ | Vaxt | Oyadır | Nümunə |
|---|---|---|---|
| ELAPSED_REALTIME | yüklənmədən | yox | iş vaxtı taymeri |
| RTC | Unix timestamp | yox | loglama |
| ELAPSED_REALTIME_WAKEUP | yüklənmədən | bəli | dövri tapşırıq |
| RTC_WAKEUP | Unix timestamp | bəli | siqnal |
Android 12-dən (API 31) başlayaraq, dəqiq siqnallardan (setExact) istifadə etmək üçün SCHEDULE_EXACT_ALARM icazəsi tələb olunur. İstifadəçi onu parametrlərdən geri götürə bilər. Göstərilən dəqiq siqnal tələb edən tətbiqlər üçün (məsələn, saat) quraşdırma zamanı verilən USE_EXACT_ALARM istifadə olunur.
AlarmManager tapşırıqları planlaşdırmaq üçün üç əsas metodu təmin edir. Metod seçimi işə düşmə dəqiqliyini və cihazın enerji istehlakına təsirini müəyyən edir.
set — birdəfəlik qeyri-dəqiq işə düşmə üçün əsas metod. Sistem digər hadisələrlə qruplaşdırmaq üçün vaxtı bir neçə dəqiqə dəyişə bilər. Dəqiqliyin kritik olmadığı tapşırıqlar üçün uyğundur: tətbiqə daxil olmağı xatırlatma.
setRepeating — dövri təkrarlar üçün metod. Android 4.4-dən (API 19) başlayaraq setRepeating qeyri-dəqiq oldu — intervallar dəyişə bilər. Sistem artıq sabit dövrə zəmanət vermir. setRepeating əvəzinə əl ilə yenidən planlaşdırma ilə setExact və ya PeriodicWorkRequest ilə WorkManager istifadə etmək tövsiyə olunur.
setExact — dəqiq birdəfəlik işə düşmə üçün metod. Sistem cihazı göstərilən vaxta mümkün qədər yaxın oyadır. setAlarmClock — setExact-in xüsusi halıdır, status panelində siqnal ikonasını göstərir və bütün siqnal növləri arasında ən yüksək prioritetə malikdir.
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
// Dəqiq birdəfəlik siqnal
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
this, 0, intent,
PendingIntent.FLAG_IMMUTABLE
)
alarmManager.setAlarmClock(
AlarmManager.AlarmClockInfo(
targetTime, pendingIntent
),
pendingIntent
)
Tipik ssenari — müəyyən vaxtda gündəlik xatırlatmanın yaradılması. Bunun üçün RTC_WAKEUP setExact ilə istifadə olunur. İşə düşdükdə BroadcastReceiver bildiriş və ya Service-i işə salır. Emaldan sonra tapşırığı növbəti günə yenidən planlaşdırmaq lazımdır.
class ReminderReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE)
as NotificationManager
val notification = NotificationCompat.Builder(
context, "reminder_channel"
)
.setContentTitle("Xatırlatma")
.setContentText("Tapşırığı yerinə yetirmə vaxtıdır")
.setSmallIcon(R.drawable.ic_reminder)
.build()
notificationManager.notify(1001, notification)
}
}
Hər gün təkrarlamaq üçün setExact növbəti işə düşmənin hesablanması ilə istifadə olunur. Intent-də müxtəlif xatırlatma növlərini identifikasiya etmək üçün flaglar ötürmək olar. BroadcastReceiver-in AndroidManifest.xml-də WAKEUP aksiyasının emalı ilə qeydiyyatdan keçdiyinə əmin olun.
fun scheduleDailyReminder(context: Context, hour: Int, minute: Int) {
val calendar = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, hour)
set(Calendar.MINUTE, minute)
set(Calendar.SECOND, 0)
if (before(Calendar.getInstance())) {
add(Calendar.DAY_OF_MONTH, 1)
}
}
val alarmManager =
context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
pendingIntent
)
}
AlarmManager — güclü, lakin enerji sərf edən alətdir. Hər WAKEUP siqnalı cihazı yuxu rejimindən çıxarır ki, bu da batareyanı boşaldır. Google dəqiq siqnalların istifadəsini minimuma endirməyi və Doze Mode-a təsiri azaltmaq üçün Android 6+-da setExactAndAllowWhileIdle-a üstünlük verməyi tövsiyə edir. Dəqiqlik tələb etməyən dövri tapşırıqlar üçün PeriodicWorkRequest ilə WorkManager istifadə edin, o cihazı oyatmağı tələb etmir və hər işə salınmada batareya sərf etmir.
AlarmManager-i sınamaq üçün Android Test Framework-dən TestAlarmManager istifadə edin. O, real vaxtı gözləmədən siqnalın işə düşməsini simulyasiya etməyə imkan verir. Robolectric-də set, setExact və setRepeating çağırışlarını ələ keçirən ShadowAlarmManager mövcuddur, məcburi işə düşmə və planlaşdırılmış tapşırıqların sayını yoxlamaq üçün metodlar təmin edir. BroadcastReceiver-in vahid testləri üçün Robolectric.getForegroundScheduler() istifadə edin. İnteqrasiya testlərində siqnalın işə düşməsini gözləyən IdlingResource ilə Espresso testi də mövcuddur.
Əgər tətbiq dəqiq vaxt tələb etməyən dövri tapşırıqlar üçün AlarmManager istifadə edirsə, WorkManager-ə miqrasiyanı nəzərdən keçirin. Minimal intervalı 15 dəqiqə olan PeriodicWorkRequest setRepeating-i əvəz edir, WorkManager yenidən başlatmadan sonra icraya zəmanət verir, Doze Mode-u emal edir və SCHEDULE_EXACT_ALARM icazəsi tələb etmir. Vaxt baxımından kritik tapşırıqlar üçün (səhər 7-də siqnal) AlarmManager yeganə düzgün seçim olaraq qalır. Optimal strategiya — AlarmManager-i yalnız setAlarmClock ilə siqnallar üçün istifadə etmək, bütün digər fon tapşırıqlarını WorkManager-ə köçürmək.
Dəqiqlik tələb etməyən dövri tapşırıqlar üçün WorkManager-i PeriodicWorkRequest ilə istifadə edin. Dəqiq vaxt tələb edən, lakin yuxu rejimində işə düşməsi kritik olmayan tapşırıqlar üçün — WAKEUP-sız setExact. Və yalnız məcburi oyatma ilə siqnallar üçün — setAlarmClock və ya RTC_WAKEUP.
Həmçinin Android 12+-da SCHEDULE_EXACT_ALARM icazəsinin mövcudluğunu yoxlamaq vacibdir. İcazə verilməyibsə, setExact adi set kimi işləyəcək (qeyri-dəqiq). Yoxlamaq üçün AlarmManager.canScheduleExactAlarms() istifadə edin. İcazə olmadıqda, istifadəçiyə Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM) vasitəsilə parametrlərə keçməyi təklif edə bilərsiniz.
AlarmManager-in kritik vacib xüsusiyyəti — bütün planlaşdırılmış siqnallar cihaz yenidən başladıldıqdan sonra sıfırlanır. Onları bərpa etmək üçün Intent.ACTION_BOOT_COMPLETED-i emal edən BroadcastReceiver bəyan etmək və onReceive metodunda bütün aktiv siqnalları yenidən planlaşdırmaq lazımdır. Bu olmadan istifadəçi telefonu söndürüb açdıqdan sonra bütün xatırlatmalarını itirəcək.
class BootReceiver : BroadcastReceiver() {
override fun onReceive(
context: Context,
intent: Intent
) {
if (intent.action ==
Intent.ACTION_BOOT_COMPLETED
) {
val prefs =
context.getSharedPreferences("alarms", 0)
val savedTime =
prefs.getLong("next_alarm", 0L)
if (savedTime > System.currentTimeMillis()) {
scheduleReminder(context, savedTime)
}
}
}
}
Praktikada AlarmManager siqnal tətbiqləri, təqvimlər, dərman qəbulu xatırlatmaları və istifadəçi üçün işə düşmə vaxtının kritik olduğu hər hansı tapşırıqlar üçün ən yaxşı həll olaraq qalır. Bütün digər fon iş ssenariləri üçün WorkManager və ya JobScheduler üstünlük təşkil edir.
AlarmManager və WorkManager arasında seçim edərkən qaydaya əməl edin: əgər istifadəçi açıq şəkildə saat 14:30-da xatırlatma istəyibsə — setAlarmClock ilə AlarmManager istifadə edin. Tapşırıq „təxminən saatda bir dəfə" yerinə yetirilməlidirsə — PeriodicWorkRequest ilə WorkManager daha enerji effektiv və etibarlı olacaq.
Tez-tez verilən suallar
Hər iki metod dəqiq işə düşməyə zəmanət verir, lakin setAlarmClock əlavə olaraq status panelində siqnal ikonasını göstərir və sistemə bunun istifadəçi üçün siqnal olduğunu bildirir. Android 6+-da setAlarmClock Doze Mode-dan immunitetə malikdir, setExact isə gecikdirilə bilər.
Yenidən başlatmadan sonra bütün planlaşdırılmış siqnallar sıfırlanır. Bərpa etmək üçün BOOT_COMPLETED aksiyası üçün BroadcastReceiver qeydiyyatdan keçirmək və onReceive-də bütün tapşırıqları yenidən planlaşdırmaq lazımdır. Bu olmadan cihaz işə salındıqdan sonra heç bir siqnal işləməyəcək.
API 19-dan başlayaraq setRepeating qeyri-dəqiq oldu — sistem enerjiyə qənaət etmək üçün intervalları dəyişə bilər. Bunun əvəzinə əl ilə yenidən planlaşdırma ilə setExact və ya daha proqnozlaşdırıla bilən davranış təmin edən PeriodicWorkRequest ilə WorkManager istifadə edin.
setExact üçün istifadəçinin parametrlərdə verə və ya geri götürə biləcəyi SCHEDULE_EXACT_ALARM icazəsi tələb olunur. Saat interfeysində göstərilən setAlarmClock üçün mağazadan quraşdırma zamanı avtomatik verilən USE_EXACT_ALARM istifadə olunur.
Xeyr, AlarmManager həmişə PendingIntent vasitəsilə işləyir. Bu BroadcastReceiver üçün PendingIntent.getBroadcast, Service üçün PendingIntent.getService və ya Activity üçün PendingIntent.getActivity ola bilər. PendingIntent olmadan sistem hadisəni tətbiqə çatdıra bilməyəcək.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun