Alarm kur

Alarmlar (AlarmManager sınıfını temel alır) uygulamanızın kullanım ömrü dışında zamana dayalı işlemler gerçekleştirmenize olanak tanır. Örneğin, hava durumu tahmini indirmek üzere günde bir kez hizmet başlatmak gibi uzun süreli bir işlemi başlatmak için alarm kullanabilirsiniz.

Alarmlar şu özelliklere sahiptir:

  • Belirlenen zamanlarda ve/veya aralıklarda Intent tetiklemenizi sağlarlar.

  • Bunları yayın alıcılarıyla birlikte kullanarak işleri veya diğer işlemleri gerçekleştirmek amacıyla WorkRequest'leri planlayabilirsiniz.

  • Uygulamanızın dışında çalıştığından bunları, uygulamanız çalışmıyorken, cihazın kendisi uyku modunda olsa bile etkinlikleri veya işlemleri tetiklemek için kullanabilirsiniz.

  • Uygulamanızın kaynak gereksinimlerini en aza indirmenize yardımcı olur. Zamanlayıcılara dayanmadan veya sürekli çalışan hizmetlere güvenmeden işlemleri planlayabilirsiniz.

Tam olmayan alarm ayarlama

Bir uygulama tam olmayan alarm kurduğunda, sistem alarmı gelecekteki bir zamanda çalacaktır. Tam olmayan alarmlar, Doz gibi pil tasarrufu kısıtlamalarına uyarak, alarmın teslim zamanıyla ilgili birtakım garantiler verir.

Geliştiriciler, tam olmayan alarm tesliminin zamanlamasını özelleştirmek için aşağıdaki API garantilerinden yararlanabilir.

Alarmı belirli bir süre sonra çal

Uygulamanız set(), setInexactRepeating() veya setAndAllowWhileIdle() çağrıyorsa alarm hiçbir zaman sağlanan tetikleme zamanından önce çalmaz.

Android 12 (API düzeyi 31) ve sonraki sürümlerde sistem, pil tasarrufu veya Doz gibi pil tasarrufu kısıtlamaları geçerli olmadığı sürece, sağlanan tetikleme zamanından itibaren bir saat içinde alarmı çalar.

Belirli bir zaman aralığında alarm çalma

Uygulamanız setWindow() çağrısı yapıyorsa alarm hiçbir zaman sağlanan tetikleyici zamanından önce çalmaz. Pil tasarrufu kısıtlaması geçerli olmadığı sürece, alarm belirtilen zaman aralığında, belirtilen tetikleme zamanından itibaren gerçekleştirilir.

Uygulamanız Android 12 veya sonraki bir sürümü hedefliyorsa sistem, zaman aralığı olan tam olmayan alarmın çağrılmasını en az 10 dakika geciktirebilir. Bu nedenle, 600000 altındaki windowLengthMillis parametre değerleri 600000 olarak kırpılır.

Yaklaşık olarak düzenli aralıklarla tekrar eden bir alarm sunma

Uygulamanız setInexactRepeating() çağırırsa sistem birden fazla alarm çağırır:

  1. İlk alarm, belirtilen tetikleyici zamanından itibaren belirtilen zaman aralığı içinde çalar.
  2. Sonraki alarmlar genellikle belirtilen zaman aralığı geçtikten sonra çalar. Alarmın art arda iki çağrısı arasındaki süre değişiklik gösterebilir.

Tam alarm ayarlama

Sistem, gelecekteki bir anda tam alarm çalar.

Çoğu uygulama, bazı yaygın kullanım alanlarını tamamlamak için tam olmayan alarmlar kullanarak görev ve etkinlikler planlayabilir. Uygulamanızın temel işlevi, tam olarak zamanlanmış alarma bağlıysa (çalar saat veya takvim uygulaması gibi) bunun yerine tam alarm kullanmanız uygundur.

Tam alarm gerektirmeyen kullanım alanları

Aşağıdaki listede tam alarm gerektirmeyen yaygın iş akışları gösterilmektedir:

