page.title=Creating and Monitoring Geofences

trainingnavtop=true
@jd:body


<div id="tb-wrapper">
<div id="tb">

<h2>This lesson teaches you to</h2>
<ol>
    <li><a href="#RequestGeofences">Set up for Geofence Monitoring</a></li>
    <li><a href="#CreateAdd">Create and Add Geofences</a></li>
    <li><a href="#HandleGeofenceTransitions">Handle Geofence Transitions</a></li>
    <li><a href="#StopGeofenceMonitoring">Stop Geofence Monitoring</a></li>

</ol>

<h2>You should also read</h2>
<ul>
    <li>
        <a href="{@docRoot}google/play-services/setup.html">Setup Google Play Services SDK</a>
    </li>
</ul>

<h2>Try it out</h2>

   <ul>
      <li>
        <a href="https://github.com/googlesamples/android-play-location/tree/master/Geofencing"
        class="external-link">Geofencing</a>
      </li>
    </ul>

</div>
</div>
<p>
    Geofencing combines awareness of the user's current location with awareness of the user's
    proximity to locations that may be of interest. To mark a
    location of interest, you specify its latitude and longitude. To adjust the proximity for the
    location, you add a radius. The latitude, longitude, and radius define a geofence, creating a
    circular area, or fence, around the location of interest.
</p>
<p>
    You can have multiple active geofences, with a limit of 100 per device user. For each geofence,
    you can ask Location Services to send you entrance and exit events, or you can specify a
    duration within the geofence area to wait, or <em>dwell</em>, before triggering an event. You
    can limit the duration of any geofence by specifying an expiration duration in milliseconds.
    After the geofence expires, Location Services automatically removes it.
</p>

<img src="{@docRoot}images/training/geofence@2x.png"
srcset="{@docRoot}images/training/geofence.png 1x, {@docRoot}images/training/geofence@2x.png 2x" alt=""
  width="400" height="400"/>
<p>
    This lesson shows you how to add and remove geofences, and then listen for geofence transitions
    using an {@link android.app.IntentService}.</p>

<h2 id="RequestGeofences">Set up for Geofence Monitoring</h2>
<p>
    The first step in requesting geofence monitoring is to request the necessary permission.
    To use geofencing, your app must request
    {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION}. To request this
    permission, add the following element as a child element of the
<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
    element in your app manifest:
</p>
<pre>
&lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/&gt;
</pre>

<p>
    If you want to use an {@link android.app.IntentService} to listen for geofence transitions,
    add an element specifying the service name. This element must be
    a child of the <code><a href="{@docRoot}guide/topics/manifest/application-element.html">
    &lt;application&gt;</a></code> element:
</p>

<pre>
&lt;application
   android:allowBackup=&quot;true&quot;&gt;
   ...
   &lt;service android:name=".GeofenceTransitionsIntentService"/&gt;
&lt;application/&gt;
</pre>

<p>To access the location APIs, you need to create an instance of the
  Google Play services API client. To learn how to connect your client, see
  <a href="{@docRoot}training/location/retrieve-current.html#play-services">Connect
  to Google Play Services</a>.</p>

<h2 id="CreateAdd">Create and Add Geofences</h2>

<p>Your app needs to create and add geofences using the location API's builder class for
 creating Geofence objects, and the convenience class for adding them. Also, to handle the
 intents sent from Location Services when geofence transitions occur, you can define a
 {@link android.app.PendingIntent} as shown in this section.
</p>

<h3>Create geofence objects</h3>

<p>
    First, use <code><a href="{@docRoot}reference/com/google/android/gms/location/Geofence.Builder.
    html">Geofence.Builder</a></code> to create a geofence, setting the desired radius, duration, and
    transition types for the geofence. For example, to populate a list object named
    {@code mGeofenceList}:
    </p>

<pre>
mGeofenceList.add(new Geofence.Builder()
    // Set the request ID of the geofence. This is a string to identify this
    // geofence.
    .setRequestId(entry.getKey())

    .setCircularRegion(
            entry.getValue().latitude,
            entry.getValue().longitude,
            Constants.GEOFENCE_RADIUS_IN_METERS
    )
    .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
            Geofence.GEOFENCE_TRANSITION_EXIT)
    .build());
