Bluetooth


Introduction

The framework supports a layer of abstraction above the native Android handling of Bluetooth and Bluetooth Low Energy (BLE) connections, in order to simplify their inclusion in any application.  In Android, this handling occurs at a very low level, and has separate philosophies for Bluetooth versus BLE, namely their treatment in polling versus event-based terms. In the Berkeley Telemonitoring framework we have endeavored to make the experience with dealing with each of these more similar and straightforward, and have included a more generic overarching Bluetooth Health Device class that encapsulates both device types with a unified interface.

This tutorial will briefly show the functionality of Bluetooth, BLE, and generic Bluetooth Health Device operation within the framework. Finally we will show a full example of usage for a Health Device.

Prerequisites

In order to communicate with any Bluetooth or BLE device, permission to enable and use Bluetooth must be specified in the AndroidManifest.xml file of the client application by adding the following lines:

Bluetooth Device Flow

Ensuring Bluetooth Discoverability

The first step in incorporating Bluetooth communications into an application is to turn on Bluetooth capabilities and ensure the device is discoverable with the following line of code:

Scanning for Devices

Unless the MAC address of the peripheral Bluetooth device you wish to connect to is already known, it is necessary to scan for nearby devices to find those accessible for connection.  Before starting the scan, you will likely want to add a listener to handle events like devices found and scan completed:

Once any desired listeners to handle events relating to the scan have been added, you can start a scan with the following line:

Establishing a Connection

Next, to establish a pairing connection with a Bluetooth device found or specified (represented as a  UnpairedBluetoothDevice with a name and address), we can set a  PairedBluetoothDevice as the result of calling  pairToDevice() on the unpaired device, if successful, which we can finally initiate an attempt to connect to:

We will again likely wish to add a listener to handle events such a successful connection or data received from the paired device after connection is established:

It is now also possible to write data in a BluetoothSendable format to the paired and connected device using:

BLE Device Flow

The process for establishing connection with a BLE device is fairly similar in our framework to that for Bluetooth devices.

Ensuring BLE Is Enabled

To ensure that BLE communications can be established, the service can be called to switch on Bluetooth:

Scanning for Devices

Again, if the device MAC address is not already known it may be necessary to scan for nearby devices, and again it is likely desirable to add a listener to handle BLE events before beginning the scan:

Establishing a Connection

Next, to begin exchanging data with a BLE device, given a  BLEDevice instance with the device’s name and address, as with Bluetooth it is then necessary to call  connect for that device:

And as for Bluetooth we will likely wish to add an event listener to handle connection and data events from the BLE device:

The framework abstracts away concepts like the Gatt server that you may be familiar with from native Android BLE support, and automatically handles tasks like starting service discovery upon connection, reading values when a characteristic changes, and following specified retry logic upon lost connection (described below in the section on Bluetooth Connection Configuration).

Bluetooth Health Device

This unified class combines Bluetooth and BLE device handling into one common interaction, abstracting the lower-level details as much as possible.  To establish a connection with a Bluetooth Health Device, it is still necessary to either scan for or provide a device address, and then to create a  BluetoothHealthDevice  instance from the paired Bluetooth device or BLE device object device :

Bluetooth Health Devices have their own set of listeners that can be added to handle connection and data events, specific to the profile they follow. For instance, given a Bluetooth Health Device representing a Heart Rate monitor, we might add a listener as follows:

At present listener interfaces have been created to allow the developer to handle events for Heart Rate, Temperature, Blood Pressure, Weighing Scale, and Glucose monitoring devices, but the framework can easily be extended to support additional health device profiles in the future.

Bluetooth Connection Configuration

In addition to the framework’s setup to handle scanning for and establishing connections to devices, it also allows for more specific configuration of retry logic upon initial and lost connections to devices (for each of Bluetooth, BLE, or Bluetooth Health Device). This configuration is optional, but can be added as follows, to set these preferences before connection to the device:

Bluetooth Connection Configuration options include flags for both initial connection and reconnection to follow patterns of NO_RETRY, RETRY_UNTIL_TIMEOUT, or RETRY_INDEFINITELY . For instance, to modify the above configuration to retry connection only until a timeout of 15 seconds you could apply the following:

The default setting is to have no retry attempts on either initial or lost connection, simply to try once to connect to a specified device and to close the connection if it is lost.

A visualization of the connection lifecycle of a device following each configuration option is depicted by the following:

bt_lifecycle

Heart Rate Monitor Example

The following code is an example that shows how a listener would be implemented to access data being received from an external Bluetooth heart rate monitor. The class should extend the BluetoothHeartRateListenerInterface , and therefore contain the method  heartRateDataReceived. Within this method you can access the incoming Bluetooth heart rate monitor data.