Foreground service requires notification (don’t forget that for android 8+ notification channel should be created before showing any notification):

val notification = NotificationCompat.Builder(applicationContext, channelId)

.setSmallIcon(R.mipmap.ic_launcher)

.setContentTitle("Important background job")

.build()

Then need to create ForegroundInfo object and pass notification as parameter:

val foregroundInfo = ForegroundInfo(notification)

And run the worker in foreground service:

setForeground(foregroundInfo)

And that’s all, your worker is run in foreground service.

You can observe the progress:

workManager.getWorkInfoByIdLiveData(workRequest.id)

.observe(this, Observer { workInfo: WorkInfo? ->

if (workInfo != null) {

val progress = workInfo.progress

val value = progress.getInt(Progress, 0)

binding.progressBar.progress = value

}

})

Let’s run the app and make sure everything works fine:

The foregrouns service is started and the notification is shown. However, the notification doesn’t have progress bar and displays only text. WorkManager doesn’t provide API to interact with service notification. But there is a way…

In order to update notification we just need the notification id. And there is such id, but it’s declared as a constant in SystemForegroundDispatcher and there is no way to change it. I hope the WorkManager team will provide either ability to create own notification id or a way to set notification progress in the future.

And before we just use the value from SystemForegroundDispatcher :

// constants

@VisibleForTesting

public static final int NOTIFICATION_ID = 42;

Now, adding progress bar to the notification is easy:

val notification = NotificationCompat.Builder(applicationContext, channelId)

.setSmallIcon(R.mipmap.ic_launcher)

.setContentTitle("Important background job")

.setProgress(100, progress, false)

.build()

notificationManager?.notify(42, notification)

Now it looks better:

The foreground service is stopped when a worker is done its job, the notification is removed automatically.

UPD 0: As I have been told there is another way to update notification, calling setForeground multiple times updates the notification too.

UPD 1: In stable version the API is slightly changed, now you can pass notification id to ForegroundInfo constructor.

The complete project is available on GitHub:

LinkedIn: https://www.linkedin.com/in/ymysochenko/

Twitter: https://twitter.com/sdexyz