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.
Why is the service is crashing? What am I doing wrong? I'm very thankful if someone tell me whats happening here.
A started service can use the startForeground(int, android. app. Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory.
From Google's docs on Android 8.0 behavior changes: The system allows apps to call Context. startForegroundService() even while the app is in the background. However, the app must call that service's startForeground() method within five seconds after the service is created.
NO MORE STARTSERVICE - The new context. startForegroundService() method starts a foreground service but with a implicit contract that service will call start foreground within 5 second of its creation. You can also call startService and startForegroundService for different OS version.
To remove the service from the foreground, call stopForeground() . This method takes a boolean, which indicates whether to remove the status bar notification as well. Note that the service continues to run. If you stop the service while it's running in the foreground, its notification is removed.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With