I recently learned about Foreground Services in Android and how to use them.
Often what is used in examples is something like this:
class MyForegroundService : Service() {
...
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val notification = NotificationCompat.Builder(this, "my_foreground_service")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("This is a notification")
.setContentText("Hello").build()
startForeground(1, notification) //don't use id = 0!
return super.onStartCommand(intent, flags, startId)
}
...
}
However, what is often not shown for some reason and I am wondering about is:
Where should I put my code that's actually supposed to do stuff in the foreground service?
Should I...
startForeground()?startForeground()?.setContentIntent() to the notification builder with an intent that runs the code from another class?One situation where this is actually important is vibration. On WearOS devices, vibration does not happen while the app is in the background, unless it happens from within a foreground service.
I tested running the code both before and after startForeground(). It seemed to work better when writing it after startForeground(), although even then it didn't seem to work every time.
class MyForegroundService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val notification = NotificationCompat.Builder(this, "my_foreground_service")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("This is a notification")
.setContentText("Hello")
.build()
startForeground(1, notification)
doActualWork()
return START_STICKY
}
private fun doActualWork() {
Thread {
val vibrator = getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
vibrator.vibrate(VibrationEffect.createOneShot(500, VibrationEffect.DEFAULT_AMPLITUDE))
for (i in 1..5) {
Log.d("MyForegroundService", "Working... step $i")
Thread.sleep(1000)
}
stopForeground(STOP_FOREGROUND_REMOVE)
stopSelf()
}.start()
}
}