AlarmManager: مفاهیم کلیدی و کار با هشدارها

نویسنده: IT Sectr منتشر شده: 2026-03-28 زمان مطالعه: 8 دقیقه

AlarmManager — یک سرویس سیستمی Android است که به برنامه‌ها اجازه می‌دهد وظایف را در زمان مشخصی اجرا کنند، حتی اگر برنامه اجرا نشده باشد یا دستگاه در حالت خواب باشد. برخلاف JobScheduler یا WorkManager، AlarmManager دقت اجرا را تضمین می‌کند که آن را برای هشدارها، یادآوری‌های تقویمی و وظایف حساس به زمان ضروری می‌سازد. طبق Android Developers, 2026، از Android 4.4 به بعد setRepeating به‌عنوان تکرار نادقیق عمل می‌کند و برای هشدارهای دقیق به setExact یا setAlarmClock نیاز است.

نکات اصلی

  • AlarmManager — یک سرویس سیستمی Android برای اجرای وظایف در زمان دقیق است که حتی در حالت خواب کار می‌کند.
  • انواع هشدارها شامل ELAPSED_REALTIME، RTC، ELAPSED_REALTIME_WAKEUP و RTC_WAKEUP — با بیدار کردن و بدون آن.
  • setExact اجرای دقیق را در Android 4.4+ تضمین می‌کند، اما باتری بیشتری مصرف می‌کند.
  • setAlarmClock — تنها روشی است که سیستم در Android 6+ اجرای به‌موقع آن را تضمین می‌کند.
  • از Android 12 به بعد برای هشدارهای دقیق مجوز SCHEDULE_EXACT_ALARM الزامی است.

AlarmManager چیست؟

AlarmManager — یک سرویس سیستمی Android است که API برای برنامه‌ریزی وظایف با زمان اجرای دقیق یا تقریبی ارائه می‌دهد. از اولین نسخه Android وجود داشته و همچنان تنها راه قابل اعتماد برای اجرای کد در یک لحظه مشخص، صرف‌نظر از وضعیت برنامه و دستگاه است.

اصل کار ساده است: برنامه یک PendingIntent با زمان اجرا به سیستم ارسال می‌کند. وقتی لحظه مورد نظر فرا می‌رسد، سیستم Intent را به BroadcastReceiver ثبت‌شده ارسال می‌کند یا Service را راه‌اندازی می‌کند. حتی اگر دستگاه در حالت خواب بوده باشد، WakeLock به پردازنده اجازه بیدار شدن و پردازش رویداد را می‌دهد.

حوزه اصلی کاربرد AlarmManager — وظایفی که نیاز به زمان دقیق دارند: هشدارها، یادآوری‌های تقویمی، راه‌اندازی عملیات طولانی در ساعت مشخص. برای وظایفی که دقت در آنها حیاتی نیست (همگام‌سازی روزانه)، Google WorkManager یا JobScheduler را توصیه می‌کند زیرا آنها بهینه‌تر از نظر مصرف انرژی هستند.

AlarmManager چگونه کار می‌کند؟

AlarmManager از برنامه PendingIntent و زمان اجرا را دریافت می‌کند. سیستم این درخواست را در برنامه‌ریز داخلی خود ذخیره می‌کند و پردازنده را در زمان مشخص شده برای تحویل Intent بیدار می‌کند. توسعه‌دهنده باید از قبل BroadcastReceiver را ثبت کند که این Intent را پردازش کند.

انواع هشدارها

AlarmManager از 4 نوع هشدار پشتیبانی می‌کند: ELAPSED_REALTIME (زمان از راه‌اندازی، بیدار نمی‌کند)، RTC (زمان واقعی، بیدار نمی‌کند)، ELAPSED_REALTIME_WAKEUP (زمان از راه‌اندازی، دستگاه را بیدار می‌کند) و RTC_WAKEUP (زمان واقعی، بیدار می‌کند). نسخه‌های WAKEUP زمانی ضروری هستند که وظیفه باید حتی در حالت خواب دستگاه اجرا شود.

نوعزمانبیدار می‌کندمثال
ELAPSED_REALTIMEاز راه‌اندازیخیرتایمر مدت کار
RTCUnix timestampخیرثبت رویداد
ELAPSED_REALTIME_WAKEUPاز راه‌اندازیبلهوظیفه دوره‌ای
RTC_WAKEUPUnix timestampبلههشدار

مجوزها و حقوق

از Android 12 (API 31) به بعد، برای استفاده از هشدارهای دقیق (setExact) مجوز SCHEDULE_EXACT_ALARM الزامی است. کاربر می‌تواند آن را از طریق تنظیمات لغو کند. برای برنامه‌هایی که نیاز به هشدار دقیق با نمایش دارند (مثلاً ساعت)، از USE_EXACT_ALARM استفاده می‌شود که در زمان نصب اعطا می‌گردد.

روش‌های set، setRepeating و setExact

AlarmManager سه روش اصلی برای برنامه‌ریزی وظایف ارائه می‌دهد. انتخاب روش دقت اجرا و تأثیر بر مصرف انرژی دستگاه را تعیین می‌کند.