Zamanlama işlemlerini uygulamanızın kullanım süresi boyunca planlama
Handler sınıfı, uygulamanız yayındayken n saniyede bir çalışma yapmak gibi zamanlama işlemlerini yürütmek için birçok iyi yöntem içerir: postAtTime() ve postDelayed(). Bu API'lerin gerçek zamanlı değil, sistem çalışma süresine bağlı olduğunu unutmayın.
Uygulamanızı güncelleme ve günlükleri yükleme gibi planlı arka plan çalışmaları
WorkManager, zamanlamaya duyarlı periyodik işleri planlama olanağı sunar. İş için ayrıntılı çalışma zamanı tanımlamak amacıyla bir tekrar aralığı ve flexInterval (en az 15 dakika) sağlayabilirsiniz.
Belirli bir süreden sonra yapılması gereken kullanıcı tarafından belirtilen işlem (sistem boşta olsa bile)
Tam olmayan alarm kullanma. Özellikle setAndAllowWhileIdle() numaralı telefonu arayın.
Belirli bir sürenin sonunda yapılması gereken, kullanıcı tarafından belirtilen işlem
Tam olmayan alarm kullanma. Özellikle set() numaralı telefonu arayın.
Belirli bir zaman aralığında gerçekleşebilecek, kullanıcı tarafından belirtilen işlem
Tam olmayan alarm kullanma. Özellikle setWindow() numaralı telefonu arayın. Uygulamanız Android 12 veya sonraki bir sürümü hedefliyorsa izin verilen en kısa aralık uzunluğunun 10 dakika olduğunu unutmayın.

Tam alarm kurmanın yolları

Uygulamanız, aşağıdaki yöntemlerden birini kullanarak tam alarm ayarlayabilir. Bu yöntemler, listenin sonuna daha yakın olan yöntemler, zaman açısından daha kritik olan görevlere hizmet ederken daha fazla sistem kaynağı gerektirecek şekilde sıralanır.

setExact()

Başka pil tasarrufu önlemleri geçerli olmadığı sürece, neredeyse tam olarak gelecekteki bir zamanda alarm çağırın.

Uygulamanızın çalışması kullanıcı için zaman açısından kritik değilse tam alarm kurmak için bu yöntemi kullanın.

setExactAndAllowWhileIdle()

Pil tasarrufu önlemleri etkin olsa bile gelecekteki neredeyse kesin bir zamanda alarm çağırın.

setAlarmClock()

Gelecekteki belirli bir zamanda bir alarm çağırın. Bu alarmlar kullanıcılar tarafından çok yakından görüldüğünden, sistem teslimat süresini hiçbir zaman ayarlamaz. Sistem, bu alarmları en önemli alarmlar olarak tanımlar ve alarmların devreye alınması için gerekirse düşük güç modlarını bırakır.

Sistem kaynağı tüketimi

Sistem, uygulamanızın ayarladığı tam alarmları tetiklediğinde cihaz, özellikle güç tasarrufu modundayken pil ömrü gibi önemli miktarda kaynak tüketir. Ayrıca sistem, kaynakları daha verimli kullanmak için bu istekleri kolayca toplu hale getiremez.

Mümkün olduğunda tam olmayan bir alarm oluşturmanız önemle tavsiye edilir. Daha uzun süre çalışmak için alarmınızdaki BroadcastReceiver ayarındaki WorkManager veya JobScheduler kullanarak randevu ayarlayın. Cihaz Doz modundayken iş yapmak için setAndAllowWhileIdle() kullanarak tam olmayan bir alarm oluşturun ve alarmdan bir iş başlatın.

Uygun tam alarm iznini tanımlama

Uygulamanız Android 12 veya sonraki bir sürümü hedefliyorsa "Alarmlar ve hatırlatıcılar" özel uygulama erişimini edinmeniz gerekir. Bunu yapmak için aşağıdaki kod snippet'inde gösterildiği gibi uygulamanızın manifest dosyasında SCHEDULE_EXACT_ALARM iznini beyan edin:

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

Uygulamanız Android 13 (API düzeyi 33) veya sonraki sürümleri hedefliyorsa SCHEDULE_EXACT_ALARM veya USE_EXACT_ALARM iznini beyan edebilirsiniz.

<manifest ...>
    <uses-permission android:name="android.permission.USE_EXACT_ALARM"/>
    <application ...>
        ...
    </application>
</manifest>

Hem SCHEDULE_EXACT_ALARM hem de USE_EXACT_ALARM izinleri aynı özellikleri bildirse de farklı izinlere sahiptir ve farklı kullanım alanlarını destekler. Uygulamanız yalnızca kullanıcılara yönelik bir işlev tam olarak zamanlanmış işlemler gerektiriyorsa tam alarm kullanmalı ve SCHEDULE_EXACT_ALARM ya da USE_EXACT_ALARM iznini beyan etmelidir.

