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"
How to Fix IllegalStateException. To avoid the IllegalStateException in Java, it should be ensured that any method in code is not called at an illegal or inappropriate time. Calling the next() method moves the Iterator position to the next element.
public class IllegalStateException extends RuntimeException. Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.
context. startForegroundService(intent); Inside the service, usually in onStartCommand() , you can request that your service run in the foreground. To do so, call startForeground() .
A foreground service performs some operation that is noticeable to the user. For example, an audio app would use a foreground service to play an audio track. Foreground services must display a Notification. Foreground services continue running even when the user isn't interacting with the app.
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);
The permitted situations are a temporary whitelist where the background service behaves the same as before Android O.
Under certain circumstances, a background app is placed on a temporary whitelist for several minutes. While an app is on the whitelist, it can launch services without limitation, and its background services are permitted to run. An app is placed on the whitelist when it handles a task that's visible to the user, such as:
- Handling a high-priority Firebase Cloud Messaging (FCM) message.
- Receiving a broadcast, such as an SMS/MMS message.
- Executing a PendingIntent from a notification.
- Starting a VpnService before the VPN app promotes itself to the foreground.
Source: https://developer.android.com/about/versions/oreo/background.html
So in other words if your background service does not meet the whitelist requirements you have to use the new JobScheduler. It's basically the same as a background service, but it gets called periodically instead of running in the background continuously.
If you're using an IntentService, you can change to a JobIntentService. See @kosev's answer below.
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