set — روش پایه برای اجرای یک‌باره نادقیق. سیستم می‌تواند زمان را تا چند دقیقه برای گروه‌بندی با رویدادهای دیگر جابجا کند. برای وظایفی که دقت در آنها حیاتی نیست مناسب است: یادآوری برای ورود به برنامه.

setRepeating — روش برای تکرار دوره‌ای. از Android 4.4 (API 19) به بعد setRepeating نادقیق شد — فواصل زمانی ممکن است تغییر کنند. سیستم دیگر دوره ثابت را تضمین نمی‌کند. به جای setRepeating توصیه می‌شود از setExact با برنامه‌ریزی مجدد دستی یا WorkManager با PeriodicWorkRequest استفاده کنید.

setExact — روش برای اجرای دقیق یک‌باره. سیستم دستگاه را در نزدیک‌ترین زمان ممکن به زمان مشخص شده بیدار می‌کند. setAlarmClock — حالت ویژه setExact است که همچنین آیکون هشدار را در نوار وضعیت نشان می‌دهد و بالاترین اولویت را در میان همه انواع هشدارها دارد.

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

// هشدار دقیق یک‌باره
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(
    this, 0, intent,
    PendingIntent.FLAG_IMMUTABLE
)

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

مثال استفاده از AlarmManager

سناریوی معمول — ایجاد یک یادآوری روزانه در زمان مشخص. برای این کار از RTC_WAKEUP با setExact استفاده می‌شود. هنگام اجرا، BroadcastReceiver یک اعلان یا Service را راه‌اندازی می‌کند. پس از پردازش، باید وظیفه را برای روز بعد دوباره برنامه‌ریزی کرد.

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("یادآوری")
            .setContentText("زمان انجام وظیفه فرا رسیده است")
            .setSmallIcon(R.drawable.ic_reminder)
            .build()

        notificationManager.notify(1001, notification)
    }
}

برای تکرار روزانه از setExact با محاسبه اجرای بعدی استفاده می‌شود. در Intent می‌توان flagهایی برای شناسایی انواع مختلف یادآوری‌ها ارسال کرد. اطمینان حاصل کنید که BroadcastReceiver در AndroidManifest.xml با پردازش action 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
    )
}

بهینه‌سازی و توصیه‌ها

AlarmManager — ابزاری قدرتمند اما پرمصرف از نظر انرژی است. هر هشدار WAKEUP دستگاه را از حالت خواب خارج می‌کند که باتری مصرف می‌کند. Google توصیه می‌کند استفاده از هشدارهای دقیق را به حداقل برسانید و در Android 6+ از setExactAndAllowWhileIdle برای کاهش تأثیر بر Doze Mode استفاده کنید. برای وظایف دوره‌ای بدون نیاز به دقت، از WorkManager با PeriodicWorkRequest استفاده کنید که نیازی به بیدار کردن دستگاه ندارد و در هر بار اجرا باتری مصرف نمی‌کند.

تست AlarmManager در تست‌های واحد

برای تست AlarmManager از TestAlarmManager موجود در Android Test Framework استفاده کنید. این امکان شبیه‌سازی اجرای هشدار بدون انتظار برای زمان واقعی را فراهم می‌کند. در Robolectric، ShadowAlarmManager در دسترس است که فراخوانی‌های set، setExact و setRepeating را رهگیری کرده و روش‌هایی برای اجرای اجباری و بررسی تعداد وظایف برنامه‌ریزی‌شده ارائه می‌دهد. برای تست‌های واحد BroadcastReceiver از Robolectric.getForegroundScheduler() استفاده کنید. همچنین تست Espresso با IdlingResource در دسترس است که در تست‌های یکپارچه‌سازی منتظر اجرای هشدار می‌ماند.

مهاجرت از AlarmManager به WorkManager

اگر برنامه از AlarmManager برای وظایف دوره‌ای بدون نیاز به زمان دقیق استفاده می‌کند، مهاجرت به WorkManager را در نظر بگیرید. PeriodicWorkRequest با حداقل فاصله ۱۵ دقیقه جایگزین setRepeating می‌شود، در حالی که WorkManager اجرا پس از راه‌اندازی مجدد را تضمین می‌کند، Doze Mode را مدیریت می‌کند و نیازی به مجوز SCHEDULE_EXACT_ALARM ندارد. برای وظایف حساس به زمان (هشدار ساعت ۷ صبح)، AlarmManager تنها انتخاب صحیح باقی می‌ماند. استراتژی بهینه — استفاده از AlarmManager فقط برای هشدارها با setAlarmClock، و انتقال تمام وظایف پس‌زمینه دیگر به WorkManager.

برای وظایف دوره‌ای بدون نیاز به دقت از WorkManager با PeriodicWorkRequest استفاده کنید. برای وظایف با زمان دقیق اما غیرحساس به اجرا در حالت خواب — setExact بدون WAKEUP. و فقط برای هشدارها با بیدار کردن اجباری — setAlarmClock یا RTC_WAKEUP.