USE_EXACT_ALARM

SCHEDULE_EXACT_ALARM

  • Kullanıcı tarafından verildi
  • Daha geniş kullanım alanları
  • Uygulamalar, iznin iptal edilmediğini onaylamalıdır

SCHEDULE_EXACT_ALARM izni, Android 13 (API düzeyi 33) ve sonraki sürümleri hedefleyen uygulamaların yeni yüklemelerine önceden verilmez. Kullanıcılar, yedekleme ve geri yükleme işlemi aracılığıyla uygulama verilerini Android 14 çalıştıran bir cihaza aktarırsa yeni cihazda SCHEDULE_EXACT_ALARM izni reddedilir. Ancak mevcut bir uygulama bu izne zaten sahipse cihaz Android 14'e geçerken erişim önceden verilir.

Not: Tam alarm setExact API gibi bir OnAlarmListener nesnesi kullanılarak ayarlanmışsa SCHEDULE_EXACT_ALARM izni gerekmez.

SCHEDULE_EXACT_ALARM iznini kullanma

USE_EXACT_ALARM işlevinin aksine, SCHEDULE_EXACT_ALARM izni kullanıcı tarafından verilmelidir. SCHEDULE_EXACT_ALARM iznini hem kullanıcı hem de sistem iptal edebilir.

Uygulamanıza izin verilip verilmediğini kontrol etmek için tam bir alarm ayarlamaya çalışmadan önce canScheduleExactAlarms() numarasını arayın. Uygulamanız için SCHEDULE_EXACT_ALARM izni iptal edildiğinde, uygulamanız durdurulur ve gelecekteki tüm tam alarmlar iptal edilir. Bu aynı zamanda, canScheduleExactAlarms() tarafından döndürülen değerin, uygulamanızın tüm yaşam döngüsü boyunca geçerli kalacağı anlamına da gelir.

Uygulamanıza SCHEDULE_EXACT_ALARMS izni verildiğinde sistem, uygulamanızı ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED yayını gönderir. Uygulamanız aşağıdakileri yapan bir yayın alıcı uygulamalıdır:

  1. Uygulamanızın hâlâ özel uygulama erişimine sahip olduğunu onaylar. Bunu yapmak için canScheduleExactAlarms() numaralı telefonu arayın. Bu kontrol, uygulamanızı kullanıcının uygulamanıza izin verdiği durumdan korur ve neredeyse hemen sonra iptal eder.
  2. Uygulamanızın ihtiyaç duyduğu tam alarmları mevcut durumuna göre yeniden planlar. Bu mantık, uygulamanızın ACTION_BOOT_COMPLETED yayınını alırken yaptıklarına benzer olmalıdır.

Kullanıcılardan SCHEDULE_EXACT_ALARM izni vermelerini isteyin

&quot;Alarm ve hatırlatıcı ayarlamaya izin ver&quot; seçeneğinin adı var
Şekil 1. Kullanıcıların, uygulamanızın tam alarm ayarlamasına izin verebileceği, sistem ayarlarındaki "alarmlar ve hatırlatıcılar" özel uygulama erişim sayfası.

Gerekirse, Şekil 1'de gösterildiği gibi, kullanıcıları sistem ayarlarındaki Alarmlar ve hatırlatıcılar ekranına gönderebilirsiniz. Bunun için aşağıdaki adımları uygulayın:

  1. Uygulamanızın kullanıcı arayüzünde, kullanıcıya neden tam alarmlar programlaması gerektiğini açıklayın.
  2. ACTION_REQUEST_SCHEDULE_EXACT_ALARM intent işlemini içeren bir intent çağırın.

Tekrarlanan alarm ayarlama

Tekrarlanan alarmlar sayesinde sistem, uygulamanızı yinelenen bir programla bilgilendirir.

Kötü tasarlanmış bir alarm, pilin bitmesine ve sunucularda önemli bir yüke neden olabilir. Bu nedenle, Android 4.4 (API düzeyi 19) ve sonraki sürümlerde tekrarlanan tüm alarmlar tam olmayan alarmdır.

