This guide shows you how to build an Android foreground service that automatically restarts after the system kills its process. You’ll learn the exact components, manifest entries, and lifecycle callbacks needed, plus how to handle the most common failure points like background execution limits and OEM-specific battery killers.
What You’ll Need
- Android Studio (current stable version)
- A device or emulator running Android 8.0 (API 26) or higher for foreground service restrictions, or Android 14 (API 34) for the latest foreground service type requirements
- Basic familiarity with Kotlin or Java and Android components (Activity, Service, BroadcastReceiver)
Step-by-Step
- Create the Foreground Service class. Extend
Service(orLifecycleServiceif you use AndroidX Lifecycle). InonCreate(), build a notification channel (Android 8.0+) and a notification. InonStartCommand(), callstartForeground()with a unique notification ID and the notification. ReturnSTART_STICKYso the system recreates the service after it’s killed. - Declare the service in AndroidManifest.xml. Add a
<service>element with theandroid:foregroundServiceTypeattribute (e.g.,"dataSync"for syncing,"location"for GPS). Include intent filters if you want the service to be started by explicit intents from other components. For Android 14+, you must declare the foreground service type in the manifest and request the corresponding permission (e.g.,FOREGROUND_SERVICE_DATA_SYNC). - Request the necessary permissions. Add
FOREGROUND_SERVICEand the type-specific permission (e.g.,FOREGROUND_SERVICE_LOCATION) to the manifest. If your service accesses location or other sensitive data, add those runtime permissions too. - Start the service from your app. Use
Context.startForegroundService()when the app is in the foreground. If the service is not yet running, the system will create it. If the app is in the background, you must have a valid reason (e.g., user-initiated action) and follow the background start restrictions. - Implement recovery after process death. The key is
START_STICKYinonStartCommand(). When the system kills the service (e.g., due to memory pressure), it will attempt to recreate it with a null intent. InonStartCommand(), handle the null intent case by re-initializing your work and callingstartForeground()again. For more control, overrideonTaskRemoved()to restart the service with aPendingIntentviaAlarmManagerorWorkManager—this is useful for apps that need to continue after the user swipes away the app. - Use WorkManager for robust background work (optional but recommended). For tasks that must survive even the most aggressive OEM kill, wrap your service logic in a
CoroutineWorkerand schedule it withWorkManager. WorkManager persists the work across process death and reboots, and it respects Doze mode. You can still show a foreground service notification while the work runs, but WorkManager handles the retry logic. - Test process death. Use Android Studio’s “Terminate Application” or run
adb shell am kill com.yourpackageto simulate a system kill. Then check if the service restarts. Also test swiping the app from recents (which triggersonTaskRemoved) and force-stopping from Settings (which should NOT restart the service, as that’s user-initiated).
Common Mistakes
- Returning
START_NOT_STICKYorSTART_REDELIVER_INTENTwithout proper handling. UseSTART_STICKYfor simple recovery. If you need the original intent, useSTART_REDELIVER_INTENTbut be prepared to handle the redelivered intent. - Not calling
startForeground()within 5 seconds ofstartForegroundService(). This throws aForegroundServiceDidNotStartInTimeExceptionand crashes the app. - Forgetting to include the foreground service type permission on Android 14+. The app will crash with a
SecurityExceptionif the type is not declared and permission not granted. - Assuming the service restarts after a force-stop from Settings. It does not. Only system kills (memory pressure, etc.) trigger the sticky restart.
- Not handling the null intent in
onStartCommand(). When the system recreates the service, the intent is null, so your code must not rely on it.
Tips
- Use a foreground service only when necessary; for most background tasks,
WorkManageris simpler and more reliable. - Keep the notification informative but not spammy. Users can dismiss the notification (Android 13+ allows this), but the service remains running.
- For location services, request the
ACCESS_BACKGROUND_LOCATIONpermission and declare thelocationforeground service type. - Test on multiple devices, especially those with aggressive battery management (Xiaomi, Huawei, Samsung). You may need to guide users to whitelist your app in their battery settings.
- Use
stopForeground(STOP_FOREGROUND_REMOVE)when the work is done to remove the notification and stop the service properly.
Troubleshooting
- Service not restarting after process death. Check that you return
START_STICKYand that youronStartCommand()handles the null intent. Also verify the service is not being force-stopped by the user or a battery optimizer. - App crashes with
ForegroundServiceDidNotStartInTimeException. Ensure you callstartForeground()as soon as possible inonStartCommand(), and that the notification channel is created before that. - Foreground service type not allowed. On Android 14+, you must declare the type in the manifest and request the corresponding permission. Also, some types (like
cameraormicrophone) have additional runtime requirements. - Service stops when the app is swiped away. This is expected if you don’t override
onTaskRemoved(). To continue, useAlarmManagerorWorkManagerto restart the service after a short delay. - Service not working in Doze mode. Foreground services are exempt from Doze, but if you’re using a regular background service, it will be deferred. Use a foreground service or WorkManager.
Frequently Asked Questions
Will my service restart after the user force-stops the app from Settings?
No. A user-initiated force-stop permanently stops the service until the user opens the app again. This is by design to prevent apps from running against the user’s will.
What is the difference between START_STICKY and START_REDELIVER_INTENT?
START_STICKY recreates the service with a null intent after a system kill. START_REDELIVER_INTENT recreates it with the last intent that was passed to onStartCommand(). Use START_REDELIVER_INTENT if you need the original intent to resume work.
Can I use a foreground service for all background tasks?
Technically yes, but it’s not recommended. Foreground services show a persistent notification and consume resources. For deferrable, one-off, or periodic tasks, use WorkManager instead.
How do I handle Android 14’s foreground service type requirements?
Declare the type in the manifest (e.g., android:foregroundServiceType="dataSync") and request the corresponding permission (e.g., FOREGROUND_SERVICE_DATA_SYNC). Also ensure your service actually performs that type of work.
Why does my service stop when the screen turns off?
If the service is a foreground service, it should continue. If it stops, check that you haven’t accidentally called stopSelf() or that the battery optimizer isn’t killing it. Some OEMs require users to add the app to a protected list.
Is it possible to restart a service after a reboot?
Yes, but not with a foreground service alone. You need a BOOT_COMPLETED broadcast receiver that starts the service after the device boots. WorkManager also persists across reboots if you schedule it with ExistingPeriodicWorkPolicy.
Related
General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.
More in this bed
- Google Play Installing Apps You Didn’t Install? Fix
- MTG Arena on PC with BlueStacks: Install & Play
- Shockwave Flash Crashed in Chrome: Easy Fix
- Best Tips to Secure Your Android Mobile
- Stop Windows 11 Apps Installing on Other Drives
- Fix External Drive Not Mounting on Mac