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

phnmnn picture phnmnn · Sep 27, 2017 · Viewed 213.3k times · Source

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"

Answer

Sagar Kacha picture Sagar Kacha · Dec 5, 2017

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);