BleGattServer

class BleGattServer(context: Context, bluetoothAdapter: BluetoothAdapter)

A Bluetooth Low Energy (BLE) GATT server implementation that allows an Android device to act as a BLE peripheral.

This class provides functionality to:

  • Start and stop a GATT server with customizable services and characteristics

  • Advertise the device to nearby BLE centrals (scanners)

  • Handle read/write requests from connected central devices

  • Send notifications to subscribed devices

  • Manage characteristic values and notification subscriptions

GATT Server Overview

A GATT (Generic Attribute Profile) server hosts a hierarchy of services and characteristics that can be discovered and interacted with by connected clients (centrals). This implementation includes:

  • Automatic handling of the Client Characteristic Configuration Descriptor (CCCD) for notification subscriptions

  • Support for prepared (long) writes with offset handling

  • Proper response handling for read and write requests

Required Permissions

The following permissions must be declared in AndroidManifest.xml:

  • android.permission.BLUETOOTH (for API < 31)

  • android.permission.BLUETOOTH_ADMIN (for API < 31)

  • android.permission.BLUETOOTH_ADVERTISE (for API >= 31)

  • android.permission.BLUETOOTH_CONNECT (for API >= 31)

Usage Example

Setting up a basic BLE peripheral with Heart Rate Service:

class MyPeripheralActivity : AppCompatActivity() {

private lateinit var gattServer: BleGattServer
private val heartRateMeasurementUUID = UUID.fromString("00002A37-0000-1000-8000-00805f9b34fb")

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
val bluetoothAdapter = bluetoothManager.adapter

// Initialize the GATT server
gattServer = BleGattServer(this, bluetoothAdapter)

// Start the server (this also starts advertising)
gattServer.startServer()
}

// Send heart rate updates to subscribed clients
private fun sendHeartRateUpdate(heartRate: Int) {
val value = byteArrayOf(0x00, heartRate.toByte()) // Flags + Heart Rate
gattServer.sendNotification(heartRateMeasurementUUID, value)
}

override fun onDestroy() {
super.onDestroy()
// Always stop the server when done
gattServer.stopServer()
}
}

Custom Services Example

To create a peripheral with custom services, you can extend this class or modify the addServices method:

// Define custom UUIDs
val CUSTOM_SERVICE_UUID = UUID.fromString("12345678-1234-1234-1234-123456789abc")
val CUSTOM_CHAR_UUID = UUID.fromString("12345678-1234-1234-1234-123456789abd")

// Create a service with read/write/notify capabilities
val service = BluetoothGattService(CUSTOM_SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY)

val characteristic = BluetoothGattCharacteristic(
CUSTOM_CHAR_UUID,
BluetoothGattCharacteristic.PROPERTY_READ or
BluetoothGattCharacteristic.PROPERTY_WRITE or
BluetoothGattCharacteristic.PROPERTY_NOTIFY,
BluetoothGattCharacteristic.PERMISSION_READ or
BluetoothGattCharacteristic.PERMISSION_WRITE
)

// Add CCCD for notification support
val cccd = BluetoothGattDescriptor(
CLIENT_CHARACTERISTIC_CONFIG_UUID,
BluetoothGattDescriptor.PERMISSION_READ or BluetoothGattDescriptor.PERMISSION_WRITE
)
characteristic.addDescriptor(cccd)
service.addCharacteristic(characteristic)

Thread Safety

This class is not thread-safe. All method calls should be made from the main thread or properly synchronized. The GATT server callbacks are delivered on an internal Binder thread, which this implementation handles appropriately.

See also

Constructors

Link copied to clipboard
constructor(context: Context, bluetoothAdapter: BluetoothAdapter)

Functions

Link copied to clipboard
fun getCharacteristicValue(characteristicUUID: UUID): ByteArray?

Gets the current stored value of a characteristic.

Link copied to clipboard
fun sendNotification(characteristicUUID: UUID, value: ByteArray): Boolean

Sends a notification to all connected devices that have enabled notifications for the specified characteristic.

Link copied to clipboard
fun setCharacteristicValue(characteristicUUID: UUID, value: ByteArray)

Sets the value for a characteristic without sending a notification.

Link copied to clipboard

Initializes and starts the GATT server with predefined services and characteristics.

Link copied to clipboard

Stops the GATT server and BLE advertising.