0

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?

user149408
  • 5,385
  • 4
  • 33
  • 69
  • Now this approach is not a good way. You can go with ContentProviders – Pankaj Kumar Jul 19 '19 at 20:09
  • Indeed the other question turned out to be related to the same problem. However, it is full of red herrings—even if it had turned up at the top of my search I might have ended up skipping it as not relevant to my problem. OTOH, changing that would require heavy editing of the question. – user149408 Jul 19 '19 at 20:36

0 Answers0