همچنین بررسی وجود مجوز SCHEDULE_EXACT_ALARM در Android 12+ مهم است. اگر مجوز داده نشده باشد، setExact مانند set معمولی (نادقیق) کار می‌کند. برای بررسی از AlarmManager.canScheduleExactAlarms() استفاده کنید. در صورت عدم وجود مجوز، می‌توانید به کاربر پیشنهاد دهید از طریق Intent(Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM) به تنظیمات برود.

مدیریت BOOT_COMPLETED برای بازیابی هشدارها

ویژگی حیاتی AlarmManager — تمام هشدارهای برنامه‌ریزی‌شده پس از راه‌اندازی مجدد دستگاه بازنشانی می‌شوند. برای بازیابی آنها باید BroadcastReceiverای اعلام کنید که Intent.ACTION_BOOT_COMPLETED را پردازش کرده و تمام هشدارهای فعال را در متد onReceive دوباره برنامه‌ریزی کند. بدون این، کاربر پس از خاموش و روشن کردن تلفن، تمام یادآوری‌های خود را از دست خواهد داد.

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

در عمل AlarmManager بهترین راه‌حل برای برنامه‌های هشدار، تقویم‌ها، یادآوری‌های مصرف دارو و هر وظیفه‌ای که زمان اجرا برای کاربر حیاتی است باقی می‌ماند. برای تمام سناریوهای دیگر کار پس‌زمینه، WorkManager یا JobScheduler ترجیح داده می‌شوند.

هنگام انتخاب بین AlarmManager و WorkManager از این قانون پیروی کنید: اگر کاربر صریحاً درخواست یادآوری در ساعت ۱۴:۳۰ کرده است — از AlarmManager با setAlarmClock استفاده کنید. اگر وظیفه باید «تقریباً هر ساعت یک بار» اجرا شود — WorkManager با PeriodicWorkRequest بهینه‌تر و قابل اعتمادتر خواهد بود.

سوالات متداول

تفاوت بین setExact و setAlarmClock چیست؟

هر دو روش اجرای دقیق را تضمین می‌کنند، اما setAlarmClock علاوه بر این آیکون هشدار را در نوار وضعیت نشان می‌دهد و به سیستم اطلاع می‌دهد که این یک هشدار برای کاربر است. در Android 6+ setAlarmClock از Doze Mode مصون است، در حالی که setExact ممکن است به تأخیر بیفتد.

AlarmManager پس از راه‌اندازی مجدد دستگاه چگونه رفتار می‌کند؟

پس از راه‌اندازی مجدد، تمام هشدارهای برنامه‌ریزی‌شده بازنشانی می‌شوند. برای بازیابی باید یک BroadcastReceiver برای action BOOT_COMPLETED ثبت کنید و تمام وظایف را در onReceive دوباره برنامه‌ریزی کنید. بدون این، هیچ هشداری پس از روشن شدن دستگاه کار نخواهد کرد.

چرا setRepeating در Android 4.4+ توصیه نمی‌شود؟

از API 19 به بعد setRepeating نادقیق شد — سیستم ممکن است فواصل را برای صرفه‌جویی در انرژی تغییر دهد. به جای آن از setExact با برنامه‌ریزی مجدد دستی یا WorkManager با PeriodicWorkRequest استفاده کنید که رفتار قابل پیش‌بینی‌تری ارائه می‌دهد.

چه مجوزی برای هشدارهای دقیق در Android 12+ لازم است؟

برای setExact مجوز SCHEDULE_EXACT_ALARM لازم است که کاربر می‌تواند در تنظیمات اعطا یا لغو کند. برای setAlarmClock با نمایش در رابط ساعت از USE_EXACT_ALARM استفاده می‌شود که به طور خودکار هنگام نصب از فروشگاه اعطا می‌گردد.

آیا می‌توان از AlarmManager بدون PendingIntent استفاده کرد؟

خیر، AlarmManager همیشه از طریق PendingIntent کار می‌کند. این می‌تواند PendingIntent.getBroadcast برای BroadcastReceiver، PendingIntent.getService برای Service یا PendingIntent.getActivity برای Activity باشد. بدون PendingIntent سیستم نمی‌تواند رویداد را به برنامه تحویل دهد.

خلاصه

  • AlarmManager — سرویس سیستمی Android برای اجرای وظایف در زمان دقیق با امکان بیدار کردن دستگاه.
  • چهار نوع هشدار — ELAPSED_REALTIME، RTC، ELAPSED_REALTIME_WAKEUP و RTC_WAKEUP — سناریوهای مختلف را پوشش می‌دهند.
  • setExact و setAlarmClock — تنها روش‌های اجرای دقیق در نسخه‌های مدرن Android.
  • setRepeating در Android 4.4+ منسوخ شده است — از setExact با برنامه‌ریزی مجدد دستی استفاده کنید.
  • مجوز SCHEDULE_EXACT_ALARM در Android 12+ برای هشدارهای دقیق الزامی است.
  • WorkManager یا JobScheduler برای وظایف پس‌زمینه نادقیق بدون نیاز زمانی ترجیح داده می‌شوند.
  • فراموش نکنید BOOT_COMPLETED را برای بازیابی هشدارها پس از راه‌اندازی مجدد دستگاه مدیریت کنید.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید