Bluetooth beacons are transmitters that use Bluetooth Low Energy 4.0 (BLE) to broadcast signals that can be heard by compatible or smart devices. These transmitters can be powered by batteries or a fixed power source such as a USB adapter. When a smart device is in a beacon’s proximity, the beacon will automatically recognize it and will be able to interact with that device.
A few weeks ago, we were lucky enough to be introduced to the Eddystone project by the team here in London. It’s certainly a very interesting project and I thought it’d be a good idea to share our experience.
What’s the Google Eddystone project
Eddystone is a protocol specification that defines a BLE message format for proximity beacon messages. It is robust and extensible: It describes several different frame types that may be used individually or in combinations to create beacons that can be used for a variety of applications. It’s cross-platform, capable of supporting Android, iOS or any platform that supports BLE beacons. And it’s available on GitHub under the open-source Apache v2.0 license, for everyone to use and help improve.
Register your beacons
Before we can start playing with the APIs we need to provision our devices. Since beacons is not something you can buy from your local grocery store, you will need to purchase one of the developer kits from one of the several manufacturers which Google has already partnered with.
In our case, we are going to use one of Developer Kits from Estimote
Unfortunately, each manufacturer has it’s own process to provision the beacons. For that reason, I’d strongly recommend sticking with just one manufacturer for your development purposes. Estimote happens to have a very simple process in order to provision the beacons, just a couple of minutes and we were ready to go!
No beacons? No problem
It’s also possible to give a go at the Eddystone platform without purchasing some beacons. There is a simple Android application that allows your phone to broadcast Eddystone-UID BLE packets. Only some more recent devices are capable of using this ability classes. The application will check if your device is compatible and show an error dialog if not. The Nexus 6 phone and Nexus 9 tablet are known to work well.
In order to make use of the beacons platform, you’ll need to setup a project in the Google Developers Console account. Follow these instructions to create a project and register the application with your account. You’ll have to enable the Google Proximity Beacon API and create both an Android API Key and an Android OAuth 2.0 client ID.
As it turns out, following this order is very important. It took me a while to figure that out, but creating an API Key before enabling the permission was causing some problems and I wasn’t able to connect to the Google services. After creating the project and adding the proper APIs, this is what you should be seeing.
Google Proximity Beacon API
One of the biggest advantages that the Proximity API introduces is the ability to manage your BLE beacons using a REST interface. It’s now possible to manage an entire beacon fleet from your living room with ease. There is no need to be physically next to the beacon in order to manage it. If you take a look at the complete reference you’ll see that this API provides services to register, manage, index, and search beacons.
The authentication happens using an OAuth access token from a signed-in user with Is owner or Can edit permissions in the Google Developers Console project.
The sample application
For the purpose of this post, I’ve built an application that allows you to register and manage Eddystone beacons. It’s very simple to use and showcases several endpoints from the Proximity API that are worth looking at.
Before we can start registering and managing the beacons, seems obvious but we first need to find them, The setup is not very complicated, however it’s very important to understand what’s happening. First of all, we need to add the permissions so the application has access access to Bluetooth sensor.
Lucky for us, BluetoothLeScanner provides methods to perform scan related operations for Bluetooth LE devices. We can restrict the scan to only those beacons that are of interest to us ScanFilter and we can also request different types of callbacks for delivering the result.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
Since we are only interested in Eddystone beacons we need to create a filter that scans only devices with Eddystone Service UUID. The second parameter in this method corresponds to the scan settings used to define the parameters for the scan via ScanSettings. There are three different scan modes available: balanced, low latency and low power. For the purpose of this example we are using an aggressive approach since we want to react to the beacons as soon as possible. This approach is only recommended when the application is running in the foreground.
Now that we’ve decided the scanning approach we want to follow it’s time to look at the Callback that the BluetoothAdapter calls.
1 2 3 4 5 6
At this point we need to check if we are receiving a valid Eddystone beacon. What the adapter sends us back is a ScanResult which may or may not be an Eddystone beacon. We’ll use the frame type byte to do the validation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
We are now able to recognize if the scan result is an Eddystone beacon or not, but still don’t know anything about the beacon itself. In order to do that we’ll need to use the Google Client API, which is why earlier we had to create a Project in the Developers Console.
You’ll only be able to manage the beacons that are associated to your Google account. There are several steps involved in this process and we’ll cover them all in a second.
First of all you’ll need to associate your account with the project that we created earlier in the Google Developer Console.
1 2 3 4 5 6 7
We’ll use the
AccountPicker from Play Services in order to start the authentication flow. Once the account is selected we’ll start the Authentication call. Using Play Services and the useful
GoogleAuthUtil class we’ll be able to generate the token that validates the user. Besides the account name, we’ll also need to send the AUTH_SCOPE for the task. In this case, authentication to register the beacons.
Yes, it’s an
AsyncTask but obviously you are more than welcome to handle this with your preferred Non-UI thread solution.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
The first time the user starts the authentication flow a dialog will appear:
Accessing to a beacon data
At this point we can both scan beacons and use our account to register them with Eddystone, however we are still not reading any data from Eddystone yet. The magic happens in the BluetoothScanner class thanks to the interface ProximityBeacon. This interface maps all the rest endpoints supported by Eddystone and that will allow us to access all it’s capabilities. We wouldn’t be able to access all these endpoints unless our account has been previously authenticated, this is why is so important to follow the proper order of steps to get here.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
You are already familiar with this callback, it’s what we receive from the
BluetoothScanner when locating a beacon. After validating that the scan result is indeed an Eddystone beacon, we’ll make use of the
ProimityBeacon API in order to retrieve it’s data.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
The Proximity Beacon API will return a JSON response when the request is successful. We’ll get more into detail about that JSON to Object conversion in a second. Firstly, I wanted to drive your attention to the other two status code responses, 403 and 404.
We’ll get a 403 if the request is made with an account that has not authorized access to the Eddystone platform as seen before. This means that we can’t read or modify the beacon data related to Eddystone. Receiving a 404 means that the beacon itself is not registered with the platform.
If you take a look at the BeaconConverter you’ll get to see all the different values that the platform sends us. Such as
description and even more interesting things like
placeId which gives is the Google Places Id which this beacon has been assigned to.
Changing the data associated with a beacon
Once we’ve done all the dance of scanning, authenticating and receiving the beacons, we can finally look what’s inside them! To make it easy I’m presenting the data in three separate
Cards: Info, Location and Attachments.
Any time we want to modify the data of a beacon we’ll need to make a call to
updateBeacon from the REST API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
As you can see we are following the same pattern as before, there is a remote endpoint that we hit and a callback when we check the response. The difference here is that we need to pass a JSON object to the
updateMethod call. The BeaconConverter class does that for us.
Adding Attachments to a Beacon
One of the most interesting features of Eddystone is the ability to add attachments to your beacons. This means that you could add some information there that your application users could read (not modify). Imagine a train station with 20 rail lines and several beacons placed next to each line. Your application could ready the attachment from one of those beacons and tell the user that he / she is standing next to the middle section of rail line number 12. The possibilities are endless!
When you create an attachment, you must populate two fields. * namespacedType: a string made up of a namespace identifier, followed by a forward slash and the data type. The namespace identifier can’t be modified and is assigned to your Google Developer Console project. * data: a base64 encoded value of the data type defined in the namespacedType field.
You may have noticed that
updateBeacon does not modify the attachments of a beacon. That’s because there is a different endpoint for it. Each attachment is translated to it’s own JSON Object and sent to the Proximity Beacon API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
Another interesting feature of Eddystone is the ability to assign a Beacon to a specific Google Places ID. The very handy LatLng class from Play Services allow us to request a Place Picker which will return a Place object which gives us all the information we want.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Eddystone is a great platform that, once implemented, will bring a whole new set of experiences for our day to day life. There are literally thousands of use cases where the user will be the main beneficiary of this technology. I can’t wait to see what developers and companies come up with!
If you are curious to see the whole implementation, all the source code is published on Github. As always, all the feedback is welcome!
You may have seen an empty Tab in the application, it corresponds to the
Nearby Messages API which I’ll be covering soon. Stay tuned!