Android Kotlin

Android Background Services:
Surviving Battery Killers

By Ankit Kumar, Founder of Kyvronix Technologies · 16 min read

Keeping an Android app running in the background has become an absolute nightmare for developers over the last few years. With the introduction of Doze Mode, App Standby Buckets, and aggressive OEM battery optimizations (looking at you, Xiaomi and Samsung), a standard background service will be ruthlessly killed by the OS within minutes.

When building PhoneGuard, an anti-theft app that needs to listen for SMS triggers and report GPS locations 24/7, we had to master the art of surviving the Android battery grim reaper. Here is the definitive guide to Android Background Services in 2026.

1. The Demise of Standard Services

In the old days, you could call startService() and run forever. Since Android 8.0 (API 26), background services face severe restrictions. If your app is not in the foreground, you cannot start a background service. If you have one running, the OS will kill it shortly after the user leaves the app.

2. WorkManager: The De Facto Standard

If your task is deferrable (i.e., it doesn't need to happen at a precise millisecond), WorkManager is the Google-recommended approach. It handles constraints (e.g., "only run when on Wi-Fi and charging") and guarantees execution even if the device restarts.

class SyncWorker(appContext: Context, workerParams: WorkerParameters) :
    CoroutineWorker(appContext, workerParams) {

    override suspend fun doWork(): Result {
        return try {
            // Perform background sync
            syncDataWithServer()
            Result.success()
        } catch (e: Exception) {
            Result.retry()
        }
    }
}

// Scheduling the work
val constraints = Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .build()

val syncRequest = PeriodicWorkRequestBuilder<SyncWorker>(15, TimeUnit.MINUTES)
    .setConstraints(constraints)
    .build()

WorkManager.getInstance(context).enqueueUniquePeriodicWork(
    "DataSync",
    ExistingPeriodicWorkPolicy.KEEP,
    syncRequest
)
  

3. Foreground Services (When You Need It NOW)

If your task is urgent and user-facing (e.g., music playback, active GPS tracking, or in PhoneGuard's case, an anti-theft siren), you must use a Foreground Service. A Foreground Service requires a persistent notification, letting the user know the app is actively consuming resources.

Since API 34 (Android 14), you must specify a foregroundServiceType in your manifest and request the corresponding permission.

<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />

<service
    android:name=".TrackingService"
    android:foregroundServiceType="location"
    android:exported="false" />
  

And starting the service:

val notification = NotificationCompat.Builder(this, "tracking_channel")
    .setContentTitle("PhoneGuard is active")
    .setContentText("Protecting your device")
    .setSmallIcon(R.drawable.ic_shield)
    .build()

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    startForeground(1, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION)
} else {
    startForeground(1, notification)
}
  

4. Defeating OEM Battery Optimizers

Even with a Foreground Service, manufacturers like Xiaomi, Huawei, and Samsung might still kill your app to save battery. To ensure maximum survivability, you need to ask the user to explicitly exempt your app from battery optimizations.

val intent = Intent()
val packageName = context.packageName
val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager

if (!pm.isIgnoringBatteryOptimizations(packageName)) {
    intent.action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
    intent.data = Uri.parse("package:$packageName")
    context.startActivity(intent)
}
  

Warning: Google Play policies strictly govern the use of this intent. Only use it if your app's core functionality (like anti-theft or alarm clocks) genuinely requires it.

Conclusion

Background execution on Android is a constant battle between developer requirements and battery life. By using WorkManager for deferrable tasks, strictly typed Foreground Services for active tasks, and educating the user on battery optimization settings, you can build reliable background apps that survive the OS's aggressive memory management.

— Ankit Kumar