HaylLtd / cordova-background-geolocation-plugin

Background and foreground geolocation plugin for Cordova.
Apache License 2.0
57 stars 66 forks source link

[Android] Crash on reboot / Does not start on reboot #111

Closed andreandersson closed 2 years ago

andreandersson commented 2 years ago

Describe the bug If you have enabled startOnBoot (value is true), there is a crash when you reboot the device and the plugin crashes. From our app in production we only have crashes on Android 12.

To Reproduce Steps to reproduce the behavior:

  1. Configure with startOnBoot: true and start() the plugin
  2. Reboot the device
  3. The plugin does not start

Expected behavior The plugin should start fetching geolocation again in the background.

Smartphone (please complete the following information):

Additional context 2022-08-20 09:56:51.116 4058-4058/package.name E/AndroidRuntime: FATAL EXCEPTION: main Process: package.name, PID: 4058 android.app.ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{d3bd3eb u0 package.name/com.marianhello.bgloc.service.LocationServiceImpl} at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:1923) at android.app.ActivityThread.access$2700(ActivityThread.java:247) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2148) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003) 2022-08-20 09:56:51.120 4058-4058/package.name E/com.marianhello.logging.UncaughtExceptionLogger: FATAL EXCEPTION: mainandroid.app.ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{d3bd3eb u0 package.name/com.marianhello.bgloc.service.LocationServiceImpl} at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:1923) at android.app.ActivityThread.access$2700(ActivityThread.java:247) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2148) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7839) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

andreandersson commented 2 years ago

The quick and dirty solution, simply add the following line to BootCompletedReceiver.java:

locationServiceIntent.putExtra("cmd", new LocationServiceIntentBuilder.Command(1).toBundle());

Based on my small knowledge of the code, that solution does look wrong. But perhaps it will help someone whom is more familiar with the code to find the correct solution!

andreandersson commented 2 years ago

I've looked though the code a bit more. Had an idea to modify the LocationServiceImpl, and have it run start(); if no command was available.

However, that created a few other issues. Mainly, the error will still exist if "startForeground" is false or "notificationsEnabled" is false.

@HarelM I'm happy to make a PR and dig a bit more into the code, however I'm not really sure what the solution should be at the moment. Can you, or anyone else, point me in the correct direction?

HarelM commented 2 years ago

I'm not sure I have a good direction here. One of the problems might be the changes in latest android versions when you might need background permissions to start a service on boot, I'm not sure, but it's not supported in this plugin as is right now. I don't use start on boot so I don't test it... Background permissions need google to approve the app, so we decided not to support it (as it needs different service definitions while installing the plugin, which is a mess). In any case, I would try to fork, fix, run and see what fully solves this... I'm sorry I don't have better input...

andreandersson commented 2 years ago

The problem isn't that the service isn't started when rebooting, the problem is that the service is killed after a few seconds for not calling startForeground. I've created a PR for the issue which does solve the issue on our end, but I haven't tested it in other scenarios...