Alarm kur

Alarmlar (AlarmManager sınıfına göre), uygulamanızın kullanım ömrü dışında zamana dayalı işlemler gerçekleştirmeniz için bir yöntem sunar. Örneğin, hava durumu tahmini indirmek için günde bir kez hizmet başlatmak gibi uzun süreli bir işlemi başlatmak için alarm kullanabilirsiniz.

Alarmlar şu özelliklere sahiptir:

  • Amaçları belirlenen zamanlarda ve/veya aralıklarla tetiklemenizi sağlarlar.

  • Bunları, diğer işlemleri gerçekleştirmek üzere işleri veya WorkRequests'i planlamak için yayın alıcılarıyla birlikte kullanabilirsiniz.

  • Uygulamanızın dışında çalışırlar. Böylece uygulamanız çalışmıyorken ve cihazın kendisi uyku durumunda olsa bile etkinlikleri veya işlemleri tetiklemek için bunları kullanabilirsiniz.

  • Uygulamanızın kaynak gereksinimlerini en aza indirmenize yardımcı olurlar. Operasyonları, zamanlayıcılara veya sürekli çalışan hizmetlere bağlı kalmadan planlayabilirsiniz.

Kesintisiz alarm ayarlama

Bir uygulama değişken olmayan alarm ayarladığında, sistem alarmı gelecekte bir noktada iletir. Tam olmayan alarmlar, Doz gibi pil tasarrufu kısıtlamalarına uyarken alarmın yayınlanma zamanıyla ilgili bazı garantiler sağlar.

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

Belirli bir saatten sonra alarm verme

Uygulamanız set(), setInexactRepeating() veya setAndAllowWhileIdle() çağrısı yaparsa alarm belirtilen tetikleme zamanından önce asla çalmaz.

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

Belirli bir zaman aralığında alarm kurma

Uygulamanız setWindow() çağırırsa alarm, bildirilen tetikleyici zamanından önce asla çalmaz. Herhangi bir pil tasarrufu kısıtlaması olmadığı sürece alarm, belirtilen tetikleme zamanından başlayarak belirtilen zaman aralığı içinde gönderilir.

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

Yaklaşık olarak düzenli aralıklarla tekrarlanan bir alarm verme

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

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

Tam alarm ayarlama

Sistem, gelecekteki belirli bir anda tam alarm kurar.

Çoğu uygulama, çeşitli yaygın kullanım alanlarını tamamlamak için görevleri ve etkinlikleri tam olmayan alarmlar kullanarak planlayabilir. Uygulamanızın temel işlevi tam olarak zamanlanmış bir alarma (örneğin, bir çalar saat veya takvim uygulaması için) bağlıysa bunun yerine tam alarm kullanmak sorun yaratmaz.

Tam alarm gerektirmeyebilecek kullanım alanları

Aşağıdaki listede tam alarm gerektirmeyebilecek, yaygın olarak kullanılan iş akışları gösterilmektedir:

Uygulamanızın kullanım ömrü boyunca zamanlama işlemleri planlama
Handler sınıfı, zamanlama işlemlerini yönetmek için uygulamanız etkin durumdayken n saniyede bir çalışma gibi çeşitli iyi yöntemler içerir: postAtTime() ve postDelayed(). Bu API'lerin gerçek zamanlı değil, sistem çalışma süresine dayandığını unutmayın.
Uygulamanızı güncelleme ve günlükleri yükleme gibi planlı arka plan çalışmaları
WorkManager, zamanlamaya duyarlı periyodik çalışmalar planlamanızı sağlayan bir yöntem sunar. İş için ayrıntılı bir çalışma zamanı tanımlamak üzere bir tekrarlama aralığı ve flexInterval (en az 15 dakika) sağlayabilirsiniz.
Belirli bir süre sonra gerçekleşmesi gereken, kullanıcı tarafından belirlenen işlem (sistem boşta durumda olsa bile)
Süresiz alarm kullanma. Özellikle, setAndAllowWhileIdle() numaralı telefonu arayın.
Belirli bir süre sonra gerçekleşmesi gereken, kullanıcı tanımlı işlem
Süresiz alarm kullanma. Özellikle, set() numaralı telefonu arayın.
Belirli bir zaman aralığında gerçekleşebilecek, kullanıcı tanımlı işlem
Süresiz 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 alarmlar ayarlayabilir. Bu yöntemler, listenin en altına yakın olanlarda daha fazla zaman açısından kritik görev yapacak, ancak daha fazla sistem kaynağı gerektirecek şekilde sıralanır.

