2

I have a music player app and recently I switched to MediaBrowserServiceCompat from a regular service. The service is created automatically by the framework (onCreate method is called at app startup), and I start it as foreground only on play action.

The ANR is encountered on a few devices, especially Samsung, but also seen on Sony, Nokia, AllView etc.

class MusicService: MediaBrowserServiceCompat() {

  override fun onCreate() {
    super.onCreate()
    .....
 }

 override fun onTaskRemoved(rootIntent: Intent?) {
    super.onTaskRemoved(rootIntent)
    stopSelf()
 }

  fun moveServiceToStartedState(){
     if (!mServiceInStartedState) {
          ContextCompat.startForegroundService(
                  this@MusicService,
                  Intent(this@MusicService, MusicService::class.java))
          mServiceInStartedState = true
      }

      startForeground(PlayerNotificationManager.NOTIFICATION_ID, notification)
  }

  fun  moveServiceOutOfStartedState() {
     if(mServiceInStartedState) {
       stopForeground(true)
       stopSelf()
       mServiceInStartedState = false
     }
  }

  fun updateNotificationForPause(state: PlaybackStateCompat) {
      stopForeground(false)
      ................
  }

private inner class MediaPlayerListener: PlaybackInfoListener() {

   private val mServiceManager: ServiceManager = ServiceManager()

   override fun onPlaybackStateChange(state: PlaybackStateCompat) {

      // Manage the started state of this service.
      when (state.state) {
         PlaybackStateCompat.STATE_PLAYING -> mServiceManager.moveServiceToStartedState(state)
         PlaybackStateCompat.STATE_PAUSED -> mServiceManager.updateNotificationForPause(state)
         PlaybackStateCompat.STATE_ERROR -> {
            mServiceManager.updateNotificationForPause(state)
            Toast.makeText(this@MusicService, R.string.error, Toast.LENGTH_SHORT).show()
         }
         PlaybackStateCompat.STATE_STOPPED -> mServiceManager.moveServiceOutOfStartedState()
      }
   }

}

I ALWAYS call startForeground after ContextCompat.startForegroundService...

Is there any way to debug/reproduce/fix this issue?

Alexandru Circus
  • 5,478
  • 7
  • 52
  • 89
  • Why are you calling `startForegroundService` at all? If you're already bound, `startService()` + `startForeground()` is enough to put you in the right state. – ianhanniballake Oct 12 '20 at 05:54
  • @ianhanniballake Are you sure about that? In the doc here: https://developer.android.com/guide/components/services#StartingAService it says "If an app needs to create a foreground service, the app should call startForegroundService()"... and then call startForeground() within 5 minutes. What you're saying is `startService()` + `startForeground()` is the same as `startForegroundService()` + `startForeground()` ? – plgrenier Dec 14 '21 at 01:30
  • @plgrenier - I literally [wrote the docs on the `MediaBrowserServiceCompat`](https://developer.android.com/guide/topics/media-apps/audio-app/building-a-mediabrowserservice#service-lifecycle). You're only forced to `startForegroundService` if your service isn't already running (and, being a bound service, it is indeed already running). – ianhanniballake Dec 14 '21 at 01:36
  • 1
    @ianhanniballake I'm not sure I get it. My use case is different than Alexandru since my MediaBrowserService is NOT already running when starting the app. We start the service in response to an action, like playing a song. In that case we're using `startForegroundService()` to create our service, and then later call `startForeground()` within `onStartCommand()`. That being said, we're still getting ANR (same error as Alexandru). I then tried to start the service as a background service instead, using `startService()`, then binds to the service using local binding. – plgrenier Dec 14 '21 at 01:51
  • @ianhanniballake and tried to call `startForegroundService()` from `onServiceConnected()`, but realized that `MediaBrowserServiceCompat` is already a bound service (as you wrote in another answer) and so I couldn't do that either. – plgrenier Dec 14 '21 at 01:53
  • @ianhanniballake Could you please confirm that doing `startService()` + `startForeground()` later in `onStartCommand()` is enough to put the service in foreground? If that's the case, then I indeed don't see the point of using `startForegroundService()`. The only reason I would see to use that method is per the docs, if the service was started from background since API level 26, then using `startForegroundService()` would be necessary, but it is not my case. Is that correct? – plgrenier Dec 14 '21 at 17:05
  • @ianhanniballake thanks a lot for your answer! I'm really flattered that you answer my question, I know you from Google's videos. Indeed I was using startForegroundService instead of regular startService. I must say I'm refactoring the app from scratch and I will use startService from now on... – Alexandru Circus Nov 04 '22 at 17:56

0 Answers0