Here is the situation:
When a user creates a Geofence, I save it to backend and I register a Geofence with the OS. But whenever my app restarts I fetch geofences from my backend and reregister them with the OS again, since they keep disappearing.
I have two classes MainActivity
and FormActivity
. Both of these activities register Geofences, so I have extracted the actual registration to an ordinary POJO Geofences.java
Here is the problem:
Now the strange thing is, triggers are only received when a map activity is on the screen. I do have a map activity in my app, but it doesn't even have to be my map-activity, even if I launch google maps geofence triggers start firing.
What am I doing wrong?
Geofences.java:
public class Geofences {
private final String TAG = Geofences.class.getSimpleName();
private final float RADIUS = 150.0F; //meter
private boolean success = false;
private final int LOITERING_IN_MILLISECONDS = 30000;// 30 seconds
public boolean doGeofenceStuff(GeoTemp newTemp, String geofenceId, PendingIntent pendingIntent, GeofencingClient geofencingClient) {
Geofence geofence = createGeofence(newTemp, geofenceId);
GeofencingRequest geofencingRequest = createGeofenceRequest(geofence);
geofencingClient.addGeofences(geofencingRequest, pendingIntent)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if (task.isSuccessful()) {
success = true;
Log.i(TAG, "onComplete: DEBUG-Message: Geofence has been added.");
} else {
success = false;
Log.i(TAG, "onComplete: Geofence could not be added");
}
}
}); // handle error here
return success;
}
// Create a Geofence
private Geofence createGeofence(GeoTemp geoTemp, String geofenceId) {
long expiration = getExpirationForCurrentGeofence();
if (expiration < 1) {
Log.e(TAG, "createGeofence: Can't create Geofence, since expiration is less than zero");
return null;
}
Log.d(TAG, "createGeofence");
return new Geofence.Builder()
.setRequestId(geofenceId)
.setCircularRegion(getLat(), getLong(), RADIUS)
.setExpirationDuration(expiration)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_DWELL | Geofence.GEOFENCE_TRANSITION_EXIT)
.setLoiteringDelay(LOITERING_IN_MILLISECONDS)
.build();
}
// Create a Geofence Request
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
Log.d(TAG, "createGeofenceRequest");
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL)
.addGeofence(geofence)
.build();
}
}
This POJO Geofences.java
is then used by two of my activities:
MainActivity:
public class MainActivity extends AppCompatActivity {
private static String TAG = "MainActivity";
private final int GEOFENCE_REQ_CODE = 0;
private GeofencingClient geofencingClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
geofencingClient = LocationServices.getGeofencingClient(this);
getCurrentTemps();
}
private void refreshGeofence(GeoTemp temp, String id) {
new Geofences().doGeofenceStuff(temp, id, createGeofencePendingIntent(), geofencingClient);
}
private void getCurrentTemps() {
List<GeoTemp> currentGeofences = getUpdatedList();
currentGeofences.forEach(geoTemp -> {
refreshGeofence( geoTemp, id);
});
}
private PendingIntent createGeofencePendingIntent() {
Log.d(TAG, "createGeofencePendingIntent");
Intent intent = new Intent(this, LocationAlertIntentService.class);
return PendingIntent.getService(
this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
There is one more activity which uses Geofences.java to register geofences with the operating system.
Update:
I have found out that, if any other app (including mine) requests for location lock, geofence triggers fire. I need them to fire in the background.