Question

I am using the built in geofence APIs (play services) and have been having mixed results. It looks like after setting a geofence, the notifications for entering/exiting are very inconsistent even when GPS is on, with an up-to-date location (LocationClient connected, running in the background.) I started monitoring (polling) location changes and distances in a debug text field, and saw that, even when based on the location registered by the device and the location of the geofence I am technically inside/outside of the geofence, notifications are sometimes triggered and sometimes not. Any way to make this more predictable? I am almost tempted to abandon this api and implement my own (battery draining) geofences based on polling of device location.

Was it helpful?

Solution

A couple of suggestions:

  1. Make sure you're using a BroadcastReceiver and not a Service to receive the transitions, otherwise you will not/might not get it if your app gets killed/turned off. As discussed here: Android Geofence eventually stop getting transition intents

  2. Make sure you recreate your geofences after the device is rebooted, preferably using a boot-broadcast receiver. As discussed here: Do Geofences remain active in android after a device reboot

  3. One other common misconception, and which stumped me since it's different than IOS is that you'll always get a trigger immediately for a newly created geofence, if the device discovers that you're inside the geofence when creating it. I have solved this myself using a "grace period" for newly created geofences, which i explained in this thread: addProximityAlert doesn't work as expected

Finally one important thing: Having your LocationClient connected in your app or not should not matter at all if you follow the points above. My process for adding or removing Geofences in my code is basically:

  1. Create and connect locationclient.

  2. In connect-callback, do adding/removing of geofence(s)

  3. In geofence-result callback, disconnect locationclient.

Every time this happens, my location client is only connected a few seconds in total. The operating system will still produce geofence alerts and call my BroadcastReceiver whenever they happen.

If you do these things I bet your experience will improve.

Hope this helps!

OTHER TIPS

I tried all the suggestions from the accepted response but the accurate wasn't better for my. If you are here looking more ideas you should read the following.

I was able manage the problem doing my own geofences algorithm based on android location api plus JTS Location Suite

To be more accurate. All you need is to create a jts polygon thats represent mathematically your fence.

static GeometryFactory GF = new GeometryFactory();

public Polygon getPolygon() {
    ArrayList<Coordinate> coors = new ArrayList<>();
    
    for (Point p : getPolygonPoints()) {
        coors.add(new Coordinate(p.lat, p.lon));
    }

    // close the polygon is needs
    final Coordinate first = coors.get(0);
    final Coordinate last = coors.get(coors.size()-1);
    if (!first.equals2D(last)) {
        coors.add(coors.get(0));
    }

    // create polygon
    return GF.createPolygon(coors.toArray(new Coordinate[] {}));
}

Then you can check whether if a current GPS point is inside or not of given polygon.

final Point point = GF.createPoint(new Coordinate(lat, lon));
if (point.within(getPolygon())) {
   // hit
} else {
   // miss
}

That's it all. Then you can create a java.util.Timer to periodically iterate a list of polygons (geo fences) to know which was hit or which was behind.

Note: Add the following in your module build.gradle to add JTS library in your project:

implementation(group: 'org.locationtech.jts.io', name: 'jts-io-common', version: '1.18.1') {
   exclude(group: 'org.hamcrest')
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top