setExact()

Diğer pil tasarrufu önlemleri geçerli olmadığı sürece, gelecekteki neredeyse kesin bir zamanda alarm başlatabilirsiniz.

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

setExactAndAllowWhileIdle()

Pil tasarrufu önlemleri geçerli olsa bile gelecekte neredeyse kesin bir zamanda alarm çağırabilirsiniz.

setAlarmClock()

Gelecekteki belirli bir zamanda bir alarm çağırın. Bu alarmlar kullanıcılar tarafından kolayca görülebildiğinden sistem hiçbir zaman bunların teslimat süresini ayarlamaz. Sistem, bu alarmları en kritik alarm olarak belirler ve devreye girmesi 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 amacıyla bu istekleri kolayca gruplayamaz.

Mümkün olduğunda değişken olmayan alarm oluşturmanız önemle tavsiye edilir. Daha uzun süre çalışmak için alarmınızın BroadcastReceiver cihazından WorkManager veya JobScheduler uygulamasını kullanarak programı planlayın. Cihaz Doz modundayken iş yapmak için setAndAllowWhileIdle() aracını kullanarak değişken olmayan bir alarm oluşturun ve alarmdan bir iş başlatın.

Uygun tam alarm iznini belirtin

Uygulamanız Android 12 veya sonraki bir sürümü hedefliyorsa "Alarmlar ve hatırlatıcılar" özel uygulama erişimi elde etmeniz 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 etme seçeneğiniz vardır.

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

Hem SCHEDULE_EXACT_ALARM hem de USE_EXACT_ALARM izinleri aynı özelliklere işaret etse de farklı şekilde verilir ve farklı kullanım alanlarını destekler. Uygulamanız tam alarm kullanmalı ve yalnızca uygulamanızdaki kullanıcılara yönelik bir işlev tam olarak zamanlanmış işlemler gerektiriyorsa SCHEDULE_EXACT_ALARM veya USE_EXACT_ALARM iznini beyan etmelidir.

USE_EXACT_ALARM

SCHEDULE_EXACT_ALARM

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

SCHEDULE_EXACT_ALARM izni kullanılıyor

USE_EXACT_ALARM'den farklı olarak, SCHEDULE_EXACT_ALARM izni kullanıcı tarafından verilmelidir. Hem kullanıcı hem de sistem SCHEDULE_EXACT_ALARM iznini iptal edebilir.

Uygulamanıza izin verilip verilmediğini kontrol etmek için tam alarm kurmaya çalışmadan önce canScheduleExactAlarms() numaralı telefonu arayın. Uygulamanızın SCHEDULE_EXACT_ALARM izni iptal edildiğinde uygulamanız durur ve gelecekteki tüm tam alarmlar iptal edilir. Bu, 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 bunu ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED yayınını gönderir. Uygulamanız aşağıdakileri yapan bir yayın alıcısı uygulamalıdır:

  1. Uygulamanızın hâlâ özel uygulama erişimine sahip olduğunu onaylar. Bunun için canScheduleExactAlarms() numaralı telefonu arayın. Bu kontrol, uygulamanızı kullanıcının uygulamanıza izin verdiği destek kaydından korur ve neredeyse hemen sonra iptal eder.
  2. Uygulamanızın ihtiyaç duyduğu tam alarmları, mevcut durumuna bağlı olarak yeniden planlar. Bu mantık, uygulamanızın ACTION_BOOT_COMPLETED yayınını aldığında yaptığı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ğidir
Şekil 1. Sistem ayarlarındaki "Alarmlar ve hatırlatıcılar" özel uygulama erişim sayfası. Burada, kullanıcılar uygulamanızın tam alarm kurmasına izin verebilirler.

Gerekirse kullanıcıları sistem ayarlarındaki Alarmlar ve hatırlatıcılar ekranına Şekil 1'de gösterildiği gibi 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 uygulamanızın neden tam alarm planlaması gerektiğini açıklayın.
  2. ACTION_REQUEST_SCHEDULE_EXACT_ALARM amaç işlemini içeren bir niyet çağırın.

