skip to Main Content

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


  1. Chosen as BEST ANSWER

    Anyone running in similar issue. Geofencing events don't trigger in emulator. Spent a whole day till I figured this out.


  2. Having the issue on iOS device.. Works fine on Simulator… But intermittent to no firing at all

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search