Geofences on Android with GoogleApiClient
In this tutorial you’ll learn how to leverage GoogleApiClient to add geofences to an Android app, as well as post notifications when a geofence is crossed. By Joe Howard.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Geofences on Android with GoogleApiClient
30 mins
- Getting Started
- Running the Starter Project
- Working with GoogleApiClient
- Creating Geofence Objects
- Creating GeofenceController
- Adding Geofences
- Connecting to GoogleApiClient
- Wiring Everything Up
- Adding Persistence
- Removing Geofences
- Displaying a Notification
- Testing with Mock Locations
- Where To Go From Here?
Road trip! Summer is almost here, and for families the world over, that means hopping in the car and heading to a favorite vacation spot. For long trips, the inevitable “Are we there yet?” questions will ring forth from the kids in the back seat.
Wouldn’t it be great to give them an easy means to know definitively one way or another? Geofences can do just that! And may in fact lead to more peace and tranquility for the whole family. :]
“What’s a geofence?” I hear you ask – it’s nothing more than a virtual perimeter around a specified geographic location, which can be monitored and used to trigger events when its boundaries are crossed.
In this tutorial, you’ll build an Android app named “AWTY?” which uses GoogleApiClient, a component of Google Play Services, to add geofences. Your users will be able to enter a name, location, and size for a desired geofence. When entering the geofence, your users will get an Android notification of a geofence crossing.
Getting Started
Download the starter project for this tutorial. This project was created using Android Studio 1.2.
Fire up Android Studio, and choose either Open an existing Android Studio project or File\Open…, then navigate to and select the downloaded project folder. Once the project is open, you may need to select View\Tool Windows\Project to see the project files in the Project pane.
There are seven source code files in the starter project; take a moment to familiarize yourself with them:
-
AddGeofenceFragment.java: a
DialogFragment
used to create a geofence. -
AllGeofencesActivity.java: an
ActionBarActivity
that displays a single fragment. -
AllGeofencesAdapter.java: a
RecyclerView
adapter that transforms geofences to instances ofCardView
. -
AllGeofencesFragment.java: a
Fragment
that displays geofences in aRecyclerView
. -
AreWeThereIntentService.java: an
IntentService
that will send a notification to the user when they enter a geofence. - Constants.java: a class to hold some static constants.
- NamedGeofence.java: a model class that will be used to serialize the geofences.
The view-related classes have ViewHolder
inner classes containing the associated views. Each of the res subfolders has a number of other resource files that define colors, strings, dimensions, and styles; res/layout has files for each of the activity and fragment classes. Finally, the listitem_geofence.xml layout file defines the CardView
that will be used to display geofences.
The following build settings have been specified in build.gradle, and you should make sure you have the corresponding Android SDK packages installed:
- minSdkVersion: 16
- compileSdkversion: 22
- targetSdkVersion: 22
- buildToolsVersion: 22.0.1
Finally, note the dependencies for the starter project defined in build.gradle; the app includes the CardView
and RecyclerView
classes from the Android Support Library along with two third-party libraries: Gson, for serializing objects to JSON, and FAB, a library used to display a floating action button.
Running the Starter Project
Time to run up your app to see how it looks in its current state. Testing geofences on a physical device is best, but if need be, you can run the app on the Android emulator. Doing so requires an emulator setup with Google Play Services installed.
To create a new emulator that will work with Google Play Services, choose Tools\Android\AVD Manager from the Android Studio menu. Next choose the Create Virtual Device… button in the lower left:
Select the Nexus 5, and choose Next:
On the next screen, choose an API Level of 22 as this is the latest version at time of writing. For the best emulator performance, use an ABI of x86 or x86_64 if you have HAXM installed. If you don’t have HAXM, choose armebi-v7a for the ABI. Also, to use geofences in the emulator you must choose a target with Google APIs to ensure that Google Play Services are available:
Once you’ve selected your system image, click Finish in the lower right:
To test your new emulator, go back to the AVD Manager and hit play on the emulator you just created:
Press Ctrl-R or click the run button in the Android Studio toolbar to ensure the starter app builds and runs successfully:
Now that you’ve successfully launched the starter project, you can begin building out the full app. Time to start tracking your users…no, not really. Promise you’ll never, ever do that! :]
Working with GoogleApiClient
With the December 2014 release of Google Play Services 6.5, geofences are now created using GoogleApiClient
. The Location package is one of the dependencies listed in build.gradle:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:22.0.0'
compile 'com.android.support:cardview-v7:22.0.0'
compile 'com.android.support:recyclerview-v7:22.0.0'
compile 'com.google.code.gson:gson:2.3'
compile 'com.github.shell-software:fab:1.0.5'
compile 'com.google.android.gms:play-services-location:6.5.87'
}
While there are versions of Google Play Services higher than 6.5.87, this is a version that most of your users’ devices should have.
If you’ve never installed Google Play Services, go to Tools\Android\SDK Manager to open the Android SDK Manager and install the requisite library:
Creating Geofence Objects
The NamedGeofence
class stores geofence data in primitives, but you will also use it to create Geofence
objects.
Add the following public method to the class:
public Geofence geofence() {
id = UUID.randomUUID().toString();
return new Geofence.Builder()
.setRequestId(id)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.setCircularRegion(latitude, longitude, radius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build();
}
The above method uses the Builder pattern to instantiate a new geofence object. You first create a unique id for the geofence and then build a geofence based on the values in NamedGeofence
. The geofence type is specified as GEOFENCE_TRANSITION_ENTER
, and the geofence is set to never expire.
Note: Beyond the basic properties of location (in terms of latitude and longitude) and size (usually given as a radius), geofences can have a fixed lifespan, or stay active with no expiration.
Geofences can be defined as entry, which triggers when the user enters the fence; exit, when the user leaves the fence; dwell, where the user stays inside the fence for a certain length of time period, or even a combination of these three.
In this tutorial, you’ll stick with creating entry geofences.
Note: Beyond the basic properties of location (in terms of latitude and longitude) and size (usually given as a radius), geofences can have a fixed lifespan, or stay active with no expiration.
Geofences can be defined as entry, which triggers when the user enters the fence; exit, when the user leaves the fence; dwell, where the user stays inside the fence for a certain length of time period, or even a combination of these three.
In this tutorial, you’ll stick with creating entry geofences.
Now that you have a way to create Geofence
objects, it’s time to create a companion controller class.