How to Advertise Android as a Bluetooth LE Peripheral

Although a relatively new technology, Bluetooth Low Energy (LE) has already proven itself to be a versatile and useful communication medium. While it can be used for connecting devices to each other wirelessly, it also enables devices to act as beacons and broadcast data.

In this tutorial, you will learn about the BluetoothLeAdvertiser class, which enables developers to turn a supported phone into a Bluetooth LE beacon without the need for additional hardware. You will also learn how to scan for Bluetooth LE advertisement data so that you can react appropriately within your own applications. You can download the source files for this tutorial on GitHub.

1. Project Setup

For this tutorial, you can start by creating a basic empty project in Android Studio. You need to set the minimum SDK version to 21 in your build.gradle file, as Bluetooth LE advertising was not introduced on Android until the release of Lollipop. Although there are ways to wrap the APIs that are not supported before SDK 21, they will not be covered in this tutorial. We're only going to focus on the new technology at hand.

Next, you need to add three permissions to the project's AndroidManifest.xml. The first two allow for Bluetooth communication and the third permission, ACCESS_COARSE_LOCATION, is a new requirement for using Bluetooth on Android 6.0 devices and above.

If you are developing on a device that runs Android 6.0 or above, your app needs the location permission granted by the user. Instructions for doing that can be found in Understanding Permissions in Android M, which I wrote earlier this year. For the sake of simplicity, this tutorial will simply grant the permission from the Android App Info screen.

Android app permissions screen showing the location permission granted

Now that you have permission to access everything your application will need, it's time to create the layout file. Open activity_main.xml and create a simple layout with two buttons and a text view.

The two Button objects are used to start advertisement or discovery. The TextView is used to display data found on discovery. When you are done filling in the layout file, you can close it and open MainActivity.java. The first thing you do in this file is add the implementation for View.OnClickListener that is used by the buttons.

In the above onClick(View v) method, advertise() and discover() are defined later in this tutorial. You can add stubs for those methods now in order for your app to compile. Next, you need to create member variables at the top of the class to keep track of the buttons and the text view.

Once you have your views defined, you need to initialize them in onCreate(Bundle savedInstanceState) and wire each Button up to the OnClickListener you defined earlier.

Finally, make sure that the device you or your users are using supports multiple advertisements. While the software features necessary for advertising as a peripheral are available from Lollipop on, manufacturers must also use a Bluetooth chipset that can support advertisement.

If Bluetooth LE advertising is not supported, you should disable the two buttons in your application. While this feature is known to work on the Nexus 6, 5X, 6P, and 9, there are other phones that also support Bluetooth LE advertisement and additional devices will continue to be made as manufacturers create newer phones and tablets.

2. Advertising Over Bluetooth LE

To start advertising over Bluetooth LE, you need to retrieve the BluetoothLeAdvertiser from the Android BluetoothAdapter. You can do this in the advertise() method that is called when the advertising button is tapped.

Once you have your BluetoothLeAdvertiser, you define the settings that are used when advertising, such as the amount of power the antenna should use when broadcasting and how often the device should advertise. The AdvertiseSettings.Builder class also allows you to define whether the mobile device should be connectable, which allows you to stream much more data across devices.

You'll notice that this example is advertising with high signal strength (TX power) and low latency. While this makes your device discoverable quickly, it can also take up a lot of the battery, which is a precious commodity when you are developing in the mobile space.

There are other options for the advertising mode. The ADVERTISE_MODE_LOW_POWER option is the default setting for advertising and transmits the least frequently in order to conserve the most power. The ADVERTISE_MODE_BALANCED option attempts to conserve power without waiting too long between advertisements.

TX power can be set to ultra low, low, medium, or high. Each level corresponds to how far a Bluetooth LE advertising packet will be visible, though exact ranges depend on the device hardware.

Next, you define a UUID that is used for identifying your packets when they are advertised. You can create a new UUID by using the uuidgen utility from the command line.

While this utility creates a 128-bit UUID, the Android system only uses 16-bit UUIDs for advertisement and will automatically adjust a 128-bit UUID to conform. In the example above, the 16-bit UUID would be 950D. Next, save the 128-bit UUID as a string in strings.xml.

Once you have your UUID created, it's time to create the ParcelUuidAdvertiseData object, and broadcast some additional data as an additional service. For this example, you just broadcast the name of the device and the string "Data" (which must be converted to a byte array) as the size of your advertising packets are fairly limited.

The last thing you do to advertise over Bluetooth LE with your device is create a callback that listens for success or failure when advertising, and then start advertising over the BluetoothLeAdvertiser.

At this point, you should be able to run your app and start advertising over Bluetooth LE. However, the next step in this tutorial will go over discovering advertisements so that you can display that information.

3. Discovering Bluetooth LE Advertisements

Before you begin discovering Bluetooth LE services, you need to add a few more member variables at the top of your class.

mBluetoothLeScanner is used for scanning for Bluetooth LE packets and mHandler controls a small timer that stops discovery after a set period of time.

In addition to these member variables, you need to create a new ScanCallback at the top of your class so that it can be accessed later in your application by an inner class. This callback receives the result of a discovered acceptable advertisement and displays the advertising device name and associated data in a text view.

Next, initialize mBluetoothLeScanner in onCreate(Bundle savedInstanceState) as shown below.

After you have initialized the Bluetooth scanner, you can start to flesh out the discover() method. For this sample application, you create a ScanFilter object and place it into a List so that your application only responds to the advertising packets that you are interested in.

You also need to create a ScanSettings object, which works similarly to the AdvertiseSettings object that you created earlier in this tutorial.

Once you have your filters, settings, and callbacks in place, you can begin discovering Bluetooth LE advertisements.

If you run your application now on two devices that both support Bluetooth LE advertisements and set one to advertise and the other to discover, the discovering device should find the advertiser and display the advertised data. The following screenshot shows a Nexus 5X discovering an advertising Nexus 6.

Nexus 5X discovering Bluetooth LE advertisement packets from a Nexus 6

The last thing you need to do is create a new Runnable object and associate it with mHandler. The handler waits for ten seconds and then start the Runnable that stops discovery. The reason for this is that discovery can quickly drain the battery of the device. You only want to attempt to discover advertisement packets for short periods of time or when you expect to find an advertising device.

Conclusion

While this example may not be much to look at, you've just created a fully working app that advertises over Bluetooth LE so that other devices can discover it and transfer data. Although this tutorial went over advertising and discovering with Android, you can just as easily make a similar app for iOS in order to share data across the two platforms or build your own Bluetooth LE enabled device that can interact with mobile phones and tablets.

As this technology continues to grow and be integrated into everyone's pockets, there will be endless possibilities for developers to make really interesting things. For more information on working with additional Bluetooth technology on Android, check out Create a Bluetooth Scanner With Android's Bluetooth API by Matthew Kim.

Tags:

Comments

Related Articles