Android Bluetooth Low Energy | Building Chat App with BLE and Jetpack Compose

Flow of the Article:
- What is BLE?
- Fundamentals of BLE.
- Building Chat App with BLE.
What is BLE?
BLE stands for Bluetooth Low Energy. Bluetooth can handle a lot of data but quickly consumes battery life. Bluetooth Low Energy is used for applications that do not need to exchange large amounts of data and can run on battery power for years at a cheaper cost. Android provides built-in platform support for Bluetooth Low Energy (BLE) in the central role and provides APIs that apps can use to discover devices, query for services, and transmit information. BLE APIs help you to communicate with BLE devices smoothly with less battery consumption.
Fundamentals of BLE
For transmitting data between BLE-enabled devices you need to follow these steps:
- Mention the required permissions in Manifest.xml.
- they must first form a channel of communication.
- Then access BluetoothAdapter and scan for available BLE devices nearby.
- Once a device is found, the capabilities of the BLE device are discovered by connecting to the GATT server on the BLE device.
- Once the connection is established transmit data.
You need to know a few terms before moving forward
Profiles:
A profile is a specification of how a device works in a particular application. A device can implement more than one profile.
Listing a few Profiles:
- Advanced Audio Distribution Profile (A2DP)
2. Generic Attribute Profile (GATT)
3. Health Device Profile (HDP)
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. Using this profile we can transmit data between BLE devices.
Characteristic:
A characteristic contains a single value and optional descriptors that describe the characteristic’s value.
Descriptor:
Descriptors are defined attributes that describe a characteristic value. They can be used to describe the characteristic’s features or to control certain behaviors of the characteristic.
Service:
Service contains a collection of characteristics.
Advertisement:
Advertisement means when a BLE peripheral device broadcasts packets to every device around it. The receiving device can then act on this information or connect to receive more information.
Building Chat App with BLE
Note: When a user pairs their device with another device using BLE, the data that’s communicated between the two devices is accessible to all apps on the user’s device.
Here is the GitHub Link
Let’s build Chat App with BLE Apis
prerequisite: you need two android devices with BLE supported.
Step 1. Create an Android Project you can give any name


Step 2. First, we need to add Permissions plus we need to add ble feature which will be required.
Step 3. Now, we need to ask for location permission.
for permission handling, I am using a library use this library by adding this in the app gradle file.
and now use this to ask for permission in onStart()
Step 4. Now as you can see on Line 16 we will start the GATT server which will send data to the GATT client.
Here in startServer() method we get BluetoothAdapter from BluetoothManager and first we check if Bluetooth is enabled or disabled. if it is disabled then we will call Bluetooth to enable the dialog
when the user enables it we will start the GATT server and then start advertising.
I will show the methods now.
So, now in this method first, I need a GATT server callback as all this process is async. In this callback, there are two methods implemented
onConnectionStateChange: this is called when any remote device is connectedonCharacteristicWriteRequest: this means a remote client has requested to write to a Local Characteristic.
Now setUpGattSerive() method we are creating a local service and adding two characteristics Message needs to have a Unique Id.
Now, let’s discuss startAdvertisement() method
In this method again we will have an advertisement callback which will tell whether the advertising failed or was successful.
We have to mention two more things while starting the advertisement of this device. the advertisement setting how this advertisement will be transmitted to other devices nearby and then data to include while advertising this device. here we are advertising SERVICE_UUID and device name data included.
Step 5. Now we need to scan nearby devices for this we need a BluetoothScanner
It is also similar to our advertisement. Here in this scan callback
we have three methods to implement
onScanResult: this is invoked when an advertisment has been found.onBatchScanResults: this is just returns list of previously scanned devices. onScanFailed: as you might have guessed it will return error code
Here in scanFilters we are looking specifically for the SERVICE_UUID which we mentioned while advertising at the GATT server, not anything else.
In scanSettings define how to do the scanning.
And when you get a device choose a device with which you want to communicate.
you can chat by the connectToChatDevice() method by passing that device instance.
to connect to a device you need to call connectGatt() method and pass GattClient Callback.
onConnectionStateChange(): this will help you tell whether Gatt Client is Connected/Disconnected to/from a remote Gatt server. once connected to a Gatt Server we will discover services provided by the server.
onServiceDiscovered(): In this method, you will find the Services the Gatt Server provides. here we are interested in a service with UUID = SERVICE_UUID.
You are not done creating Bluetooth scanning and advertising.
Just make sure to call stopServer() otherwise the app will drain the battery.
Now, We will focus on creating UI using Jetpack Compose
first, to observe live data as the state you need to add this dependency
match the version with your compose version
Now, In MainActivit.kt . we have 3 states.
- BluetoothScanning State
- ConnectedDeviceConnection State.
- isChatUI open.
Using this we will show a scanning screen and once a device is selected show the chat screen.
This is the chat compose.
Simply used LazyColumn to show chats.
This is the DeviceScan Compose.
Here depending on the Scan states, we will show the UI.
Once scan results is fetched we show the scanned devices in LazyColumn
And That is it.
Here is the Output UI.
It will first prompt you to enable Bluetooth

Then You will get a list of BLE devices having service matching out SERVICE_UUID.
This is the DeviceScan Screen.
Now, On click of any device. Chat Screen will open. You need to install this app on another android device as well and select this device to chat.
That’s it
To learn more about BLE check out this
Thank You for reading