Tekrarlanan bir alarm aşağıdaki özelliklere sahiptir:

  • Bir alarm türü. Daha fazla bilgi için Alarm türü seçme konusuna bakın.

  • Tetikleyici zamanı. Belirttiğiniz tetikleme zamanı geçmişteyse alarm hemen tetiklenir.

  • Alarmın aralığı. Örneğin, günde bir, saatte bir veya 5 dakikada bir.

  • Alarm tetiklendiğinde etkinleşen beklemedeki niyet. Aynı bekleme amacını kullanan ikinci bir alarm ayarladığınızda orijinal alarmın yerini alır.

Bir PendingIntent() öğesini iptal etmek için FLAG_NO_CREATE öğesini PendingIntent.getService() hesabına ileterek niyetin bir örneğini (varsa) alın, ardından bu niyeti AlarmManager.cancel() adresine iletin

Kotlin

val alarmManager =
    context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
val pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE)
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent)
}

Java

AlarmManager alarmManager =
    (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent);
}

Alarm türü seçin

Tekrarlanan alarm kullanırken dikkat edilmesi gereken ilk noktalardan biri, alarm türünün ne olması gerektiğidir.

Alarmlar için iki genel saat türü vardır: "geçen gerçek zamanlı" ve "gerçek zamanlı saat" (RTC). Geçen gerçek zamanlı ölçüm, referans olarak "sistemin başlatılmasından bu yana geçen süre"yi, gerçek zamanlı saatte ise UTC (duvar saati) kullanılır. Bu nedenle, geçen gerçek zamanlı süre, saat diliminden veya yerel ayardan etkilenmediği için zaman sınırına göre (örneğin, her 30 saniyede bir çalan bir alarm) alarm kurmak için uygundur. Gerçek zamanlı saat türü, mevcut yerel ayara bağlı alarmlar için daha uygundur.

Her iki türün de "uyandırma" sürümü vardır. Bu sürüm, ekran kapalıyken cihazın CPU'sunu uyandırılmasını belirtir. Bu, alarmın planlanan zamanda çalmasını sağlar. Uygulamanızın zamana bağımlılığı varsa bu seçenek yararlıdır. Örneğin, bu seçenek belirli bir işlemi gerçekleştirmek için sınırlı bir pencereye sahipse. Alarm türünüzün uyandırma sürümünü kullanmazsanız cihazınız tekrar uyanık olduğunda tekrarlanan tüm alarmlar çalar.

Sadece alarmınızın belirli bir aralıkta (örneğin, yarım saatte bir) çalması gerekiyorsa geçen gerçek zamanlı türlerinden birini kullanın. Genel olarak bu, daha iyi olan seçenektir.

Alarmınızın günün belirli bir saatinde çalmasını istiyorsanız saat tabanlı gerçek zamanlı saat türlerinden birini seçin. Ancak bu yaklaşımın bazı dezavantajları da olabileceğini unutmayın. Uygulama diğer yerel ayarlara iyi çalışmayabilir ve kullanıcı cihazın saat ayarını değiştirirse uygulamanızda beklenmeyen davranışlara neden olabilir. Gerçek zamanlı saatli alarm türünün kullanılması da yukarıda açıklandığı gibi iyi ölçeklenmez. Mümkünse "geçen gerçek zamanlı" alarmı kullanmanızı öneririz.

Türlerin listesi aşağıda verilmiştir:

  • ELAPSED_REALTIME: Beklemedeki intent, cihazın başlatılmasından bu yana geçen süreye göre tetiklenir, ancak cihazı uyandırmaz. Geçen süre, cihazın uykuda olduğu zamanları da içerir.

  • ELAPSED_REALTIME_WAKEUP: Cihazı uyandırır ve cihazın açılışından itibaren belirtilen süre geçtikten sonra beklemedeki niyeti tetikler.

  • RTC: Beklemedeki intent, belirtilen zamanda etkinleştirilir ancak cihazı uyandırmaz.

  • RTC_WAKEUP: Beklemedeki amacı belirtilen zamanda tetiklemek için cihazı uyandırır.

Gerçek zamanlı alarm örnekleri

Aşağıda, ELAPSED_REALTIME_WAKEUP kullanımıyla ilgili bazı örnekler verilmiştir

Cihazı 30 dakika sonra ve sonrasında her 30 dakikada bir alarmı çalması için uyandırın:

Kotlin

// Hopefully your alarm will have a lower frequency than this!
alarmMgr?.setInexactRepeating(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
        AlarmManager.INTERVAL_HALF_HOUR,
        alarmIntent
)

Java

// Hopefully your alarm will have a lower frequency than this!
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
        AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);

