How can I start an Android service from a BroadcastReceiver
while the app is in the background?
Use case is the following: other apps can request data from my app by sending it a poll broadcast (as a directed broadcast, picked up by a manifest-declared receiver). The broadcast receiver will then start the service which supplies the data, if it is not yet running; the service will then retrieve the data (unless it is already running and has the data cached) and answer the request (by sending another broadcast).
This is the code I have tried:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
/* Start the service with the internal poll intent */
Intent outIntent = new Intent(Const.ACTION_INTERNAL_POLL, null, context, MyService.class);
context.startService(outIntent);
}
}
This works on older Android versions, but on Android 8 it fails with an exception because apps in the background cannot start services. Logcat here:
07-19 21:44:56.334 11096 11096 E AndroidRuntime: java.lang.RuntimeException: Unable to start receiver org.traffxml.roadeagle.android.core.MyReceiver: java.lang.IllegalStateException: Not allowed to start service Intent { act=my.app.POLL cmp=my.app/.android.core.MyReceiver (has extras) }: app is in background uid UidRecord{dfb1a59 u0a169 RCVR idle change:idle|uncached procs:1 seq(0,0,0)}
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.app.ActivityThread.handleReceiver(ActivityThread.java:3194)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.app.ActivityThread.-wrap17(Unknown Source:0)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1672)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.os.Looper.loop(Looper.java:164)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6494)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { act=my.app.POLL cmp=my.app/.android.core.TraffReceiver (has extras) }: app is in background uid UidRecord{dfb1a59 u0a169 RCVR idle change:idle|uncached procs:1 seq(0,0,0)}
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1521)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.app.ContextImpl.startService(ContextImpl.java:1477)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.content.ContextWrapper.startService(ContextWrapper.java:650)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.content.ContextWrapper.startService(ContextWrapper.java:650)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at my.app.android.core.MyReceiver.onReceive(MyReceiver.java:40)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: at android.app.ActivityThread.handleReceiver(ActivityThread.java:3187)
07-19 21:44:56.334 11096 11096 E AndroidRuntime: ... 8 more
Any way around this?