Tekrarlanan alarm ayarlama

Tekrarlanan alarmlar, sistemin yinelenen bir program dahilinde uygulamanıza bildirim göndermesine olanak tanır.

Kötü tasarlanmış bir alarm, pilin bitmesine ve sunuculara önemli ölçüde yük bindirilmesine neden olabilir. Bu nedenle, Android 4.4 (API düzeyi 19) ve sonraki sürümlerde yinelenen tüm alarmlar kesin olmayan alarmlardır.

Tekrarlanan alarmlar aşağıdaki özelliklere sahiptir:

  • Alarm türü. Daha ayrıntılı bilgi için Alarm türü seçme konusuna bakın.

  • Tetikleyici süresi. 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 tetiklenen beklemedeki bir amaç. Aynı bekleme niyetini kullanan ikinci bir alarm ayarladığınızda orijinal alarmın yerini alır.

Bir PendingIntent() işlemini iptal etmek için amacın bir örneğini almak amacıyla PendingIntent.getService() aracılığıyla FLAG_NO_CREATE iletken, ardından bu niyeti AlarmManager.cancel() hedefine 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ın 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 zaman, referans olarak "sistemin başlatılmasından bu yana geçen süre"yi, gerçek zamanlı saat ise UTC (duvar saati) saatini kullanır. Bu, saat diliminden veya yerel ayardan etkilenmediği için geçen gerçek zamanın, zaman geçişine (örneğin, her 30 saniyede bir tetiklenen bir alarm) dayalı bir alarm ayarlamak için uygun olduğu anlamına gelir. Gerçek zamanlı saat türü, geçerli yerel ayara bağlı olan alarmlar için daha uygundur.

Her iki türde de "uyandırma" sürümü vardır. Bu sürüm, ekran kapalıyken cihazın CPU'sunu uyandırmayı belirtir. Bu, alarmın planlanan zamanda çalmasını sağlar. Bu, uygulamanız zamana bağımlıysa kullanışlıdır. Örneğin, belirli bir işlemi gerçekleştirmek için sınırlı bir zaman aralığı varsa. Alarm türünüzün uyanma sürümünü kullanmazsanız tekrar eden tüm alarmlar, cihazınız tekrar uyandığında etkinleşir.

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

Alarmınızın günün belirli bir saatinde çalması gerekiyorsa saate dayalı gerçek zamanlı saat türlerinden birini seçin. Ancak, bu yaklaşımın bazı dezavantajları olabileceğini unutmayın. Uygulama diğer yerel ayarlarda iyi sonuç vermeyebilir ve kullanıcı cihazın saat ayarını değiştirirse bu durum, uygulamanızda beklenmeyen davranışlara neden olabilir. Ayrıca, gerçek zamanlı saat 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: Cihazın başlatılmasından bu yana geçen süreye göre beklemedeki niyeti etkinleştirir ancak cihazı uyandırmaz. Geçen süre, cihazın uyku modunda olduğu tüm süreyi içerir.

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

  • RTC: Belirtilen zamanda bekleyen niyeti tetikler ancak cihazı uyandırmaz.

  • RTC_WAKEUP: Belirtilen zamanda beklemedeki amacı etkinleştirmek için cihazı uyandırır.

Geçen gerçek zamanlı alarm örnekleri

ELAPSED_REALTIME_WAKEUP kullanımına ilişkin bazı örnekler

30 dakika sonra ve bunu izleyen her 30 dakikada bir alarmı tetiklemek için cihazı 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);

Bir dakika içinde tek seferlik (yinelenmeyen) bir alarm çalması için cihazı 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ı saat alarmı örnekleri

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

Alarmı yaklaşık 14:00'da çalması için cihazı uyandırın ve aynı anda günde bir kez tekrarlayın:

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

Alarmı tam olarak 08:30'da ve sonrasında her 20 dakikada bir çalması için cihazı 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, 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, aynı anda tekrarlanan birden fazla alarmı senkronize eder ve bunları aynı anda etkinleştirir. Bu da pil tüketimini azaltır.

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