Cihazı bir dakika içinde tek seferlik (yinelenmeyen) bir alarm çalması için uyandırın:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

alarmMgr?.set(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + 60 * 1000,
        alarmIntent
)

Java

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() +
        60 * 1000, alarmIntent);

Gerçek zamanlı alarm örnekleri

RTC_WAKEUP kullanımıyla ilgili bazı örnekleri aşağıda bulabilirsiniz.

Cihazı yaklaşık 14:00'te çalacak şekilde uyandırın ve günde bir kez aynı anda tekrar edin.

Kotlin

// Set the alarm to start at approximately 2:00 p.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 14)
}

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr?.setInexactRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        AlarmManager.INTERVAL_DAY,
        alarmIntent
)

Java

// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_DAY, alarmIntent);

Cihazı tam olarak sabah 08:30'da ve sonrasında her 20 dakikada bir çalacak şekilde uyandırın:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

// Set the alarm to start at 8:30 a.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 8)
    set(Calendar.MINUTE, 30)
}

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr?.setRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        1000 * 60 * 20,
        alarmIntent
)

Java

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000 * 60 * 20, alarmIntent);

Alarmınızın ne kadar hassas olması gerektiğine karar verin

Daha önce açıklandığı gibi, alarm türünü seçmek genellikle alarm oluşturmanın ilk adımıdır. Bir diğer ayrım ise alarmınızın ne kadar hassas olması gerektiğidir. Çoğu uygulama için setInexactRepeating() doğru seçimdir. Bu yöntemi kullandığınızda Android, birden fazla tam olmayan yinelenen alarmı senkronize eder ve aynı anda bu alarmı tetikler. Bu, pil tüketimini azaltır.

Mümkünse tam alarm kullanmaktan kaçının. Ancak kesin süre gereklilikleri olan nadir uygulamalarda setRepeating() numaralı telefonu arayarak tam alarm ayarlayabilirsiniz.

setInexactRepeating() özelliğinde, setRepeating() ile olduğu gibi özel bir aralık belirtemezsiniz. INTERVAL_FIFTEEN_MINUTES, INTERVAL_DAY gibi aralık sabitlerinden birini kullanmanız gerekir. Tam liste için bkz. AlarmManager.

Bir alarmı iptal etme

Uygulamanıza bağlı olarak alarmı iptal etme özelliğini eklemek isteyebilirsiniz. Bir alarmı iptal etmek için Alarm Manager'da cancel() numaralı telefonu arayın ve artık çalmasını istemediğiniz PendingIntent'i geçin. Örnek:

Kotlin

// If the alarm has been set, cancel it.
alarmMgr?.cancel(alarmIntent)

Java

// If the alarm has been set, cancel it.
if (alarmMgr!= null) {
    alarmMgr.cancel(alarmIntent);
}

Cihaz yeniden başlatıldığında alarm başlat

Varsayılan olarak tüm alarmlar cihaz kapandığında iptal edilir. Bunun olmasını önlemek için, kullanıcı cihazı yeniden başlattığında uygulamanızı, tekrarlanan bir alarmı otomatik olarak yeniden başlatacak şekilde tasarlayabilirsiniz. Bu sayede AlarmManager, kullanıcının alarmı manuel olarak yeniden başlatmasına gerek kalmadan görevini yapmaya devam eder.

Şu adımları uygulayabilirsiniz:

  1. Uygulamanızın manifest dosyasında RECEIVE_BOOT_COMPLETED iznini ayarlayın. Bu sayede uygulamanız, sistem başlatıldıktan sonra yayınlanan ACTION_BOOT_COMPLETED öğesini alabilir (bu seçenek yalnızca uygulama kullanıcı tarafından en az bir kez başlatılmışsa çalışır):

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  2. Yayını almak için BroadcastReceiver uygulayın:

    Kotlin

    class SampleBootReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == "android.intent.action.BOOT_COMPLETED") {
                // Set the alarm here.
            }
        }
    }
    

    Java

    public class SampleBootReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
                // Set the alarm here.
            }
        }
    }
    
  3. ACTION_BOOT_COMPLETED işlemini filtreleyen bir intent filtresiyle alıcıyı uygulamanızın manifest dosyasına ekleyin:

    <receiver android:name=".SampleBootReceiver"
            android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
    </receiver>

    Manifest'te, başlatma alıcısının android:enabled="false" olarak ayarlandığına dikkat edin. Yani, uygulama açıkça etkinleştirmedikçe alıcı çağrılmaz. Bu, başlatma alıcısının gereksiz yere çağrılmasını önler. Bir alıcıyı (örneğin, kullanıcı bir alarm ayarlarsa) aşağıdaki şekilde etkinleştirebilirsiniz:

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
    )
    

    Java

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);
    

    Alıcıyı bu şekilde etkinleştirdiğinizde, kullanıcı cihazı yeniden başlatsa bile etkin kalır. Başka bir deyişle, alıcının programatik olarak etkinleştirilmesi, yeniden başlatmalar sırasında bile manifest ayarını geçersiz kılar. Alıcı, uygulamanız devre dışı bırakana kadar etkin kalır. Bir alıcıyı (örneğin, kullanıcı bir alarmı iptal ederse) aşağıdaki şekilde devre dışı bırakabilirsiniz:

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
    )
    

    Java

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);
    

