Fence API

Similar to Geofencing, the awareness API allows us to creates fences to listen for when users enter or leave a current region of activities and / or events. One of the great things about the fence API is the ability to listen for contextual changes, for example a fence for user activity could detect when the user begins running and then when they transition to walking. So in terms of contextual signals we could create a fence for:

The users current location, such as their latitude and longitude coordinates

The users current activity, such as walking / running / driving etc

Headphone state, such as when the user connects and disconnects their headphones

Proximity to any nearby beacons, such as the user entering and exiting a beacon zone

Time of day events, such as it being 5 o’clock on Friday 🍻

We can also listen for multiple contextual signals with the use of AND, OR and NOT operators. For example we could listen for when:

The user is running and plugs their headphones in

The user enters a zone of beacons at 4 p.m on a Friday

The user is driving and approaching a specific location

The user plugs their headphones in the evening at bed time

As you can see, the possibilities are endless, the fence API really allows us to listen for contextual changes in the users activities and surroundings. So with that in mind, let’s look at how we can utilise this API 💪

Listening for Fence changes

There’s several parts which are the same for registering any type of fence. To begin with, for each fence we must use a BroadcastReceiver to listen for fence events, in my sample app I create a listener like so:

This listener will receive any callbacks related to our fences that we have registered. So for example, if I register a headphone fence:

The receiver checks the FENCE_KEY matches the FENCE_KEY declared when I register my fence (we’ll look at that in a minute)

Then we check the state of the fence. If the state is TRUE then this means the fence has been entered. So in the case of headphones, this would mean that the headphones are plugged in.

If the fence state is FALSE, then the headphones are not currently plugged in. an UNKNOWN state means that something has gone wrong and we’re unaware of the state.

Now we have our receiver, we must create a new instance of it and use that to create a new PendingIntent - this is the intent that will be launched when our fence triggers a callback.

Now it’s time to register our fence using this intent that we’ve created. There’s a few things that we need to declare, as seen in the code below:

We use the addFence() method to register a fence, we can chain multiple calls to the addFence() method here if we wish to register multiple fences. When calling this method we must pass in:

FENCE_KEY - This is a string key value that is used in our receiver so that we can react accordingly to the correct fence. If using multiple fences, then this is where you can use different keys to handle events individually

- This is a string key value that is used in our receiver so that we can react accordingly to the correct fence. If using multiple fences, then this is where you can use different keys to handle events individually yourFence - This is the fence that you have created and wish to register to, for example if a headphone fence would look like this:

AwarenessFence yourFence = HeadphoneFence.during(HeadphoneState.PLUGGED_IN);

mPendingIntent - This is the intent which we wish to be triggered when fence events occur, in this case our BroadcastReceiver will receive any triggered events

We must also remember to remove any fence when we’re done with them. We can do this by calling the removeFence() method and using the registered fences FENCE_KEY’s to do so:

As well as unregistering fences, don’t forget to unregister your receiver when it is no longer needed!

Now we now how to register and unregister for fences, as well as receive events on them, let’s take a look at the different fences that we can create:

We can create a headphone fence to listen for changes in the headphone connectivity in the users device, allowing us to detect when the user plugs in or unplugs their headphones. This can be created like so:

AwarenessFence headphonesPluggedInFence = HeadphoneFence.during(HeadphoneState.PLUGGED_IN); AwarenessFence headphonesUnpluggedFence = HeadphoneFence.during(HeadphoneState.UNPLUGGED);

We can create a location fence in order to detect when the user is entering, exiting or is in a specified location. All this requires is the latitude, longitude and radius of the location that you wish to monitor, we can create these fences like so:

AwarenessFence inLocationFence = LocationFence.in(

50.830951, -0.146978, 200, 1); AwarenessFence exitingLocationFence = LocationFence.exiting(

50.830951, -0.146978, 200); AwarenessFence enteringLocationFence = LocationFence.entering(

50.830951, -0.146978, 200);

We can create a fence to listen for when the user is engaged in an activity, as well as when they’re starting and stopping it. We can use any of the DetectedActivity types and create fences for them like so:

AwarenessFence headphoneFence = DetectedActivityFence.during(DetectedActivity.WALKING); AwarenessFence startWalking = DetectedActivityFence.starting(DetectedActivity.WALKING); AwarenessFence stopWalkingFence = DetectedActivityFence.stopping(DetectedActivity.WALKING);

We can create a fence to listen for specific time periods to occur. Whether we wish to listen for daily intervals or an interval on a specific day, we can create fences like so:

AwarenessFence fence = TimeFence.inInterval(startTime, endTime); AwarenessFence dailyFence = TimeFence.inDailyInterval(

timeZone, startTime, endTime); AwarenessFence mondayFence = TimeFence.inMondayInterval(

timeZone, startTime, endTime); AwarenessFence tuesdayFence = TimeFence.inTuesdayInterval(

timeZone, startTime, endTime); AwarenessFence wednesdayFence = TimeFence.inWednesdayInterval(

timeZone, startTime, endTime); AwarenessFence thursdayFence = TimeFence.inThursdayInterval(

timeZone, startTime, endTime); AwarenessFence fridayFence = TimeFence.inFridayInterval(

timeZone, startTime, endTime); AwarenessFence saturdayFence = TimeFence.inSaturdayInterval(

timeZone, startTime, endTime); AwarenessFence sundayFence = TimeFence.inSundayInterval(

timeZone, startTime, endTime);

We can create a fence to listen for when we both find and lose beacons that we have registered to. We can use this to detect when a user leaves and exits a designated area of beacons, creating the fences like so: