2

I'm developing https://github.com/mauron85/cordova-plugin-mauron85-background-geolocation-phonegapbuild

Basically it's cordova plugin which is using LocationManager to send locations to webview.

The core is implemented as android.app.Service which is started in foreground to reduce chances being killed by os.

Also service has own process (android:process=":remote"). So service will survice main activity (thread) kill or app closed by user. And even if killed it will restart automatically by setting flag START_REDELIVER_INTENT in onStartCommand.

My problem is, that after app is closed (swiped away from task lisk), service crash after couple of seconds. And in the log I see:

W/BroadcastQueue(  562): Failure sending broadcast Intent { act=com.tenforwardconsulting.cordova.bgloc.STATIONARY_REGION_ACTION flg=0x10 (has extras) }
W/BroadcastQueue(  562): android.os.DeadObjectException
W/BroadcastQueue(  562):    at android.os.BinderProxy.transactNative(Native Method)
W/BroadcastQueue(  562):    at android.os.BinderProxy.transact(Binder.java:496)
W/BroadcastQueue(  562):    at android.app.ApplicationThreadProxy.scheduleRegisteredReceiver(ApplicationThreadNative.java:1093)
W/BroadcastQueue(  562):    at com.android.server.am.BroadcastQueue.performReceiveLocked(BroadcastQueue.java:431)
W/BroadcastQueue(  562):    at com.android.server.am.BroadcastQueue.deliverToRegisteredReceiverLocked(BroadcastQueue.java:521)
W/BroadcastQueue(  562):    at com.android.server.am.BroadcastQueue.processNextBroadcast(BroadcastQueue.java:729)
W/BroadcastQueue(  562):    at com.android.server.am.BroadcastQueue$BroadcastHandler.handleMessage(BroadcastQueue.java:149)
W/BroadcastQueue(  562):    at android.os.Handler.dispatchMessage(Handler.java:102)
W/BroadcastQueue(  562):    at android.os.Looper.loop(Looper.java:135)
W/BroadcastQueue(  562):    at android.os.HandlerThread.run(HandlerThread.java:61)
W/BroadcastQueue(  562):    at com.android.server.ServiceThread.run(ServiceThread.java:46)
W/ActivityManager(  562): Scheduling restart of crashed service com.xpressgo.courier.cordova/com.tenforwardconsulting.cordova.bgloc.DistanceFilterLocationService in 82050ms
W/ActivityManager(  562): Scheduling restart of crashed service com.xpressgo.courier.cordova/com.tenforwardconsulting.cordova.bgloc.FusedLocationService in 97188832ms

Then after some time (97188832ms) service restarted and operates normally. But why it crashed at first place? Why there is failure sending broadcast, when services lives in their own thread? And why it won't crash again after auto restart?

MiguelHincapieC
  • 5,445
  • 7
  • 41
  • 72
mauron85
  • 1,364
  • 1
  • 14
  • 28

3 Answers3

1

I would recommend that you review these lines (or any intents fired as a result) in your code in onCreate() of DistanceFilterLocationService.java:

...
// Stationary region PI
stationaryRegionPI  = PendingIntent.getBroadcast(this, 0, new Intent(STATIONARY_REGION_ACTION), PendingIntent.FLAG_CANCEL_CURRENT);
registerReceiver(stationaryRegionReceiver, new IntentFilter(STATIONARY_REGION_ACTION));
...

As per the official documentation of registerReceiver(BroadcastReceiver receiver, IntentFilter filter):

Registers a BroadcastReceiver to be run in the main activity thread. The receiver will be called with any broadcast Intent that matches filter, in the main application thread.

Essentially, stationaryRegionReceiver's onReceive() will be run on the main UI thread which should be gone if your app is closed. Explore this instead, registerReceiver (BroadcastReceiver receiver, IntentFilter filter, Handler handler)

You can also use this post to test what thread a portion of code is running in: How to check if current thread is not main thread.

Community
  • 1
  • 1
  • I've tried handler - looper approach https://github.com/mauron85/cordova-plugin-background-geolocation/blob/next/src/android/AbstractLocationProvider.java#L64, but problem persisted. – mauron85 Dec 29 '15 at 13:26
1

I believe that reason is this bug.

There is bug in recent versions of Android, where Services without any binding to the activity will be killed when they receive any Intent broadcast (no matter Service is living in separate process). There are some ugly workarounds (actually I've made one myself), but nothing I can really recommend. Thankfully android auto restarts Services after some time.

mauron85
  • 1,364
  • 1
  • 14
  • 28
0

I'm a little late, but maybe it still could be useful for someone. I found out this is probably a problem related with KitKat and newer versions. The workaround to this is use the following code:

AlarmManager manager = (AlarmManager) MyContext.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(MyContext, MyBroadcastReceiver.class);
alarmIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
PendingIntent myPendingIntent = PendingIntent.getBroadcast(MyContext, 1, alarmIntent, 0);

I read something about side effects, but I had no problem with the above solution.

Reference: Issue 53313