Cihaz Doz modundayken alarm çağırın

Android 6.0 (API düzeyi 23) çalıştıran cihazlar, cihazın pil ömrünü uzatan Doz modunu destekler. Cihaz Doz modunda Alarmlar çalmaz. Programlanmış alarmlar, cihaz Doz'dan çıkana kadar ertelenir. Cihaz boşta olsa bile işlemi tamamlamanız gerekiyorsa birkaç seçenek mevcuttur:

  • Tam alarm ayarlayın.

  • Arka plan çalışması yapmak için oluşturulan WorkManager API'yi kullanın. İşin mümkün olan en kısa sürede tamamlanması için sistemin işinizi hızlandırması gerektiğini belirtebilirsiniz. Daha fazla bilgi için WorkManager ile görev planlama bölümüne bakın

En iyi uygulamalar

Tekrarlanan alarmınızı tasarlarken yaptığınız her seçim, uygulamanızın sistem kaynaklarını kullanma (veya kötüye kullanma) üzerinde bazı sonuçları olabilir. Örneğin, bir sunucuyla senkronize olan popüler bir uygulama düşünün. Senkronizasyon işlemi saat saatine dayanıyorsa ve uygulamanın her örneği saat 23:00'te senkronize ediliyorsa sunucudaki yük yüksek gecikmeye, hatta "hizmet reddi"ne neden olabilir. Alarmları kullanırken aşağıdaki en iyi uygulamalardan yararlanın:

  • Tekrarlanan bir alarm nedeniyle tetiklenen ağ isteklerine rastgelelik (ses dalgalanması) ekleyin:

    • Alarm tetiklendiğinde yerel işlemleri yapın. "Yerel iş", bir sunucuya çalışmayan veya sunucudan veri almayı gerektiren her şeyi ifade eder.

    • Aynı zamanda, ağ isteklerini içeren alarmı rastgele bir süre içinde etkinleşecek şekilde programlayın.

  • Alarm frekansınızı minimumda tutun.

  • Cihazı gereksiz şekilde uyandırmayın (bu davranış, Alarm türü seçme konusunda açıklandığı şekilde alarm türüne göre belirlenir).

  • Alarmınızın tetikleme zamanını daha kesin olarak ayarlamayın.

    setRepeating() yerine setInexactRepeating() kullanın. setInexactRepeating() kullandığınızda Android, birden fazla uygulamadaki yinelenen alarmları senkronize eder ve aynı anda bu alarmları tetikler. Bu, sistemin cihazı toplamda kaç kez uyandırması gerektiğini, böylece pil tüketimini azaltır. Android 4.4 (API Düzeyi 19) sürümünden itibaren, tüm tekrarlanan alarmlar tam olmayan alarmdır. setInexactRepeating(), setRepeating()'e göre daha iyi bir iyileştirme olsa da bir uygulamanın her örneği sunucuya hemen hemen aynı anda gelirse sunucuyu meşgul edebilir. Bu nedenle, ağ istekleri için daha önce belirtildiği gibi alarmlarınıza biraz rastgelelik ekleyin.

  • Mümkünse alarmınızı saat saatine dayandırmaktan kaçının.

    Tam tetikleme süresine dayalı tekrarlanan alarmlar iyi ölçeklenmez. Mümkünse ELAPSED_REALTIME kullanın. Farklı alarm türleri aşağıdaki bölümde daha ayrıntılı olarak açıklanmıştır.