Android’de Broadcast Receiver Arka Plan Kısıtlamaları

Rüveyda Kılıç
3 min readAug 4, 2024

--

Android, uygulama geliştirme sürecinde sistem olaylarına yanıt vermek için BroadcastReceiver kullanımını destekler. Ancak, kullanıcı deneyimini iyileştirmek ve batarya ömrünü korumak amacıyla Android, özellikle arka planda çalışan uygulamalar için çeşitli kısıtlamalar getirmiştir. Bu yazıda, BroadcastReceiver ile ilgili kısıtlamaları, bu kısıtlamaların nedenlerini ve bu durumla nasıl başa çıkabileceğimizi inceleyeceğiz.

Broadcast Receiver ve Arka Plan Kısıtlamaları

1. Implicit Broadcast Kısıtlamaları

Android 8.0 (Oreo) ve Sonrası:

Android 8.0 (Oreo) ile birlikte, bazı implicit broadcast olayları yalnızca ön planda çalışan uygulamalar tarafından alınabilir oldu. Bu değişiklik, batarya ömrünü korumak ve arka planda gereksiz sistem kaynaklarını kullanmayı önlemek amacıyla yapılmıştır. Özellikle CONNECTIVITY_CHANGE, BATTERY_LOW gibi olaylar, arka planda dinlenemez.

  • Önceden Kullanılan Manifest Tanımı:
<receiver android:name=".ConnectivityReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
  • Alternatif Çözüm: Bu tür olayları dinlemek için JobScheduler veya WorkManager kullanabiliriz. Örneğin:
val jobInfo = JobInfo.Builder(jobId, componentName)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.build()

val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
jobScheduler.schedule(jobInfo)

2. Arka Planda Veri Senkronizasyonu

Android 8.0 (Oreo) ve Sonrası:

Uzun süreli arka plan işlemleri için BroadcastReceiver kullanmak, yeni Android sürümlerinde kısıtlanmıştır. Bunun yerine, WorkManager gibi araçlar kullanmak daha uygundur. WorkManager, arka plan işlerini güvenilir bir şekilde yönetir ve çeşitli kısıtlamalara rağmen çalışabilir.

  • Önceden Kullanılan Manifest Tanımı:
<receiver android:name=".DataSyncReceiver">
<intent-filter>
<action android:name="com.example.sync.DATA_SYNC" />
</intent-filter>
</receiver>
  • Alternatif Çözüm: WorkManager ile veri senkronizasyonu yapabiliriz:
val workRequest = OneTimeWorkRequestBuilder<SyncWorker>()
.setConstraints(
Constraints.Builder()
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.build()

WorkManager.getInstance(context).enqueue(workRequest)

3. Arka Planda Konum Güncellemeleri

Android 9.0 (Pie) ve Sonrası:

Android 9.0 (Pie) ile birlikte, arka planda konum güncellemeleri almak için daha sıkı kısıtlamalar getirilmiştir. Konum verilerini toplamak için kullanıcı etkileşimi veya Foreground Service kullanmak gereklidir.

  • Önceden Kullanılan Manifest Tanımı:
<receiver android:name=".LocationReceiver">
<intent-filter>
<action android:name="android.intent.action.LOCATION_CHANGED" />
</intent-filter>
</receiver>
  • Alternatif Çözüm: Konum güncellemelerini almak için Foreground Service veya JobSchedulerkullanabiliriz.
    Aşağıdaki örnekte konum güncellemelerini almak için LocationRequest nesnesini oluşturup ve yapılandırırız.
val locationRequest = LocationRequest.create().apply {
interval = 60000
fastestInterval = 30000
priority = LocationRequest.PRIORITY_LOW_POWER
val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
locationResult ?: return
for (location in locationResult.locations) {
// Handle location update
}
}
}

LocationServices.getFusedLocationProviderClient(this)
.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())

Bu kod bloğuyla beraber güncellemeleri her 60 saniyede, cihazın en hızlı konum güncellemelerini 30 saniyede bir alırız, aynı zamanda düşük enerji tüketimi ile konum verilerini alırız.

Bu şekilde uygulamamız batarya ömrünü korurken konum güncellemelerini almamızı sağlar. Eğer daha hassas ve sık güncellemeler istersek, interval ve fastestInterval sürelerini kısaltabilir, priority seviyesini PRIORITY_HIGH_ACCURACY olarak değiştirebiliriz, ancak bu durumda daha fazla batarya tüketmeye sebep olabilir.

4. AlarmManager Kısıtlamaları

Android 6.0 (Marshmallow) ve Sonrası:

AlarmManager arka plan görevlerini belirli zamanlarda çalıştırmak için kullanılan bir sistem hizmetidir. Ancak, Doze Mode ve diğer uygulama optimizasyonları nedeniyle AlarmManager kullanımı, bazı kısıtlamalarla karşılaşabilir.

  • Doze Mode ve App Standby: Bu özellikler, cihazın batarya ömrünü uzatmak amacıyla arka plan işlemlerini sınırlayan bir güç yönetim sistemidir. AlarmManager ile planlanan alarmlar, bu modlar aktif olduğunda doğru şekilde çalışmayabilir. Örneğin, cihaz uyku moduna geçtiğinde veya ekran kapalıyken, arka plan işlemleri gecikebilir veya tamamen durdurulabilir.

Uzun süreli veya belirli aralıklarla çalışması gereken görevler için AlarmManager kullanmak, Doze Mode ve uygulama optimizasyonları nedeniyle güvenilir olmayabilir. Bu nedenle, arka plan işlemlerinin daha güvenilir bir şekilde çalışmasını sağlamak için JobScheduler veya WorkManagergibi modern araçlara yönelmek daha verimli bir seçenek olacaktır.

  • Önceden Kullanılan Manifest Tanımı:
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="com.example.alarm.ALARM_EVENT" />
</intent-filter>
</receiver>
  • Alternatif Çözüm: JobScheduler kullanarak arka plan işlerini planlayabiliriz:
val jobInfo = JobInfo.Builder(jobId, componentName)
.setPeriodic(15 * 60 * 1000L) // 15 min
.build()

val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
jobScheduler.schedule(jobInfo)

JobScheduler, arka plan görevlerini planlamak için geliştirilmiştir. Bu araç, cihazın batarya ömrünü korurken, sistem kaynaklarını verimli bir şekilde kullanmamızı sağlamaktadır.

Sonuç

Android, BroadcastReceiver kullanımı ve arka plan işlemlerini yönetmek için çeşitli kısıtlamalar getirmiştir. Bu kısıtlamalar, kullanıcı gizliliğini korumayı ve cihaz kaynaklarını daha etkili bir şekilde kullanmayı amaçlar. Modern araçlar, JobScheduler, WorkManager ve Foreground Service gibi, bu kısıtlamalarla uyumlu olarak uygulama performansını ve kullanıcı deneyimini optimize etmemize yardımcı olabilir.

--

--