What is a foreground service in android?
A foreground service runs in the background but must come with a notification, so the user knows it’s running on the OS.
It’s used for tasks the user should be aware of that shouldn’t be killed by the OS, such as tracking on a run or playing music, or looking for a ride.
Before writing a foreground service you should add foreground service permission in AndroidManifest.xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
Now create a very simple TestForegroundService
class TestForegroundService : Service() {
companion object {
var isServiceRunning = false
const val ACTION_START_FOREGROUND_SERVICE = "ACTION_START_FOREGROUND_SERVICE"
const val ACTION_STOP_FOREGROUND_SERVICE = "ACTION_STOP_FOREGROUND_SERVICE"
}
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
when (intent?.action) {
ACTION_START_FOREGROUND_SERVICE -> {
isServiceRunning = true
startForegroundService()
}
ACTION_STOP_FOREGROUND_SERVICE -> {
isServiceRunning = false
stopForeground(true)
stopSelf()
}
}
return START_STICKY
}
private fun startForegroundService() {
val pendingIntent = Intent(this, MainActivity::class.java).let {
it.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
PendingIntent.getActivity(this, 0, it, 0)
}
val notification = NotificationCompat.Builder(this, App.NOTIFICATION_CHANNEL_ID)
.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher_round)
.setContentIntent(pendingIntent)
.setContentTitle("TestForegroundService")
.setContentText("This is content text of notification")
.build()
startForeground(1, notification)
}
}
startForegroundService()
will launch your service as a foreground service. It needs an ongoing sticky notification we created here.
You must create the Application class and notification channel before.
class App : Application() {
companion object {
const val NOTIFICATION_CHANNEL_ID = "YOUR_NOTIFICATION_CHANNEL_ID"
}
override fun onCreate() {
super.onCreate()
createNotificationChannel()
}
private fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val serviceChannel = NotificationChannel(NOTIFICATION_CHANNEL_ID, "Test Service Channel", NotificationManager.IMPORTANCE_DEFAULT)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager.createNotificationChannel(serviceChannel)
}
}
}
Now add application into AndroidManifest.xml
<application
android:name=".App"
............>
</application>
Now launch service from an activity or a fragment like below.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.button.setOnClickListener {
val serviceIntent = Intent(this, TestForegroundService::class.java)
serviceIntent.action = TestForegroundService.ACTION_START_FOREGROUND_SERVICE
startService(serviceIntent)
}
}
}
If an application class is not added in manifest and a notification channel is not created then you will get an error like below
E/AndroidRuntime: FATAL EXCEPTION: main
Process: info.androidboss.sample, PID: 17306
android.app.RemoteServiceException: Bad notification for startForeground
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2005)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7664)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Whatever you do in this service will now be executed reliably in the background until you force stop the app from phone Settings.
Add TestForegroundService
in AndroidManifest.xml
<application
........>
<service
android:name=".TestForegroundService"/>
</application>
Keep more alive foreground service by ignoring battery optimization – Read This Post By Clicking Here