setInexactRepeating() kullanırken setRepeating() ile belirleyebileceğiniz özel bir aralık belirleyemezsiniz. 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() çağrısı yapın ve artık tetiklemek istemediğiniz PendingIntent testini geçirin. Örneğin:

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, cihaz kapandığında tüm alarmlar iptal edilir. Bunun olmasını önlemek için uygulamanızı, kullanıcı cihazı yeniden başlattığında yinelenen bir alarmı otomatik olarak yeniden başlatacak şekilde tasarlayabilirsiniz. Bu şekilde AlarmManager, kullanıcının alarmı manuel olarak yeniden başlatmasına gerek kalmadan görevini gerçekleştirmeye devam eder.

İlgili adımlar aşağıdadır:

  1. Uygulamanızın manifest dosyasında RECEIVE_BOOT_COMPLETED iznini ayarlayın. Bu, uygulamanızın, sistem başlatıldıktan sonra yayınlanan ACTION_BOOT_COMPLETED öğesini almasına olanak tanır (bu yalnızca uygulama kullanıcı tarafından en az bir kez başlatıldıysa ç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. Bu, uygulama açıkça etkinleştirmediği sürece alıcı çağrılmayacağı anlamına gelir. 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. Diğer bir deyişle, alıcının programatik olarak etkinleştirilmesi, yeniden başlatmalarda bile manifest ayarını geçersiz kılar. Alıcı, uygulamanız devre dışı bırakana kadar etkin durumda 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 alarmları çağır

Android 6.0 (API düzeyi 23) çalıştıran cihazlar, cihazın pil ömrünü uzatmaya yardımcı olan Doz modunu destekler. Cihaz Doz modundayken alarm çalmaz Programlanan tüm alarmlar cihaz Doz modundan çıkana kadar ertelenir. Cihaz boşta olsa bile çalışmayı tamamlamanız gerekiyorsa birkaç seçenekten yararlanabilirsiniz:

  • Tam alarm ayarlayın.

  • Arka plan çalışması için tasarlanan WorkManager API'sini kullanın. İşin bir an önce bitmesi için sistemin çalışmanızı hızlandırması gerektiğini belirtebilirsiniz. Daha fazla bilgi için WorkManager ile görev planlama bölümüne göz atı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) biçimiyle ilgili sonuçlar doğurabilir. Örneğin, bir sunucuyla senkronizasyon yapan popüler bir uygulama düşünün. Senkronizasyon işlemi saat saatini temel alıyorsa ve uygulamanın her örneği saat 23:00'da senkronize ediliyorsa sunucudaki yük yüksek oranda gecikmeye veya "hizmet reddine" neden olabilir. Alarmları kullanmayla ilgili şu en iyi uygulamaları izleyin:

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

    • Alarm çaldığında yerel bir çalışma yapın. "Yerel çalışma", bir sunucuya gelmeyen veya sunucudaki verileri gerektirmeyen her şey anlamına gelir.

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

  • Alarm frekansını minimumda tutun.

  • Cihazı gereksiz yere uyandırmayın (bu davranış, Alarm türü seçme bölümünde açıklandığı gibi alarm türüne göre belirlenir).

  • Alarmınızın tetiklenme zamanını olduğundan daha hassas yapmayın.

    setRepeating() yerine setInexactRepeating() özelliğini kullanın. setInexactRepeating() kullandığınızda Android, birden fazla uygulamadan gelen yinelenen alarmları senkronize eder ve bunları aynı anda etkinleştirir. Bu, sistemin cihazı uyandırması gereken toplam sayıyı azaltarak pil tüketimini azaltır. Android 4.4 (API Düzeyi 19) sürümünden itibaren, tekrar eden tüm alarmlar kesin olmayan alarm kategorisindedir. setInexactRepeating(), setRepeating()'e kıyasla bir iyileştirme olsa da bir uygulamanın her örneği aynı zamanda sunucuya isabet ederse yine de sunucuyu yorabilir. Bu nedenle, daha önce açıklandığı gibi ağ istekleri için alarmlarınıza biraz rastgelelik ekleyin.

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

    Kesin bir tetikleme zamanına dayalı yinelenen alarmlar iyi ölçeklendirilemez. 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.