Not sure if this is related to me trying to use it in a react-native module, it is more ore less the same – unless initialising it inside ReactContextBaseJavaModule is a issue.
Everything seems to work. Fence region is added to API without errors, but never triggering.
Maybe there is some trivial thing I have missed, but have gone over multiple tutorials and docs.
Code:
public class BackgroundFence extends ReactContextBaseJavaModule {
private GeofencingClient geofencingClient;
private String TAG = "FENCE:BackgroundFence";
BackgroundFence(ReactApplicationContext context) {
super(context);
}
@ReactMethod(isBlockingSynchronousMethod = false)
public void createFence(double latitude, double longitude,int radius) {
Log.d("BackgroundFence", "Create fence for " + latitude +":"+longitude+" r:"+radius);
Activity activity = this.getReactApplicationContext().getCurrentActivity();
Context context = activity.getBaseContext();
geofencingClient = LocationServices.getGeofencingClient(context);
Geofence geofence = createGeofence(
latitude,
longitude,
radius,
Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT
);
GeofencingRequest geofencingRequest = new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofence(geofence)
.build();
List<Geofence> fences = geofencingRequest.getGeofences();
Log.d(TAG,"Fences: "+fences.size());
for (Geofence fence : fences) {
Log.d(TAG,"Fence: "+fence.getRequestId());
}
PendingIntent pendingIntent = getGeofencePendingIntent();
if (activity == null || ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Log.d(TAG,"No activity or permission");
return;
}
geofencingClient.addGeofences(geofencingRequest, pendingIntent)
.addOnSuccessListener(activity, new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.d(TAG, "onSuccess: Geofence Added...");
}
})
.addOnFailureListener(activity, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG, "onFailure: " + e.getMessage());
}
});
}
private PendingIntent getGeofencePendingIntent() {
ReactApplicationContext context = this.getReactApplicationContext();
Intent intent = new Intent(context, GeofenceBroadcastReceiver.class);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE );
}
public Geofence createGeofence(double latitude, double longitude, float radius, int transitionTypes) {
return new Geofence.Builder()
.setRequestId(generateRequestId())
.setCircularRegion(latitude, longitude, radius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(transitionTypes)
.build();
}
private String generateRequestId() {
return UUID.randomUUID().toString();
}
@Override
public String getName() {
return "BackgroundFence";
}
}
Manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<receiver
android:name=".GeofenceBroadcastReceiver"
android:enabled="true"
android:exported="true"
/>
Reciever:
public class GeofenceBroadcastReceiver extends BroadcastReceiver {
private String TAG = "FENCE:GeofenceBroadcastReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "onReceive!");
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if(geofencingEvent==null) {
Log.d(TAG, "onReceive: geofencingEvent is null");
return;
}
if (geofencingEvent.hasError()) {
Log.d(TAG, "onReceive: Error receiving geofence event...");
return;
}
int transition = geofencingEvent.getGeofenceTransition();
if (transition == Geofence.GEOFENCE_TRANSITION_ENTER) {
Log.d(TAG, "onReceive: ENTER");
} else if (transition == Geofence.GEOFENCE_TRANSITION_EXIT) {
Log.d(TAG, "onReceive: EXIT");
}
}
}
2
Answers
Anyone running in similar issue. Geofencing events don't trigger in emulator. Spent a whole day till I figured this out.
Having the issue on iOS device.. Works fine on Simulator… But intermittent to no firing at all