androidkotlinandroid-serviceforeground-service

Foreground Service: Where should I put the code I actually want to run?


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...

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.


Solution

  • 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()
        }
    }