AlarmManager: kluczowe pojęcia i praca z alarmami

Autor: IT Sectr Opublikowano: 2026-03-28 Czas czytania: 8 min

AlarmManager — to systemowa usługa Androida, która pozwala aplikacjom wykonywać zadania o określonej porze, nawet jeśli aplikacja nie jest uruchomiona lub urządzenie znajduje się w trybie uśpienia. W przeciwieństwie do JobScheduler czy WorkManager, AlarmManager gwarantuje precyzyjne wyzwalanie, co czyni go niezastąpionym dla budzików, przypomnień kalendarzowych i zadań krytycznych czasowo. Według Android Developers, 2026, począwszy od Androida 4.4 setRepeating działa jako niedokładne powtórzenie, a do precyzyjnych alarmów wymagany jest setExact lub setAlarmClock.

Najważniejsze

  • AlarmManager — to systemowa usługa Androida do wykonywania zadań o dokładnym czasie, działająca nawet w trybie uśpienia.
  • Typy alarmów obejmują ELAPSED_REALTIME, RTC, ELAPSED_REALTIME_WAKEUP i RTC_WAKEUP — z budzeniem i bez.
  • setExact gwarantuje precyzyjne wyzwolenie na Androidzie 4.4+, ale zużywa więcej baterii.
  • setAlarmClock — jedyna metoda, którą system gwarantowanie wykonuje na czas na Androidzie 6+.
  • Począwszy od Androida 12 do precyzyjnych alarmów wymagane jest pozwolenie SCHEDULE_EXACT_ALARM.

Czym jest AlarmManager?

AlarmManager — to systemowa usługa Androida udostępniająca API do planowania zadań z dokładnym lub przybliżonym czasem wykonania. Istnieje od pierwszej wersji Androida i pozostaje jedynym niezawodnym sposobem na wykonanie kodu w określonym momencie, niezależnie od stanu aplikacji i urządzenia.

Zasada działania jest prosta: aplikacja wysyła do systemu PendingIntent z określeniem czasu wyzwolenia. Gdy nadejdzie odpowiedni moment, system wysyła Intent do zarejestrowanego BroadcastReceiver lub uruchamia Service. Nawet jeśli urządzenie było w trybie uśpienia, WakeLock pozwala procesorowi obudzić się i przetworzyć zdarzenie.

Główny obszar zastosowania AlarmManager — zadania wymagające dokładnego czasu: budziki, przypomnienia kalendarzowe, uruchamianie długotrwałych operacji o określonej godzinie. Do zadań, gdzie precyzja nie jest krytyczna (synchronizacja raz dziennie), Google zaleca WorkManager lub JobScheduler, ponieważ są bardziej energooszczędne.

Jak działa AlarmManager?

AlarmManager otrzymuje od aplikacji PendingIntent i czas wyzwolenia. System zapisuje to żądanie w swoim wewnętrznym planiście i budzi procesor o określonej porze, aby dostarczyć Intent. Deweloper musi wcześniej zarejestrować BroadcastReceiver, który obsłuży ten Intent.

Typy alarmów

AlarmManager obsługuje 4 typy alarmów: ELAPSED_REALTIME (czas od uruchomienia, nie budzi), RTC (czas rzeczywisty, nie budzi), ELAPSED_REALTIME_WAKEUP (czas od uruchomienia, budzi urządzenie) i RTC_WAKEUP (czas rzeczywisty, budzi). Wersje WAKEUP są niezbędne, jeśli zadanie ma się wykonać, nawet gdy urządzenie śpi.

TypCzasBudziPrzykład
ELAPSED_REALTIMEod uruchomienianielicznik czasu pracy
RTCUnix timestampnielogowanie
ELAPSED_REALTIME_WAKEUPod uruchomieniatakzadanie okresowe
RTC_WAKEUPUnix timestamptakbudzik

Uprawnienia i prawa

Począwszy od Androida 12 (API 31), do używania precyzyjnych alarmów (setExact) wymagane jest pozwolenie SCHEDULE_EXACT_ALARM. Użytkownik może je cofnąć w ustawieniach. Dla aplikacji, które potrzebują precyzyjnego alarmu z wyświetlaniem (np. zegar), używane jest USE_EXACT_ALARM, przyznawane podczas instalacji.

Metody set, setRepeating i setExact

AlarmManager udostępnia trzy główne metody planowania zadań. Wybór metody określa precyzję wyzwolenia i wpływ na zużycie energii urządzenia.

