I have exhausted everything and really appreciate some help.
What I want to do is exactly what Geofences are for: to get a notification when I enter, dwell or exit a location.
So far, the performance has been horrible, to say the least.
I have scoured SO for couple of weeks now. Here's a summary of what I have tried:
- Use of a broadcast receiver (instead of Service as given in the official example, not that it should change anything)
- Use ENTER | DEWLL | EXIT transitions, to get a hit on any transition
- Increase radius to 250m
- Periodically poll GPS for location using RequestLocationUpdates
So far, the geofences triggers are a hit and miss. Most of the time they are not triggered at all and sometimes I triggered when I have drove past the location 5 minutes ago.
The only thing that seemed to help was the periodic GPS polling, but even that, the pending intents are received at very irregular intervals.
Do you have anything else I can try? Please let me know. Thanks!!!
Here are some snippets of my code:
GPS Polling
public static void CreateLocationUpdateRequest(Context context)
{
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setInterval(10000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setMaxWaitTime(10000);
locationRequest.setExpirationDuration(1000000);
Intent locReqIntent = new Intent("LOCATION_UPDATE");
PendingIntent locUpdatePendingIntent = PendingIntent.getBroadcast(context, 0, locReqIntent, PendingIntent.FLAG_UPDATE_CURRENT);
FusedLocationProviderClient fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Task<Void> locationTask = fusedLocationProviderClient.requestLocationUpdates(locationRequest, locUpdatePendingIntent);
locationTask.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.i("CreateGeofencingRequest", "SUCCESS");
}
});
locationTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.i("CreateGeofencingRequest", "FAILED");
}
});
}
}
Creating Geofence request
geofenceTransitionType = Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_DWELL | Geofence.GEOFENCE_TRANSITION_EXIT;
Geofence geofence = new Geofence.Builder()
.setRequestId(String.valueOf(geofencingReq.getId()))
.setCircularRegion(Double.parseDouble(location.getLatitude()), Double.parseDouble(location.getLongitude()), 250)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(geofenceTransitionType)
.setLoiteringDelay(2000)
.build();
GeofencingRequest geofencingRequest = new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofence(geofence)
.build();
Intent geofencingIntent = new Intent(context, GeofenceBroadcastReceiver.class);
geofencingIntent.putExtra("ID", geofencingReq.getId());
geofencingIntent.setAction("GEOFENCE_TRIGGER_BROADCAST");
PendingIntent geofencingPendingIntent = PendingIntent.getBroadcast(context, geofencingReq.getId(), geofencingIntent, PendingIntent.FLAG_UPDATE_CURRENT);
LocationManager locManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
boolean providerEnabled = locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
Task<Void> geofenceTask = mGeofencingClient.addGeofences(geofencingRequest, geofencingPendingIntent);
geofenceTask.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.i("CreateGeofencingRequest", "SUCCESS");
}
});
geofenceTask.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.i("CreateGeofencingRequest", "FAIL");
}
});
}
}