</pre>

<p>This example pulls data from a constants file. In actual practice, apps might
    dynamically create geofences based on the user's location.</p>

<h3>Specify geofences and initial triggers</h3>

<p>
    The following snippet uses the <code><a href="{@docRoot}reference/com/google/android/gms/location/GeofencingRequest.html">
    GeofencingRequest</a></code> class
    and its nested <code><a href="{@docRoot}reference/com/google/android/gms/location/GeofencingRequest.Builder.html">
    GeofencingRequestBuilder</a></code> class to
    specify the geofences to monitor and to set how related geofence events are triggered:
</p>
<pre>
private GeofencingRequest getGeofencingRequest() {
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
    builder.addGeofences(mGeofenceList);
    return builder.build();
}
</pre>

<p>
    This example shows the use of two geofence triggers. The <code><a href="{@docRoot}reference/com/google/android/gms/location/Geofence.html#GEOFENCE_TRANSITION_ENTER">
    GEOFENCE_TRANSITION_ENTER</a></code>
    transition triggers when a device enters a geofence, and the <code><a href="{@docRoot}reference/com/google/android/gms/location/Geofence.html#GEOFENCE_TRANSITION_EXIT">
    GEOFENCE_TRANSITION_EXIT</a></code>
    transition triggers when a device exits a geofence. Specifying
    <code><a href="{@docRoot}reference/com/google/android/gms/location/GeofencingRequest.html#INITIAL_TRIGGER_ENTER">
        INITIAL_TRIGGER_ENTER</a></code> tells Location services that
    <code><a href="{@docRoot}reference/com/google/android/gms/location/Geofence.html#GEOFENCE_TRANSITION_ENTER">
        GEOFENCE_TRANSITION_ENTER</a></code>
    should be triggered if the the device is already inside the geofence.</p>
</p>

<p>In many cases, it may be preferable to use instead <code><a href="{@docRoot}reference/com/google/android/gms/location/GeofencingRequest.html#INITIAL_TRIGGER_DWELL">
    INITIAL_TRIGGER_DWELL</a></code>,
    which triggers events only when the user stops for a defined duration within a geofence.
    This approach can help reduce "alert spam" resulting from large numbers notifications when a
    device briefly enters and exits geofences. Another strategy for getting best results from your
    geofences is to set a minimum radius of 100 meters. This helps account for the location accuracy
    of typical WiFi networks, and also helps reduce device power consumption.
</p>

<h3>Define an Intent for geofence transitions</h3>
<p>
    The {@link android.content.Intent} sent from Location Services can trigger various actions in
    your app, but you should <i>not</i> have it start an activity or fragment, because components
    should only become visible in response to a user action. In many cases, an
    {@link android.app.IntentService} is a good way to handle the intent. An
    {@link android.app.IntentService} can post a notification, do long-running background work,
    send intents to other services, or send a broadcast intent. The following snippet shows how
    to define a {@link android.app.PendingIntent} that starts an {@link android.app.IntentService}:
</p>
<pre>
public class MainActivity extends FragmentActivity {
    ...
    private PendingIntent getGeofencePendingIntent() {
        // Reuse the PendingIntent if we already have it.
        if (mGeofencePendingIntent != null) {
            return mGeofencePendingIntent;
        }
        Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
        // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when
        // calling addGeofences() and removeGeofences().
        return PendingIntent.getService(this, 0, intent, PendingIntent.
                FLAG_UPDATE_CURRENT);
    }
</pre>

<h3>Add geofences</h3>

<p>
    To add geofences, use the <code><a href="{@docRoot}reference/com/google/android/gms/location/GeofencingApi.html#addGeofences(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.location.GeofencingRequest, android.app.PendingIntent)">{@code GeoencingApi.addGeofences()}</a></code> method.
    Provide the Google API client, the <code><a href="{@docRoot}reference/com/google/android/gms/location/GeofencingRequest">
    GeofencingRequest</a></code> object, and the {@link android.app.PendingIntent}.
    The following snippet, which processes the results in <code><a href="{@docRoot}reference/com/google/android/gms/common/api/ResultCallback.html#onResult(R)">
    onResult()</a></code>, assumes that the main activity implements <code><a href="{@docRoot}reference/com/google/android/gms/common/api/ResultCallback.html">
    ResultCallback</a></code>:
</p>
<pre>
public class MainActivity extends FragmentActivity {
    ...
    LocationServices.GeofencingApi.addGeofences(
                mGoogleApiClient,
                getGeofencingRequest(),
                getGeofencePendingIntent()
        ).setResultCallback(this);
</pre>


<h2 id="HandleGeofenceTransitions">Handle Geofence Transitions</h2>
<p>
    When Location Services detects that the user has entered or exited a geofence, it
    sends out the {@link android.content.Intent} contained in the {@link android.app.PendingIntent}
    you included in the request to add geofences. This {@link android.content.Intent} is received
    by a service like <code>GeofenceTransitionsIntentService</code>,
    which obtains the geofencing event from the intent, determines the type of Geofence transition(s),
    and determines which of the defined geofences was triggered. It then sends a notification as
    the output.
</p>
<p>
    The following snippet shows how to define an {@link android.app.IntentService} that posts a
    notification when a geofence transition occurs. When the user clicks the notification, the
    app's main activity appears:
</p>
<pre>
public class GeofenceTransitionsIntentService extends IntentService {
   ...
    protected void onHandleIntent(Intent intent) {
        GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
        if (geofencingEvent.hasError()) {
            String errorMessage = GeofenceErrorMessages.getErrorString(this,
                    geofencingEvent.getErrorCode());
            Log.e(TAG, errorMessage);
            return;
        }

        // Get the transition type.
        int geofenceTransition = geofencingEvent.getGeofenceTransition();

        // Test that the reported transition was of interest.
        if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
                geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {

            // Get the geofences that were triggered. A single event can trigger
            // multiple geofences.
            List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();

            // Get the transition details as a String.
            String geofenceTransitionDetails = getGeofenceTransitionDetails(
                    this,
                    geofenceTransition,
                    triggeringGeofences
            );

            // Send notification and log the transition details.
            sendNotification(geofenceTransitionDetails);
            Log.i(TAG, geofenceTransitionDetails);
        } else {
            // Log the error.
            Log.e(TAG, getString(R.string.geofence_transition_invalid_type,
                    geofenceTransition));
        }
    }
</pre>

<p>After detecting the transition event via the {@link android.app.PendingIntent},
    this {@link android.app.IntentService} gets the geofence transition type and tests whether
    it is one of the events the app uses to trigger notifications -- either
    <code><a href="{@docRoot}reference/com/google/android/gms/location/Geofence.html#GEOFENCE_TRANSITION_ENTER">GEOFENCE_TRANSITION_ENTER</a></code>
     or <code><a href="{@docRoot}reference/com/google/android/gms/location/Geofence.html#GEOFENCE_TRANSITION_EXIT">GEOFENCE_TRANSITION_EXIT</a></code>
    in this case. The service then sends a notification and logs the transition details.</p>
<!--
    Remove Geofences
 -->
<h2 id="StopGeofenceMonitoring">Stop Geofence Monitoring</h2>

<p>Stopping geofence monitoring when it is no longer needed or desired can help save battery
    power and CPU cycles on the device. You can stop geofence monitoring
    in the main activity used to add and remove geofences; removing a geofence stops it
    immediately. The API provides methods to
    remove geofences either by request IDs, or by removing geofences associated with a given
    {@link android.app.PendingIntent}.
</p>
<p>
    The following snippet removes geofences by {@link android.app.PendingIntent}, stopping all
    further notification when the device enters or exits previously added geofences:
</p>
<pre>
LocationServices.GeofencingApi.removeGeofences(
            mGoogleApiClient,
            // This is the same pending intent that was used in addGeofences().
            getGeofencePendingIntent()
    ).setResultCallback(this); // Result processed in onResult().
}
</pre>

<p>
    You can combine geofencing with other location-aware features, such as periodic location updates.
    For more information, see the other lessons in this class.
</p>