set — podstawowa metoda jednorazowego niedokładnego wyzwolenia. System może przesunąć czas o kilka minut w celu grupowania z innymi zdarzeniami. Nadaje się do zadań, gdzie precyzja nie jest krytyczna: przypomnienie o konieczności wejścia do aplikacji.

setRepeating — metoda do okresowych powtórzeń. Począwszy od Androida 4.4 (API 19) setRepeating stał się niedokładny — interwały mogą się zmieniać. System nie gwarantuje już stałego okresu. Zamiast setRepeating zaleca się używanie setExact z ponownym planowaniem lub WorkManager z PeriodicWorkRequest.

setExact — metoda do precyzyjnego jednorazowego wyzwolenia. System budzi urządzenie w czasie jak najbliższym określonemu. setAlarmClock — szczególny przypadek setExact, który dodatkowo pokazuje ikonę budzika na pasku statusu i ma najwyższy priorytet spośród wszystkich typów alarmów.

kotlin
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager

// Precyzyjny pojedynczy alarm
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
    this, 0, intent,
    PendingIntent.FLAG_IMMUTABLE
)

alarmManager.setAlarmClock(
    AlarmManager.AlarmClockInfo(
        targetTime, pendingIntent
    ),
    pendingIntent
)

Przykład użycia AlarmManager

Typowy scenariusz — tworzenie codziennego przypomnienia o określonej porze. W tym celu używany jest RTC_WAKEUP z setExact. Po wyzwoleniu BroadcastReceiver uruchamia powiadomienie lub Service. Po przetworzeniu należy zaplanować zadanie ponownie na następny dzień.

kotlin
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("Przypomnienie")
            .setContentText("Czas wykonać zadanie")
            .setSmallIcon(R.drawable.ic_reminder)
            .build()

        notificationManager.notify(1001, notification)
    }
}

Do codziennego powtarzania używany jest setExact z obliczeniem następnego wyzwolenia. W Intent można przekazać flagi do identyfikacji różnych typów przypomnień. Upewnij się, że BroadcastReceiver jest zarejestrowany w AndroidManifest.xml z obsługą akcji WAKEUP.

kotlin
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
    )
}

Optymalizacja i zalecenia

AlarmManager — potężne, ale energochłonne narzędzie. Każdy alarm WAKEUP wybudza urządzenie z trybu uśpienia, co zużywa baterię. Google zaleca minimalizowanie użycia precyzyjnych alarmów i preferowanie setExactAndAllowWhileIdle na Androidzie 6+ w celu zmniejszenia wpływu na Doze Mode. Do zadań okresowych bez wymogu precyzji używaj WorkManager z PeriodicWorkRequest, który nie wymaga budzenia urządzenia i nie zużywa baterii przy każdym uruchomieniu.

Testowanie AlarmManager w testach jednostkowych

Do testowania AlarmManager używaj TestAlarmManager z Android Test Framework. Pozwala on emulować wyzwolenie alarmu bez oczekiwania na rzeczywisty czas. W Robolectric dostępny jest ShadowAlarmManager, który przechwytuje wywołania set, setExact i setRepeating, udostępniając metody do wymuszonego wyzwolenia i sprawdzania liczby zaplanowanych zadań. Do testów jednostkowych BroadcastReceiver używaj Robolectric.getForegroundScheduler(). Dostępny jest również test Espresso z IdlingResource, który oczekuje na wyzwolenie alarmu w testach integracyjnych.

Migracja z AlarmManager na WorkManager

Jeśli aplikacja używa AlarmManager do zadań okresowych niewymagających dokładnego czasu, rozważ migrację na WorkManager. PeriodicWorkRequest z minimalnym interwałem 15 minut zastępuje setRepeating, przy czym WorkManager gwarantuje wykonanie po ponownym uruchomieniu, obsługuje Doze Mode i nie wymaga pozwolenia SCHEDULE_EXACT_ALARM. Do zadań krytycznych czasowo (budzik na 7 rano) AlarmManager pozostaje jedynym właściwym wyborem. Optymalna strategia — używać AlarmManager tylko do budzików z setAlarmClock, a wszystkie inne zadania w tle przenieść na WorkManager.

Do zadań okresowych bez wymogu precyzji używaj WorkManager z PeriodicWorkRequest. Do zadań z dokładnym czasem, ale niekrytycznych do wyzwolenia w trybie uśpienia — setExact bez WAKEUP. I tylko do budzików z obowiązkowym budzeniem — setAlarmClock lub RTC_WAKEUP.

