At work we've created an app that will track the routes a user makes to and from work and we have an automatic recording feature build in but it's not behaving the way we would like. It seems like this automatic system is being turned off by the OS after a day or two of inactivity (the phones don't even move during that time, they're used only for testing basically).
On iOS we're using CLRegions to create a couple regions around the user's current location, there are 5 regions created at the exact location of the user with different radiuses and 12 created in a circle around the user at a distance of 10 meters (these have a radius of 80 meters). The CLLocationManager object is also instructed to start monitoring significant changes and visits (though these have yet to be fired even once).
On Android we're using Geofences through the LocationServices API and here we only have the 5 incremental radiuses around the user's current location. In case the user closes the app on Android or restarts their phone it will launch a background service which will re-initialize the geofences and start monitoring them.
Both systems work really well when I'm testing them by walking a bit outside but it seems like after a day or two of inactivity (aka the weekend) they stop working. I've been debugging this for quite a while now and even though it has become better it's still not perfect.
Is it even possible to have a reliable system of automatically starting the app in the background when a geofence/region is triggered no matter how long the app has been turned off? I know both OS's handle background tasks very differently but I'm not quite sure on the long term limitations of GPS usage in this way.
The app we're making is written in Xamarin Forms but these systems are written in their native project (still in C# but full access to the entire native platform)
The thing with Android services, is that the OS kills the background service, since it is considered low priority, then restarts at a timed interval. This can happen several times through out several days, each time incrementing the length of time before restarting the service (some phones just use a set time, no incrementing).
My suggestion is that if you want an always on service, you need to make it into a foreground service. I'd give some code examples of how to implement this, but I do not know Xamarin very well, so I don't want to give you any bad examples.
Another approach is to use an AlarmManager with a PendingIntent to check if a service is running and start it in case it isn't. Just be aware that if you do this too often, it can lead to a noticeable battery drain, but if you don't do it often enough, you can potentially miss out on geofence events.
Hope this helps, and good luck!
UPDATE #1
Here are the code samples for both having a service in the foreground and running an AlarmManager.
Foreground
This is properly the easiest way to keep your app alive.
AlarmManager
This will continuously try to create this service at the interval you set (10 minutes for this example). There are a few pitfalls here, although. First, due to Android 6.0 introducing Doze Mode, the AlarmManager may not fire off while the phone is asleep, which means the service may be dead for quite some time. Second, is that this calls the
onStartCommandfunction several times, so you'll need logic to handle that.Of these two, setting the service as a foreground service is probably the easiest thing, unless you really can't have that, then the AlarmManager is the route to take.