8000 GitHub - NordicSemiconductor/Kotlin-BLE-Library
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

NordicSemiconductor/Kotlin-BLE-Library

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Kotlin BLE Library for Android

The library simplifies usage of Android Bluetooth Low Energy on Android. It is a wrapper around native API and uses Kotlin Coroutines for asynchronous operations. The usage is designed to be more natural according to the BLE specification.

Warning

This library is in early development stage and is not recommended for production use. The API is subject to change. Any feedback is welcome.

Version 2

We are working on version 2 of the library. The new version will be a complete rewrite of the library.

Current status:

  • Central role
    • Scanning
      • Scanning for nearby Bluetooth LE devices
      • Ranging and monitoring device
      • Obtaining list of connected devices
    • Establishing connection
      • Direct (autoConnect = false)
      • Using AutoConnect feature
      • Service discovery and subscribing to services changes
    • Basic GATT operations
      • Reading / writing characteristics
      • Enabling notifications / indications
      • Subscribing to value changes
      • Requesting highest MTU
    • Advanced GATT operations
      • Requesting PHY
      • Subscribing to PHY changes
      • Requesting connection priority
      • Subscribing to connection parameter changes
      • Reliable write
    • Mock implementation
  • Peripheral role
    • Advertising
    • Setting up GATT server
    • GATT operations
    • Mock implementation

Documentation

Dokka documentation can be found here.

Scanning

val centralManager = CentralManager.Factory.native(context, scope)
centralManager
    .scan(1250.milliseconds) {
        ServiceUUID(someServiceUUID)
        Any {
            Name("MyName")
            Name("OtherName")
        }
    }
    .distinctByPeripheral()
    .map {
        it.peripheral
    }
    .onEach { peripheral ->
        // Do something with the peripheral
    }
    .launchIn(scope)

Connecting

scope.launch {
    try {
        withTimeout(10000) {
            centralManager.connect(
                peripheral = peripheral,
                options = CentralManager.ConnectionOptions.Direct(
                    timeout = 3.seconds,
                    retry = 2,
                    retryDelay = 1.seconds,
                    Phy.PHY_LE_1M,
                ),
                // options = CentralManager.ConnectionOptions.AutoConnect,
            )
            Timber.i("Connected to ${peripheral.name}!")
        }
    
        // The first time the app connects to the peripheral it needs to initiate
        // observers for various parameters.
        // The observers will get cancelled when the connection scope gets cancelled,
        // that is when the device is manually disconnected in case of auto connect,
        // or disconnects for any reason when auto connect was false.
        peripheral.phy
            .onEach {
                Timber.i("PHY changed to: $it")
            }
            .onEmpty {
                Timber.w("PHY didn't change")
            }
            .onCompletion {
                Timber.d("PHY collection completed")
            }
            .launchIn(this)
    } catch (e: Exception) {
        Timber.e(e, "Connection attempt failed")
    }
}

Service discovery

peripheral.services()
    .onEach { services ->
        Timber.i("Services changed: $services")

        services.forEach { remoteService ->
            // Do something with the service.
        }
    }
    .onEmpty {
        Timber.w("No services found")
    }
    .onCompletion {
        Timber.d("Service collection completed")
    }
    .launchIn(scope)

GATT operations

Reading characteristic value

remoteService.characteristics.forEach { remoteCharacteristic ->
    try {
        Timber.w("Reading value of ${remoteCharacteristic.uuid}...")
        val value = remoteCharacteristic.read()
        Timber.i("Value of ${remoteCharacteristic.uuid}: 0x${value.toHexString()}")
    } catch (e: Exception) {
        // An exception is thrown when a characteristic is not readable, or an error occurs.
        Timber.e("Failed to read ${remoteCharacteristic.uuid}: ${e.message}")
    }
}

Subscribing to value changes

remoteService.characteristics.forEach { remoteCharacteristic ->
    try {
        Timber.w("Subscribing to ${remoteCharacteristic.uuid}...")
        remoteCharacteristic.subscribe()
            .onEach { newValue ->
                Timber.i("Value of ${remoteCharacteristic.uuid} changed: 0x${newValue.toHexString()}")
            }
            .onEmpty {
                Timber.w("No updates from ${remoteCharacteristic.uuid}")
            }
            .onCompletion {
                Timber.d("Stopped observing updates from ${remoteCharacteristic.uuid}")
            }
            .launchIn(scope)
    } catch (e: Exception) {
        // An exception is thrown when a characteristic does not have NOTFY or INDICATE property,
        // has no Client Characterisitc Configuration descriptor, or an error occurs.
        Timber.e("Failed to subscribe to ${remoteCharacteristic.uuid}: ${e.message}")
    }
}

For more, see sample.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 11

0