9

From onCreate() of my Activity,

I am trying to start a service via following code:

Intent intent = new Intent();
intent.setClassName(SERVICE_PKG_NAME, SERVICE_NAME);
context.startService(intent); //context = MainActivity.this

However, I receive following exception:

java.lang.IllegalStateException: Not allowed to start service Intent (service-name) : app is in background

Any idea what could be reason for this? Stuck on it for few hours now.

Somesh Kumar
  • 8,088
  • 4
  • 33
  • 49
Sahil Mehta
  • 147
  • 1
  • 10
  • 1
    What version of Android are you testing on? Also, can you post the entire Java stack trace? – CommonsWare Jun 01 '17 at 14:23
  • Does it work with `getApplicationContext().startService(intent)`? – tynn Jun 01 '17 at 15:17
  • @tynn No tried it..still the same error.. – Sahil Mehta Jun 02 '17 at 04:13
  • 2
    @CommonsWare Android -O. From https://developer.android.com/preview/behavior-changes.html seems newly added. **bold** The startService() method now throws an IllegalStateException if an app targeting Android O tries to use that method in a situation when it isn't permitted to create background services.**bold** – Sahil Mehta Jun 02 '17 at 04:13
  • 1
    Your error message matched what I was seeing from O, which is why I was asking about the device version. Where and when are you trying to start the service? – CommonsWare Jun 02 '17 at 10:32
  • @CommonsWare **Problem Scenario**: My App A tries to start service & bind to it (of App B). However , App B is in background & App A is in foreground, so system won't allow to start Service for app in Background. **Solution** Able to fix by Starting the service of App B on boot-up (by listen to boot complete receiver). Then App A is able to bind succcessfully. Ofcourse Limitation of this solution is start service at boot-up & not when required. Any other **suggestions** to avoid this limitation – Sahil Mehta Jun 02 '17 at 11:58
  • 1
    "so system won't allow to start Service for app in Background" -- that does not make any sense. App A is in the foreground. It is supposed to be able to start services to its heart's content, including any services of App B. Regardless, try binding to the service first, then calling `startService()` for that same service once the service is bound. – CommonsWare Jun 02 '17 at 12:28
  • @CommonsWare yes, your suggestion works fine. Only call bindService() first, after OnServiceConnected() due to bind call, call StartService(). Could you explain the rationale why this sequence works fine but the original one didn't ? – Sahil Mehta Jun 05 '17 at 13:07
  • Perhaps it is a bug in Android O. Otherwise, given your description of the symptoms, I have no idea why it would behave that way. – CommonsWare Jun 05 '17 at 13:10
  • @CommonsWare I was able to solve this problem as I mentioned before by calling bindService() followed by startService(). However it was applicable only when App A was in foreground. Now I have another scenario where App C (a Background service) want to startService() of App B, but crashes even when call startService() from onServiceConnected() [of bindService]. Any suggestions for this scenario ? – Sahil Mehta Jul 17 '17 at 10:03
  • 1
    Perhaps A, B, and C should all be one app. Regardless, you can try calling `startForegroundService()` on `Context` instead of `startService()`. – CommonsWare Jul 17 '17 at 11:06
  • if you're using `IntentService` switching to `JobIntentService` should do the trick. Under the hood it's using `JobScheduler` for Devices running O+ and `IntentService` for older APIs – cwiesner Apr 06 '18 at 12:31
  • @SahilMehta : try this one https://stackoverflow.com/questions/46445265/android-8-0-java-lang-illegalstateexception-not-allowed-to-start-service-inten – Anand Savjani Jun 18 '18 at 15:02

1 Answers1

3

For cases involving need to invoke service of Background app from a foreground app, We can follow the sequence:

  • call bindService() first
  • after OnServiceConnected() due to bind call
  • call StartService().
Sahil Mehta
  • 147
  • 1
  • 10
  • So this has to be a Bound Service? – IgorGanapolsky Jul 27 '17 at 19:18
  • So how do I start a service in reaction to a Firebase Notification? – Daniel F Aug 28 '17 at 15:26
  • 1
    @DanielF I think it's better to use JobScheduler for it. You can specify the Job to be started to it, based on certain condition like Charger Connected etc. https://developer.android.com/reference/android/app/job/JobScheduler.html – Sahil Mehta Aug 29 '17 at 11:53
  • @SahilMehta Thanks for your feedback. My issue was that I started targeting API 26 and there you can't invoke a service from the background unless you do it with `startForegroundService` (I think that was the name), You have to pass it a notification then. – Daniel F Aug 29 '17 at 13:57
  • @DanielF ,I think JobScheduler should help in this case. I had a similar scenario. – Sahil Mehta Sep 04 '17 at 04:12