Android 8.0: java.lang.IllegalStateException: Not allowed to start service Intent

androidandroid-8.0-oreoandroid-service

On application launch, app starts the service that should to do some network task.
After targeting API level 26, my application fails to start service on Android 8.0 on background.

Caused by: java.lang.IllegalStateException: Not allowed to start
service Intent {
cmp=my.app.tt/com.my.service
}: app is in background uid UidRecord{90372b1 u0a136 CEM idle procs:1
seq(0,0,0)}

as I understand it related to:
Background execution limits

The startService() method now throws an IllegalStateException if an
app targeting Android 8.0 tries to use that method in a situation when
it isn't permitted to create background services.

"in a situation when it isn't permitted" – what it's actually mean?? And how to fix it. I don't want to set my service as "foreground"

Best Answer

I got solution. For pre-8.0 devices, you have to just use startService(), but for post-7.0 devices, you have to use startForgroundService(). Here is sample for code to start service.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(new Intent(context, ServedService.class));
    } else {
        context.startService(new Intent(context, ServedService.class));
    }

And in service class, please add the code below for notification:

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

Where O is Android version 26.

If you don't want your service to run in Foreground and want it to run in background instead, post Android O you must bind the service to a connection like below:

Intent serviceIntent = new Intent(context, ServedService.class);
context.startService(serviceIntent);
context.bindService(serviceIntent, new ServiceConnection() {
     @Override
     public void onServiceConnected(ComponentName name, IBinder service) {
         //retrieve an instance of the service here from the IBinder returned 
         //from the onBind method to communicate with 
     }

     @Override
     public void onServiceDisconnected(ComponentName name) {
     }
}, Context.BIND_AUTO_CREATE);