Android Bluetooth Low Energy Communication — Simplified

It seems a bit confusing while setting up communication of Bluetooth LE with our apps and guess what — it is! But we’ll be moving ahead to the point and understand what matters in order to make it work in the simplest manner.
Before integrating the BLE communication, we should be clear on few terms:
Generic Attribute Profile (GATT) — The GATT profile is a general specification for sending and receiving short pieces of data known as “attributes” over a BLE link. All current Low Energy application profiles are based on GATT.
Attribute Protocol (ATT) — GATT is built on top of the Attribute Protocol (ATT). This is also referred to as GATT/ATT. ATT is optimized to run on BLE devices.
Characteristic — A characteristic contains a single value and 0-n descriptors that describe the characteristic’s value. A characteristic can be thought of as a type, analogous to a class.
Service — A service is a collection of characteristics. For example, you could have a service called “Heart Rate Monitor” that includes characteristics such as “heart rate measurement.”
Descriptor — Descriptors are defined attributes that describe a characteristic value. For example, a descriptor might specify a human-readable description, an acceptable range for a characteristic’s value, or a unit of measure that is specific to a characteristic’s value.
A BLE device can have one or more GATT profiles for multiple purposes like Temperature measurement and Heart Rate measurement.
Each GATT profile contains a Service and each service has some Characteristics. Each of these attribute is uniquely identified by a Universally Unique Identifier (UUID), which is a standardized 128-bit format for a string ID used to uniquely identify information.
To communicate with BLE device, we should know from which service and characteristic, the data can be retrieved.
Let’s dive into the code set up.
Manifest permissions required:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
One must be wondering why Location permission is used, here is the note

The first step in the process is to identify if the Bluetooth is enabled on device or not. If not then enable it using BluetoothAdapter object.


Once the Bluetooth is turned on, we also need to make sure if the device is running on Marshmallow or above then location services should also be turned ON by requesting at runtime. Otherwise, BLE search won’t detect the devices.
Now, Bluetooth and other services are ready, we should now request a scan of devices nearby.


We’ve successfully scanned the devices. As we select our BLE device from the list, we need to connect it via its device address.

Our BLE Service(which is running) will take care of notifying us about the connection status and data status.
As soon as the mBluetoothGatt gets connected, we receive the onConnectionStateChange and inside which we checks the connection status and start services discovery as

As the services from BLE device are discovered, onServicesDiscovered callback comes up as

If you remember, we’ve defined our Service and Characteristics of interest as

In order to continuously gets notified about the change in characteristics, we need to set the Notification as ON for the characteristics. In our case, we need to know about the temperature change. So after the discovery callback, here’s how we do it

We loop through every service & characteristics and enable notification for characteristics and then write them on the BluetoothGatt object defined in our Service.
As we’re all set up, everytime the value of characteristics changes, we received it in the onCharacteristicChanged.

For the very first time, when we receive the characteristic value, we can read it in onCharacteristicRead

Also, don’t forget to add the service in the manifest file.

The last thing is to convert the data received from BLE into readable format.
This depends on the BLE device you’re using. I’ve used some calculation provided by the hardware engineer to convert the data into correct temperature value because the BLE device was configured so.
Well! That is it. You can now start using the BLE device with your app.
Hope it has cleared your doubts and confusion.
Happy Coding :)
Cheers!