December 7th, 2016

Google Awareness API for Android: Query and React to Signals

James Montemagno
Principal Manager, Tech PM

awareness-apiGoogle Play services offers a plethora of amazing APIs for developers to integrate into their iOS and Android applications. For Android developers, specifically, there are several more APIs available that can give you even more power and integration with the Android OS when developing apps for the platform. One of the newest APIs, Awareness, brings together seven different location and context signals into a single easy to use API, including time, location, places, beacons, headphones, activity, and even weather. The NuGet package for the Awareness API launches alongside our release of Google Play services 9.6.1 (32.961.0) for Xamarin.

The Awareness API offers two different ways to get insight to these signals, the Fence and the Snapshot APIs. The Fence API allows you to react to changes in the user’s environment and the signals. You can create multiple conditions that need to be met and when they occur, you receive a callback to react to them. The Snapshot API on the other hand, which we’ll look at today, gives you direct access to the signals from one simple asynchronous API. In addition to being a simple API, the Awareness API delivers better battery performance and memory usage due to its intelligent caching and cross-app optimizations.

snapshotandfence

Install the Awareness NuGet

The first step to accessing the Awareness APIs is to add the Google Play services – Awareness NuGet to your Xamarin.Android application. As of this blog post, the current version is 32.961.0. The easiest way to find the NuGet is to directly enter the package name Xamarin.GooglePlayServices.Awareness. The additional dependencies of Google Play services Places, Location, Base packages, and required Support Packages will also come along when the NuGet is added.

addnuget

Register for API Keys

Google Play services often require a unique API key for each application using them. These are created and enabled in the Google API Developer Console. First create a new project: 1-new-project

Once it is created, you’ll want to enable three different APIs:

  • Awareness API
  • Google Places API for Android (for Places API)
  • Nearby Messages API (for Beacons API)

2-add-apis

You’ll need to enter your application’s package name and the keystore’s SHA1 you’re using for debug and release when ready to deploy to the app store to register these. You can read through Obtaining your Signing Key Fingerprint in our Android documentation.

Simply create new credentials using these keys. 3-credentials

Add Keys to the Android Manifest

Once you have registered for the APIs, you’ll receive a unique API Key that needs to be added to your Android Manifest file. It’s the same API Key for each of the meta-data tags that we’ll add to the application node, which will look like this:


    
    
    

Create GoogleAPIClient

With all of the API Key registration out of the way, it’s now time to actually start using the Awareness API. To use any Google Play service API, we’ll need to create a GoogleApiClient. First let’s bring in a few namespaces:

using Android.Gms.Common.Apis;
using Android.Gms.Awareness;
using Android.Gms.Awareness.State;
using Android.Gms.Extensions;

Now, in our Activity, we can create and connect to the GoogleApiClient:

public class MainActivity : Activity
{
  GoogleApiClient client;
  protected async override void OnCreate(Bundle bundle)
  {
    base.OnCreate(bundle);

    client = await new GoogleApiClient.Builder(this)
                       .AddApi(Awareness.Api)
                       .AddConnectionCallbacks(() =>
                        {
                          //Connected Successful
                        })
                        .BuildAndConnectAsync((i) =>{ });
            
  }
}

Query Signals

We can now start using the API to query signals, such as headphones.

var headPhones = await Awareness.SnapshotApi.GetHeadphoneStateAsync(client);
if (headPhones?.Status?.IsSuccess ?? false)
{
  if(headPhones.HeadphoneState.State == HeadphoneState.PluggedIn)
    Debug.WriteLine(Headphones plugged in");
  else
    Debug.WriteLine(Headphones not plugged in");
}
else
{
  Debug.WriteLine("Could not get headphone state");
}

Other signals besides headphones require additional permissions such as location and activity recognition. We must add two specific permissions to the Android Manifest:



To check and request permissions, we can use the Permissions Plugin that helps abstract the functionality into a simple call. If we want to query the location and weather, we can use the Permissions Plugin along side the Awareness API:

//Check and request permissions
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (status != PermissionStatus.Granted)
{
  var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
  if (results[Permission.Location] != PermissionStatus.Granted)
    return; //handle rejection
}

//Get current location
var location = await Awareness.SnapshotApi.GetLocationAsync(client);
if (location?.Status?.IsSuccess ?? false)
  Debug.WriteLine($"Location: {location.Location.Latitude},{location.Location.Longitude}");

//Get weather information
var weather = await Awareness.SnapshotApi.GetWeatherAsync(client);
if (weather?.Status?.IsSuccess ?? false && weather.Weather != null)
{
  Debug.WriteLine($"Temperature: {weather.Weather.GetTemperature(1)} ";
  Debug.WriteLine($"Humidity: {weather.Weather.Humidity}%";
  Debug.WriteLine($"Feels Like: {weather.Weather.GetFeelsLikeTemperature(1)} ";
  Debug.WriteLine($"Dew Point: {weather.Weather.GetDewPoint(1)} ";
}

We can even take it a step further and detect the user’s current activity, such as running or cycling, by requesting the Detected Activity:

var detectedActivity= await Awareness.SnapshotApi  .GetDetectedActivityAsync(client);
if (detectedActivity?.Status?.IsSuccess ?? false)
{
  var probablyActivity = detectedActivity?.ActivityRecognitionResult ?.MostProbableActivity;
  Debug.WriteLine(probablyActivity?.ToString() ?? "No activity"); 
}

Learn More

The Awareness API is extremely powerful and at the same time extremely energy efficient when querying signals on the device. You can download a full source code example from my GitHub page that walks through using each of the Snapshot APIs, and you can also learn more about the Awareness API from the Google Developer portal.

Author

James Montemagno
Principal Manager, Tech PM

James Montemagno is a Principal Lead Program Manager for Developer Community at Microsoft. He has been a .NET developer since 2005, working in a wide range of industries including game development, printer software, and web services. Prior to becoming a Principal Program Manager, James was a professional mobile developer and has now been crafting apps since 2011 with Xamarin. In his spare time, he is most likely cycling around Seattle or guzzling gallons of coffee at a local coffee shop. He ...

More about author

0 comments

Discussion are closed.