Ważne jest również sprawdzanie obecności pozwolenia SCHEDULE_EXACT_ALARM na Androidzie 12+. Jeśli pozwolenie nie zostało przyznane, setExact będzie działać jak zwykły set (niedokładnie). Używaj AlarmManager.canScheduleExactAlarms() do sprawdzenia. W przypadku braku pozwolenia można zaproponować użytkownikowi przejście do ustawień przez Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM).

Obsługa BOOT_COMPLETED do przywracania alarmów

Krytycznie ważna cecha AlarmManager — wszystkie zaplanowane alarmy są resetowane po ponownym uruchomieniu urządzenia. Do ich przywrócenia należy zadeklarować BroadcastReceiver obsługujący Intent.ACTION_BOOT_COMPLETED i zaplanować ponownie wszystkie aktywne alarmy w metodzie onReceive. Bez tego użytkownik straci wszystkie przypomnienia po wyłączeniu i włączeniu telefonu.

kotlin
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)
            }
        }
    }
}

W praktyce AlarmManager pozostaje najlepszym rozwiązaniem dla aplikacji budzików, kalendarzy, przypomnień o przyjmowaniu leków i wszelkich zadań, gdzie czas wyzwolenia jest krytyczny dla użytkownika. Dla wszystkich innych scenariuszy pracy w tle preferowane są WorkManager lub JobScheduler.

Przy wyborze między AlarmManager a WorkManager kieruj się zasadą: jeśli użytkownik wyraźnie poprosił o przypomnienie o 14:30 — użyj AlarmManager z setAlarmClock. Jeśli zadanie ma się wykonać „mniej więcej raz na godzinę" — WorkManager z PeriodicWorkRequest będzie bardziej energooszczędny i niezawodny.

Często zadawane pytania

Jaka jest różnica między setExact a setAlarmClock?

Obie metody gwarantują precyzyjne wyzwolenie, ale setAlarmClock dodatkowo pokazuje ikonę budzika na pasku statusu i informuje system, że to alarm dla użytkownika. Na Androidzie 6+ setAlarmClock ma odporność na Doze Mode, podczas gdy setExact może być opóźniony.

Jak AlarmManager zachowuje się po ponownym uruchomieniu urządzenia?

Po ponownym uruchomieniu wszystkie zaplanowane alarmy są resetowane. Do przywrócenia należy zarejestrować BroadcastReceiver dla akcji BOOT_COMPLETED i zaplanować ponownie wszystkie zadania w onReceive. Bez tego żaden alarm nie zadziała po włączeniu urządzenia.

Dlaczego setRepeating nie jest zalecany na Androidzie 4.4+?

Począwszy od API 19 setRepeating stał się niedokładny — system może przesuwać interwały w celu oszczędzania energii. Zamiast tego używaj setExact z ręcznym ponownym planowaniem lub WorkManager z PeriodicWorkRequest, który zapewnia bardziej przewidywalne zachowanie.

Jakie pozwolenie jest potrzebne do precyzyjnych alarmów na Androidzie 12+?

Dla setExact wymagane jest pozwolenie SCHEDULE_EXACT_ALARM, które użytkownik może przyznać lub cofnąć w ustawieniach. Dla setAlarmClock z wyświetlaniem w interfejsie zegara używane jest USE_EXACT_ALARM, przyznawane automatycznie podczas instalacji ze sklepu.

Czy można używać AlarmManager bez PendingIntent?

Nie, AlarmManager zawsze działa przez PendingIntent. Może to być PendingIntent.getBroadcast dla BroadcastReceiver, PendingIntent.getService dla Service lub PendingIntent.getActivity dla Activity. Bez PendingIntent system nie będzie w stanie dostarczyć zdarzenia do aplikacji.

Podsumowanie

  • AlarmManager — systemowa usługa Androida do wykonywania zadań o dokładnym czasie z możliwością budzenia urządzenia.
  • Cztery typy alarmów — ELAPSED_REALTIME, RTC, ELAPSED_REALTIME_WAKEUP i RTC_WAKEUP — pokrywają różne scenariusze.
  • setExact i setAlarmClock — jedyne metody precyzyjnego wyzwolenia na nowoczesnych wersjach Androida.
  • setRepeating jest przestarzały na Androidzie 4.4+ — używaj setExact z ręcznym ponownym planowaniem.
  • Pozwolenie SCHEDULE_EXACT_ALARM jest obowiązkowe na Androidzie 12+ do precyzyjnych alarmów.
  • WorkManager lub JobScheduler są preferowane do niedokładnych zadań w tle bez wymogu czasowego.
  • Nie zapomnij obsłużyć BOOT_COMPLETED do przywracania alarmów po ponownym uruchomieniu urządzenia.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również