Будильник в Android на Kotlin: полный разбор Alarm Manager для новичков

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Как работает Alarm Manager в Android? Полный разбор на Kotlin с реальным примером

Вы когда-нибудь задумывались, как работают будильники в вашем телефоне? Или как приложение для заметок напоминает вам о встрече ровно в 14:30? В Android за это отвечает мощный системный сервис — Alarm Manager. Хотя его название переводится как «менеджер будильников», на самом деле это универсальный планировщик задач, который позволяет запускать код в определённое время, даже если ваше приложение свёрнуто или телефон находится в режиме сна.

Тема Alarm Manager Example — один из самых популярных запросов на StackOverflow (тысячи просмотров и десятки вопросов). И это неудивительно: новички часто путаются в PendingIntent, BroadcastReceiver и многочисленных методах типа set(), setRepeating() или setExact(). В этой статье мы разберём реальный рабочий пример на Kotlin, который вы сможете сразу применить в своём проекте. Никакой воды — только код и объяснения.

Что такое Alarm Manager и зачем он нужен?

Alarm Manager — это системный сервис Android, который позволяет вашему приложению выполнять действия в заданное время. Главная фишка в том, что он работает независимо от жизненного цикла вашего приложения. Вы можете установить будильник, закрыть приложение, выключить экран — и Alarm Manager всё равно выполнит задачу в нужный момент.

Типичные сценарии использования:

  • Напоминания о событиях (встречи, дни рождения)
  • Периодическая синхронизация данных с сервером
  • Отложенные уведомления (например, «Не забудьте выпить воду через 2 часа»)
  • Выполнение фоновых задач по расписанию

Важно понимать: Alarm Manager не является точным таймером для миллисекундных интервалов. Для этого есть Handler или Coroutines. Alarm Manager оптимизирован для работы на уровне системы с учётом энергосбережения.

Основные компоненты: PendingIntent и BroadcastReceiver

Прежде чем писать код, разберёмся с двумя ключевыми понятиями, без которых Alarm Manager не работает.

PendingIntent — это «отложенное намерение». Вы не запускаете действие сразу, а упаковываете его в специальный контейнер, который Alarm Manager выполнит в будущем. Представьте, что вы даёте курьеру запечатанный конверт с инструкцией: «Открой ровно в 15:00». Конверт — это PendingIntent.

BroadcastReceiver — это приёмник широковещательных сообщений. Когда Alarm Manager срабатывает, он отправляет широковещательное сообщение (broadcast), которое ловит ваш BroadcastReceiver. Именно в нём вы пишете код, который должен выполниться по будильнику.

Пошаговый пример: создаём будильник на Kotlin

Давайте напишем простое приложение, которое показывает уведомление через 10 секунд после нажатия кнопки. Этот пример основан на реальном коде из популярного ответа на StackOverflow.

Шаг 1. Создаём BroadcastReceiver

Создайте новый класс, который будет обрабатывать срабатывание будильника:

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.widget.Toast

class AlarmReceiver : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        // Этот код выполнится, когда сработает будильник
        Toast.makeText(context, "Будильник сработал!", Toast.LENGTH_LONG).show()
    }
}

Пока что мы просто показываем Toast. В реальном приложении здесь может быть создание уведомления, запуск сервиса или любой другой код.

Шаг 2. Регистрируем BroadcastReceiver в манифесте

Чтобы система знала о нашем приёмнике, его нужно зарегистрировать в AndroidManifest.xml:

<receiver android:name=".AlarmReceiver" />

Если вы используете Android 12+ и ваш будильник должен срабатывать точно, добавьте также разрешение:

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

Шаг 3. Создаём Alarm Manager и устанавливаем будильник

Теперь самое интересное — код, который запускает Alarm Manager. Добавьте этот метод в вашу Activity или Fragment:

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.SystemClock
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val btnSetAlarm: Button = findViewById(R.id.btnSetAlarm)
        btnSetAlarm.setOnClickListener {
            setAlarm()
        }
    }

    private fun setAlarm() {
        // 1. Получаем системный сервис AlarmManager
        val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager

        // 2. Создаём Intent, который будет отправлен при срабатывании
        val intent = Intent(this, AlarmReceiver::class.java)

        // 3. Оборачиваем Intent в PendingIntent
        // FLAG_IMMUTABLE обязателен для Android 12+
        val pendingIntent = PendingIntent.getBroadcast(
            this,
            0, // requestCode (уникальный идентификатор)
            intent,
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )

        // 4. Устанавливаем будильник через 10 секунд от текущего момента
        val triggerTime = SystemClock.elapsedRealtime() + 10_000 // 10 секунд

        // Для точного срабатывания используем setExactAndAllowWhileIdle
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            alarmManager.setExactAndAllowWhileIdle(
                AlarmManager.ELAPSED_REALTIME_WAKEUP,
                triggerTime,
                pendingIntent
            )
        } else {
            alarmManager.setExact(
                AlarmManager.ELAPSED_REALTIME_WAKEUP,
                triggerTime,
                pendingIntent
            )
        }
    }
}

Разбор ключевых моментов:

  • AlarmManager.ELAPSED_REALTIME_WAKEUP — тип будильника, который отсчитывает время от момента загрузки устройства и пробуждает телефон, если он спит.
  • SystemClock.elapsedRealtime() — возвращает количество миллисекунд с момента загрузки системы. Это надёжный способ, не зависящий от изменений системного времени.
  • setExactAndAllowWhileIdle() — метод, который гарантирует максимально точное срабатывание, даже если устройство находится в режиме энергосбережения (Doze mode).
  • PendingIntent.FLAG_IMMUTABLE — обязательный флаг для Android 12+, который делает PendingIntent неизменяемым (безопасность).

Как отменить будильник?

Отмена будильника — это частая задача. Для этого нужно создать точно такой же PendingIntent и вызвать метод

Блоги

Рекомендаций по книгам