Bound service crash with "Context.startForegroundService() did not then call Service.startForeground()" error

UdeshUK picture UdeshUK · Dec 2, 2017 · Viewed 25.8k times · Source

I'm currently working on audio playback app and I'm using a started bound service to play music in background. I start and bind to the service using following code.

val intent = Intent(context, MusicService::class.java)
context.startService(intent)
context.bindService(intent, serviceConnection, 0)

It gets promoted to foreground when playing and gets demoted when music is paused.

// onAudioPlay
service.startForeground(NOTIFY_ID, notification)

// onAudioPause
service.stopForeground(false)

Service work fine up to now. But when the notification is swiped(removed) by the user in the paused state, the service crashes after few seconds giving this error.

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myplayer, PID: 4380
    android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
        android.app.ActivityThread$H.handleMessage(ActivityThread.java:1775)
        android.os.Handler.dispatchMessage(Handler.java:105)
        android.os.Looper.loop(Looper.java:164)
        android.app.ActivityThread.main(ActivityThread.java:6541)
        java.lang.reflect.Method.invoke(Native Method)
      com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

This only happens on Oreo and I already read about the background limitations in Oreo. But following points bugs me.

  • This service is a bound service(which aren't affected by limitations)
  • I never use Context.startForegroundService() to start the service.(and don't want to use it)
  • The service doesn't crash when it gets demoted from foreground, it's happens when removing the notification.

Why is the service is crashing? What am I doing wrong? I'm very thankful if someone tell me whats happening here.

Answer

Andy S picture Andy S · May 31, 2018

To expand on UdeshUk's answer - any use of MediaButtonReceiver (either building pending intents or just receiving media button intents) can result in your service being called with startForegroundService, because MediaButtonReceiver.onReceive starts your service in that way on Oreo. I haven't seen this documented anywhere.