Is your app Aware?

A few hours ago, Google released for everyone the new Awareness API, a suite of signals concurring to give you (the developer) the context in which our user is, all as part of the Play Services 9.2.0, already available on Android devices around the globe.

This library combines 7 different feeds managing both the battery drain and the used memory, providing us with data such as user location, weather, time, headphones connection status, places, nearby beacons and currently performing activity.

Overview

The Awareness API comes with two different flavours, a callback based one (Fence API) and a polling based one (Snapshot API): while the first one will notify us when the conditions we specified are met, the latter expects us to query the suite for the data from a unified interface. In this article, we will cover the first one, to get a taste of what the platform can do.

Getting started

The first thing we have to do in order to use the new APIs is adding the Awareness suite to the Google API client:

Note: at the time of writing, the Awareness API is being provided by the play-services-contextmanager dependency, that we can include as version 9.2.0 in our build.gradle file.

The next step will be to create the conditions we want to be notified of, and we can freely choose between different ones: the detected activity the user is performing, the place the user is in or the status of the headphones (you can find here all the available trigger conditions, which are called “fences”).

Taken singularly, fences do not really bring anything new to the old (and fragmented) APIs, but they are conditions, thus they can be combined by using boolean operators AND, OR, NOT:

Note: some of the fences (such as entering or exiting a location) work in a slightly different way by being TRUE only for the first 5 seconds of the event, returning then to the state of FALSE. This is because when you are entering some location, the idea of entering is instantaneous and, shortly after that, you are inside the place, you are not entering anymore.

Setting up the request

In order to inform the Awareness API about what we need, we have to create a FenceUpdateRequest, that can be done by taking advantage of the builder paradigm:

The most important line, here, is the second one: fences are internally managed with a key-value system, so that you can understand what fence triggered the update, or even remove unneeded fences. Let’s leave alone the fencePendingIntent, for the moment.

Note: if you call twice the addFence() method with the same key, the second set of data will overwrite the first one.

Once the request is created, we just need to forward the request to the API:

Receiving the updates

As we already stated, the Fence API works with callbacks, and the fencePendingIntent gave us a clue about the way we get notified of the updates: they will be sent to an Intent, thus we need to subclass a BroadcastReceiver and extract the fence from the delivered Intent, in order to check its type and status and react accordingly:

As we see, the fence is delivered together with the key we specified in the request, so that we can easily understand what fence is triggering the receiver and we can deal with the result.

Finally, we can see what was the fuzz about the PendingIntent, but we can say that the system works more or less like the Alarm system, thus we need to wrap into it the same action we want to listen to, so that the the Awareness API knows which receiver will be notified:

Wrapping up

These new APIs are certainly far from being complete, but they are an important step towards a smarter apps ecosystem, a wiser battery usage and, certainly, an easier way for us developers to interact with the context surrounding our users.