Android 9.0 (APi 28): java.lang.IllegalStateException: Not allowed to start service Intent

androidandroid-9.0-pieandroid-service

I'm building a music app, everything is alright but recently, app will be crashed. When see my crash list on fabric so notice that only happens on os 9.

Fatal Exception: java.lang.RuntimeException
Unable to start activity ComponentInfo{android.store/android.store.MusicPlayerActivity}: java.lang.IllegalStateException: Not allowed to start service Intent { act=android.store.mediaservice.PLAY_PLAYLIST cmp=android.store/.mediaservice.MediaService (has extras) }: app is in background uid UidRecord{1aba0fa u0a192 SVC bg:+5m42s914ms idle change:uncached procs:1 seq(0,0,0)}

I couldn't reproduce that issue because it rarely happen.
These following code cause crash :

if (intent.hasExtra(MediaService.EXTRAS_INDEX)) {
    Intent i = new Intent(getApplicationContext(), MediaService.class);
    i.setAction(MediaService.ACTION_PLAY_PLAYLIST);             i.putExtra(MediaService.EXTRAS_INDEX, intent.getIntExtra(MediaService.EXTRAS_INDEX, 0));
    i.putExtra(MediaService.EXTRAS_TRACK_IDLIST, intent.getStringArrayExtra(MediaService.EXTRAS_TRACK_IDLIST));     startService(i);
} else if (intent.hasExtra(EXTRAS_SHUFFLE)) {
    Intent i = new Intent(getApplicationContext(), MediaService.class);
    i.setAction(MediaService.ACTION_PLAY_SHUFFLE);
    i.putExtra(MediaService.EXTRAS_TRACK_IDLIST, intent.getStringArrayExtra(MediaService.EXTRAS_TRACK_IDLIST));
    startService(i);
}

So what's the main reason cause crash and solution for this ?

Best Answer

For pre Oreo devices, you have to use startService(), but from Oreo onwards devices, you have to use startForgroundService(). Check the below sample code.

   ContextCompat.startForegroundService(new Intent(context, MyService.class));

Background Execution Limits in Android Oreo. ContextCompat makes Build.Version check inside and calls right method

To show the notification to the user use below code in your service.

@Override
public void onCreate() {
    super.onCreate();
    startForeground(NOTIFICATION_ID,new Notification());
}