Create and Monitor Geofencing in Android

Posted By : Prince Bhardwaj | 31-Dec-2018

Introduction

 

Geofencing consolidates awareness of the client's current location with a familiarity with the client's nearness to locations that might be of interest for the client. To highlight an area of interest, you indicate its latitude and longitude. To modify the nearness for the location, you include a radius. The latitude, longitude, and radius characterize a geofence, making a circular area, or fence, around the area of interest.

 

We can have multiple dynamic geofences, with a limit of 100 for every device user overall applications. For each geofence, we can ask Location Services to send you to enter and exit occasions, or we can also indicate a time period inside the geofence territory to pause or dwell, before triggering an event. We can limit the duration of any geofence by setting an expiration duration in milliseconds. After the geofence terminates, Location Services consequently removes it.

 

Now, we will discuss how to add geofence events in an android application and listen to them when the user enters or stay at a location(dwell).

 

1. Setup Geofence

 

To set geofence in our app, we first need to have ACCESS_FINE_LOCATION

permission granted. To request this permission we need to ask this     permission in our manifest file as :

 

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

 

For listening to geofence events, we have used a receiver where we receive geofence triggers. For this, add an element referring to the receiver as -

 

<application
  android:allowBackup="true">
  ...
  <service android:name=".GeofenceTransitionsIntentService"/>
<application/>

 

2. Create and Add Geofences

 

We first need to connect to Location Services API. For this, we have to create an instance of Geofencing client as -

 

GeofencingClient geofencingClient = LocationServices.getGeofencingClient(mContext);

Now we need to add geofences to the geofence list. To create a geofence,   we have to use Geofence.Builder() as

 

private Geofence getGeofence(double lat, double lang, String key) {
  return new Geofence.Builder()
       // Set the request ID of the geofence. This is a string to identify this
       // geofence.
          .setRequestId(key)

       
// Set circular region of the geofence
          .setCircularRegion(lat, lang, GEOFENCE_RADIUS)

      // Set the expiration duration of the geofence.
          .setExpirationDuration(Geofence.NEVER_EXPIRE)

    // Set the transition types of interest. Alerts are only triggered for          
    // these transition. We track entry and dwell(pause) transitions in this example.
          .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                  Geofence.GEOFENCE_TRANSITION_DWELL)

    // Set the delay between GEOFENCE_TANSITION_ENTER AND GEOFENCE_TRANSITION_DWELLING
          .setLoiteringDelay(10000)  // optional
          .build();
}  

 

In this example, we have used two transitions-

 

 

 

 

GEOFENCE_TRANSITION_ENTER

 

 

 

 

 

 

 

: This transition event triggers when a device enters a geofence area.

 

 

 

 

GEOFENCE_TRANSITION_ENTER

 

 

 

 

 

 

 

: The transition event triggers when the user enters and dwells in geofences for a given period of time.

 

We can also use

 

 

 

GEOFENCE_TRANSITION_EXIT :  which is triggered when a device leaves a geofence area.


The above method will return a geofence object to be added in geofence list and to be used to create geofence request as -

 

private GeofencingRequest getGeofencingRequest(ArrayList<Geofence> geofences) {
  GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
  builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
  builder.addGeofences(geofences);
  return builder.build();
}

 

Determining INITIAL_TRIGGER_ENTER indicates Location services that GEOFENCE_TRANSITION_ENTER transition should be triggered if the device is already inside the geofence.

 

In most of the cases, it might be desirable overuse rather INITIAL_TRIGGER_DWELL, which triggers events just when the client stops for a specified duration inside a geofence.

 

To listen to geofence events, we should add a pending intent to our geofence client where we receive all the triggered events.

 

private PendingIntent getGeofencePendingIntent() {
  Intent intent = new Intent(mContext, GeofenceTransitionsIntentService.class);
      return PendingIntent.getService(mContext, 0, intent,
              PendingIntent.FLAG_UPDATE_CURRENT);
}

 

To add geofences, we have to use GeofencingClient.addGeofences() method. Give the GeofencingRequest object, and the PendingIntent. The accompanying piece shows handling the results:

 

geofencingClient.addGeofences(getGeofencingRequest(geofences),
      getGeofencePendingIntent())
      .addOnCompleteListener(new OnCompleteListener<Void>() {
          @Override
          public void onComplete(@NonNull Task<Void> task) {
              if (task.isSuccessful()) {
                  Toast.makeText(mContext,
                          "Location alter has been added",
                          Toast.LENGTH_SHORT).show();
              }else{
                  Toast.makeText(mContext,
                          "Location alter could not be added",
                          Toast.LENGTH_SHORT).show();
              }
          }
      });


 

3. Listen to Geofence Transitions

 

At the point when Location Services detects that the user has entered or dwells in a geofence area, it conveys the Intent contained in the PendingIntent you incorporated into the request to include geofences. This Intent is received by a service like GeofenceTransitionsIntentService, which gets the geofencing event from the intent, decides the type of Geofence transition(s), and figures out which of the defined geofences was triggered.

 

In this example, we have used JobIntentService keeping in mind the Background Services Limits On Android 8.0 (API level 26) and higher.

 

public class LocationAlertIntentService extends JobIntentService {
  private static final String IDENTIFIER = "LocationAlertIS";

  public LocationAlertIntentService() {
  }

  @Override
  protected void onHandleWork(Intent intent) {

      GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
      geofencingEvent.getTriggeringLocation();
      if (geofencingEvent.hasError()) {
          Log.e(IDENTIFIER, "" + getErrorString(geofencingEvent.getErrorCode()));
          return;
      }

      int geofenceTransition = geofencingEvent.getGeofenceTransition();
      Log.i(IDENTIFIER, String.valueOf(geofenceTransition));

      if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER||geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL) {
      // Do whatever your requirement is as per your application
    
}
}
}

 

4. Stop/Remove Geofence Monitoring

It is best practice to remove geofence monitoring when it is no longer needed. We can remove geofence in the main activity used to add geofences. We can remove a geofence either by pending

Intent or by requests. Here are the two methods which are used to remove geofences by pending intent -

  

public void removeLocationAlerts(){
      if (!isLocationAccessPermitted()) {
          return;
      } else {
          geofencingClient.removeGeofences(getGeofencePendingIntent())
                  .addOnCompleteListener(new OnCompleteListener<Void>() {
                      @Override
                      public void onComplete(@NonNull Task<Void> task) {
                      }
                  });
      }
  }

and by requestIds-

public void removeLocationAlerts(List<String> requestIds) {
  if (!isLocationAccessPermitted()) {
      return;
  } else {
      geofencingClient.removeGeofences(appGeofenceIds)
              .addOnCompleteListener(new OnCompleteListener<Void>() {
                  @Override
                  public void onComplete(@NonNull Task<Void> task) {
                  }
              });
  }
}

 

Best Practices for Geofencing

  • 1. Use Dwell Transition to reduce alert spam.
  • 2. Re-register geofences only when required.

    The application must re-register geofences if they're required after the accompanying events since the system can't recover the geofences in the following cases:

    The device is rebooted. The application ought to tune in for the device's boot finished activity, and after that re-register the geofences required.

    The application is uninstalled and re-installed.

    The application's data is cleared.

    Google Play services data is cleared.

    The application has received a GEOFENCE_NOT_AVAILABLE alarm. This ordinarily occurs after NLP (Android's Network Location Provider) is disabled.

 

 



 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

About Author

Author Image
Prince Bhardwaj

Prince Bhardwaj is having Talent as Application Developer, he is an enthusiastic team player in Oodles Technologies.

Request for Proposal

Name is required

Comment is required

Sending message..