An Android library that solves a lot of Android's Bluetooth Low Energy problems

Overview

Android BLE Library

Download

An Android library that solves a lot of Android's Bluetooth Low Energy problems. The BleManager class exposes high level API for connecting and communicating with Bluetooth LE peripherals. The API is clean and easy to read.

Features

BleManager class provides the following features:

  1. Connection, with automatic retries
  2. Service discovery
  3. Bonding (optional) and removing bond information (using reflections)
  4. Automatic handling of Service Changed indications
  5. Device initialization
  6. Asynchronous and synchronous BLE operations using queue
  7. Splitting and merging long packets when writing and reading characteristics and descriptors
  8. Requesting MTU and connection priority (on Android Lollipop or newer)
  9. Reading and setting preferred PHY (on Android Oreo or newer)
  10. Reading RSSI
  11. Refreshing device cache (using reflections)
  12. Reliable Write support
  13. Operation timeouts (for connect, disconnect and wait for notification requests)
  14. Error handling
  15. Logging
  16. GATT server (since version 2.2)

The library does not provide support for scanning for Bluetooth LE devices. For scanning, we recommend using Android Scanner Compat Library which brings almost all recent features, introduced in Lollipop and later, to the older platforms.

Version 2.3

New features added in version 2.3:

  1. :ble-ktx module added with support for coroutines and Flow.
    1. .suspend() methods added in Requests.
    2. asFlow() method added to ValueChangedCallback.
    3. Connection and bonding state available as Flow.
    4. New helper methods to get a BluetoothGattCharacteristic with given required properties and instance id added to BluetoothGattService.
  2. JsonMerger class added, which should help with use cases when a device sends a JSON file in multiple packets.
  3. :ble-livedata migrated to Java with some API changes, as sealed classes are no longer available.
  4. Support for new onServicesChanged() callback, added in API 31 (Android 12).
  5. Option to cancel pending Bluetooth LE connection using ConnectRequest.cancelPendingConnection().

When using coroutines use .suspend() method in Request, instead of enqueue() or await().

To register to notifications and indications (or incoming write requests for server) use

setNotificationCallback(characteristic)
   .merge(JsonMerger()) // Example of how to use JsonMerger, optional
   .asFlow()

This is still experimental feature and any feedback is welcome.

Version 2.2

New features added in version 2.2:

  1. GATT Server support. This includes setting up the local GATT server on the Android device, new requests for server operations:
    • wait for read,
    • wait for write,
    • send notification,
    • send indication,
    • set characteristic value,
    • set descriptor value.
  2. New conditional requests:
    • wait if,
    • wait until.
  3. BLE operations are no longer called from the main thread.
  4. There's a new option to set a handler for invoking callbacks. A handler can also be set per-callback.

Migration to version 2.2

Version 2.2 breaks some API known from version 2.1.1. Check out migration guide.

Importing

Maven Central

The library may be found on Maven Central repository. Add it to your project by adding the following dependency:

implementation 'no.nordicsemi.android:ble:2.3.1'

The last version not migrated to AndroidX is 2.0.5.

BLE library with Kotlin extension is available in:

implementation 'no.nordicsemi.android:ble-ktx:2.3.1'

To import the BLE library with set of parsers for common Bluetooth SIG characteristics, use:

implementation 'no.nordicsemi.android:ble-common:2.3.1'

For more information, read this.

An extension for easier integration with LiveData is available after adding:

implementation 'no.nordicsemi.android:ble-livedata:2.3.1'

This extension adds ObservableBleManager with state and bondingState properties, which notify about connection and bond state using androidx.lifecycle.LiveData.

As a library module

Clone this project and add ble module as a dependency to your project:

  1. In settings.gradle file add the following lines:
include ':ble'
project(':ble').projectDir = file('../Android-BLE-Library/ble')
  1. In app/build.gradle file add implementation project(':ble') inside dependencies.
  2. Sync project and build it.

You may do the same with other modules available in this project. Keep in mind, that ble-livedata module requires Kotlin, but no special changes are required in the app.

Setting up

The library uses Java 1.8 features. If you're using Android Studio below 4.2, make sure your build.gradle includes the following configuration:

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    // For Kotlin projects additionally:
    kotlinOptions {
        jvmTarget = "1.8"
    }

Usage

A BleManager instance is responsible for connecting and communicating with a single peripheral. Multiple manager instances are allowed. Extend BleManager with you manager where you define the high level device's API.

BleManager may be used in different ways:

  1. In a Service, for a single connection - see nRF Toolbox -> RSC profile,
  2. In a Service with multiple connections - see nRF Toolbox -> Proximity profile,
  3. From ViewModel's repo - see Architecture Components and nRF Blinky,
  4. As a singleton - not recommended, see nRF Toolbox -> HRM.

Please refer to the examples/ble-gatt-client folder for a project that illustrates the GATT server provided as a foreground service. There's a simple UI with a text field to update with the value of a characteristic that can be read and subscribed to. This characteristic also demands encryption as an illustration of best-practice.

You can run this client on one device and a complimenting server on another (see the next section).

Adding GATT Server support

Starting from version 2.2 you may now define and use the GATT server in the BLE Library.

Please refer to the examples/ble-gatt-server folder for a project that illustrates the GATT server provided as a foreground service. There's a simple UI with a text field to update the value of a characteristic that can be read and subscribed to. This characteristic also demands encryption as an illustration of best-practice.

More examples

Find the simple example here Android nRF Blinky.

For an example how to use it from an Activity or a Service, check the base Activity and Service classes in nRF Toolbox.

Version 1.x

The BLE library v 1.x is no longer supported. Please migrate to 2.x for bug fixing releases. Find it on version/1x branch.

A migration guide is available here.

Comments
  • Timeout on first connection and error 133

    Timeout on first connection and error 133

    I can no longer reliably connect to a new peripheral. The connection times out after 30s and then I get error 133. Here's the logging on the Android side.

    2018-11-30 16:04:14.048 11300-11300/? I/ProvisioningActivity: Device C7:56:60:F0:56:58 clicked.
    2018-11-30 16:04:14.196 11300-11300/? D/ProvisioningActivity: Device 228892 exists and is unowned. Good.
    2018-11-30 16:04:14.205 11300-11300/? I/ProvisioningActivity: Connecting to C7:56:60:F0:56:58
    2018-11-30 16:04:14.214 11300-11300/? D/BikeTrackerManager: onDeviceConnecting()
    2018-11-30 16:04:14.215 11300-11300/? D/BluetoothGatt: connect() - device: C7:56:60:F0:56:58, auto: false
    2018-11-30 16:04:14.215 11300-11300/? D/BluetoothGatt: registerApp()
    2018-11-30 16:04:14.215 11300-11300/? D/BluetoothGatt: registerApp() - UUID=f0f74613-fc8c-4347-bdd0-9baa346f1b46
    2018-11-30 16:04:14.219 11300-11357/? D/BluetoothGatt: onClientRegistered() - status=0 clientIf=9
    2018-11-30 16:04:17.485 11300-11300/? I/chatty: uid=10209(cc.biketracker.android) identical 2 lines
    2018-11-30 16:04:44.231 11300-11357/? D/BluetoothGatt: onClientConnectionState() - status=133 clientIf=9 device=C7:56:60:F0:56:58
    2018-11-30 16:04:44.237 11300-11300/? D/BluetoothGatt: close()
    2018-11-30 16:04:44.237 11300-11300/? D/BluetoothGatt: unregisterApp() - mClientIf=9
    2018-11-30 16:04:44.239 11300-11300/? D/BikeTrackerManager: onDeviceDisconnected()
    2018-11-30 16:04:44.239 11300-11300/? D/ProvisioningActivity: Disconnected. Presenting alert dialog.
    2018-11-30 16:04:44.332 11300-11307/? I/tracker.androi: Compiler allocated 4MB to compile void android.widget.TextView.<init>(android.content.Context, android.util.AttributeSet, int, int)
    2018-11-30 16:04:44.341 11300-11300/? D/BikeTrackerManager: onDeviceDisconnected()
    2018-11-30 16:04:44.359 11300-11300/? W/AudioTrack: Use of stream types is deprecated for operations other than volume control
    2018-11-30 16:04:44.359 11300-11300/? W/AudioTrack: See the documentation of AudioTrack() for what to use instead with android.media.AudioAttributes to qualify your playback use case
    2018-11-30 16:04:44.433 11300-11300/? W/AudioTrack: Use of stream types is deprecated for operations other than volume control
    2018-11-30 16:04:44.433 11300-11300/? W/AudioTrack: See the documentation of AudioTrack() for what to use instead with android.media.AudioAttributes to qualify your playback use case
    2018-11-30 16:04:44.622 11300-11300/? D/LocalBroadcastUtil: Local broadcast message: model changed.
    2018-11-30 16:04:44.627 11300-11300/? D/BleBackgroundScanner: Bonded peripherals:
    2018-11-30 16:04:44.629 11300-11300/? D/BleBackgroundScanner: No Bike Tracker devices bonded to this phone. Not scanning.
    2018-11-30 16:04:44.630 11300-11300/? D/BikeTrackerManager: onError()
    2018-11-30 16:04:44.630 11300-11300/? E/ProvisioningActivity: BLE error: 133: Error on connection state change
    

    I'm connecting like this:

    bleDeviceManager.connect(selectedBluetoothDevice.getDevice())
                        .retry(3, 200)
                        .useAutoConnect(false)
                        .enqueue();
    

    On the device (peripheral) side, I don't get any logging for the connection at all. It's like nothing's happened on the radio. I don't have a sniffer dongle to hand to check for sure.

    I first saw this on v2.0.0 and have just verified it on v2.0.2. I've been able to connect once, without having changed any code on either side, but then after clearing the bond on both sides and testing again, I can't connect. Turning off the Bluetooth adapter on the phone, rebooting the phone, reflashing the device - nothing seems to put it right. I can repro this with the DK as the peripheral, so it's not a hardware thing with my device.

    I can also connect, and bond, from the nRF Connect app.

    Happy to share both the device firmware and the Android app source code privately. Anything else I can check, until I get back to my sniffer and Wireshark?

    question 
    opened by eliotstock 60
  • Disable notifications ACK not received, trying to enable notifications throws Status -3

    Disable notifications ACK not received, trying to enable notifications throws Status -3

    One of the operations I perform often is an atomic enable/disable notifications and write characteristic

            Timber.d("$rawDataOn pre")
    beginAtomicRequestQueue()
                .add(klEnableNotificationsRequest(sensorsRawDataCharacteristic, rawDataOn)) //enables/disables notifications
                .add(writeCharacteristic(sensorsStreamingControlCharacteristic, payload))
                .before {
                    Timber.d("$rawDataOn before")
                }
                .done {
                    Timber.d("$rawDataOn Completed")
                }
                .enqueue()
    

    A standard execution when passing "false" logs something like this

    12:13:20.565 false pre
    12:13:20.565 false before
    12:13:20.566 gatt.setCharacteristicNotification(01000001-55d0-4989-b640-cfb64e5c34e0, false)
    12:13:20.566 setCharacteristicNotification() - uuid: 01000001-55d0-4989-b640-cfb64e5c34e0 enable: false
    12:13:20.567 Disabling notifications and indications for 01000001-55d0-4989-b640-cfb64e5c34e0
    12:13:20.568 gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x00-00)
    12:13:20.575 Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 00-00
    12:13:20.575 Notifications and indications disabled
    12:13:20.576 Writing characteristic 04000001-55d0-4989-b640-cfb64e5c34e0 (WRITE REQUEST)
    12:13:20.576 gatt.writeCharacteristic(04000001-55d0-4989-b640-cfb64e5c34e0)
    12:13:20.577 false Completed
    

    Some times, if there are consecutive calls with enable set to false and then true, it tries to enable notifications before the disable is complete. Apparently, the "disable notifications" request never confirms that the notifications are disabled but still completes

    12:13:19.467 false pre
    12:13:19.495 true pre
    12:13:20.485 false before
    12:13:20.486 gatt.setCharacteristicNotification(01000001-55d0-4989-b640-cfb64e5c34e0, false)
    12:13:20.486 setCharacteristicNotification() - uuid: 01000001-55d0-4989-b640-cfb64e5c34e0 enable: false
    12:13:20.489 Disabling notifications and indications for 01000001-55d0-4989-b640-cfb64e5c34e0
    12:13:20.490 gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x00-00)
    12:13:20.504 Writing characteristic 04000001-55d0-4989-b640-cfb64e5c34e0 (WRITE REQUEST)
    12:13:20.505 gatt.writeCharacteristic(04000001-55d0-4989-b640-cfb64e5c34e0)
    12:13:20.507 false Completed
    12:13:20.508 true before
    12:13:20.510 klEnableNotificationsRequest setNotificationCallback
    12:13:20.511 gatt.setCharacteristicNotification(01000001-55d0-4989-b640-cfb64e5c34e0, true)
    12:13:20.511 setCharacteristicNotification() - uuid: 01000001-55d0-4989-b640-cfb64e5c34e0 enable: true
    12:13:20.514 Enabling notifications for 01000001-55d0-4989-b640-cfb64e5c34e0
    12:13:20.514 gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x01-00)
    -> error -3 12:13:20.516 Failed to enabled notifications for 01000001-55d0-4989-b640-cfb64e5c34e0 (status = -3)
    12:13:20.517 Writing characteristic 04000001-55d0-4989-b640-cfb64e5c34e0 (WRITE REQUEST)
    12:13:20.518 gatt.writeCharacteristic(04000001-55d0-4989-b640-cfb64e5c34e0)
    12:13:20.519 true Completed
    

    If you compare it with the previous log, it's missing the "disable notifications" ACK

    12:13:20.575 Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 00-00
    12:13:20.575 Notifications and indications disabled
    

    Does it sound like a bug in the library?

    We develop our own firmware so there might as well be a bug there, but I don't have a sniffer to check the packets.

    bug 
    opened by ghost 40
  • setPreferredPhy in initialize() fails on Android 13

    setPreferredPhy in initialize() fails on Android 13

    Setting a preferred PHY in the initialize() method, fails on Android 13 (on a Pixel 4a) but works on older Android versions.

    onDeviceReady() is never called on Android 13.

    Setting the preferredPHY in the connect request doesn't seem to work at all, even on older devices.

     clientManager.connect(device)
        .useAutoConnect(false)
        .usePreferredPhy(PhyRequest.PHY_LE_2M_MASK)
        .enqueue()
    

    On older devices, I read the PHY in onDeviceReady() and it displays 2M only when setting it in initialize() not via the connectrequest.

    I adapted the GattService.kt example to work with my BLE device (uses Nordic UART service). The Android 13 version receives the notifications but onDeviceReady() is not called.

    I am testing with 2.5.1 on the latest commit 52d60a4de110b73faef05938ea31a699a9a38163

    
    override fun onDeviceReady() {
        Log.i(TAG, "--------------------------------------")
        Log.i(TAG, "device is ready")
        Log.i(TAG, "--------------------------------------")
        readPhy().enqueue()
        super.onDeviceReady()
    }
    
    override fun initialize() {
    
        setNotificationCallback(mTXCharacteristic)
            .with { _, data ->
                if (data.value != null) {
                    val value = String(data.value!!, Charsets.UTF_8)
                    defaultScope.launch {
                        myCharacteristicChangedChannel?.send(value)
                    }
                }
            }
    
        enableNotifications(mTXCharacteristic).enqueue()
    
        if (true && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val bluetoothManager =
                context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
            if (bluetoothManager.adapter?.isLe2MPhySupported == true) {
                setPreferredPhy(
                    PhyRequest.PHY_LE_2M_MASK,
                    PhyRequest.PHY_LE_2M_MASK,
                    PhyRequest.PHY_OPTION_NO_PREFERRED
                ).enqueue()
            } else {
                Log.w(TAG, "PHY LE 2M not supported. Run with default 1M")
            }
        }
    }
    
    opened by bobatsar 30
  • beginAtomicRequestQueue not working as expected with a split() request.

    beginAtomicRequestQueue not working as expected with a split() request.

    When adding a split-write request followed by a waitForNotification request, the wait request is started when the first packet is sent, even on multi-packet writes. This causes the write request to never send the remaining packets until the wait request times out.

    opened by andybdahl 24
  • BLE peripheral failing to connect to the central phone running Android OS 9 (Pie)

    BLE peripheral failing to connect to the central phone running Android OS 9 (Pie)

    The app issues a connect(bluetoothDevice) command as shown below to the Nordic BLE library v2.2.3 after a user manually clicks "Connect" from the UI in the app.

    connect(bluetoothDevice).useAutoConnect(true)
                        .usePreferredPhy(PhyRequest.PHY_LE_2M_MASK)
                        .before { log.debug("connect request starting execution id $id") }
                        .fail { _, status -> log.debug("connect request id $id failed ${status.toRequestFailureMessage()}") }
                        .enqueue()
    

    I also make a check before using LE 2M PHY if the device is compatible. If the device is incompatible, I call like shown below:

    connect(bluetoothDevice).useAutoConnect(true)
                        .before { log.debug("connect request starting execution id $id") }
                        .fail { _, status -> log.debug("connect request id $id failed ${status.toRequestFailureMessage()}") }
                        .enqueue()
    

    I get a ConnectionObserver callback onDeviceFailedToConnect in my custom class which implements the interface with a reason -1

    /** The reason of disconnection is unknown. */
    int REASON_UNKNOWN = -1;
    

    This is however only affecting Android OS 9 and most probably 9.1 users. We have noticed that if you upgrade the OS to the latest stable OS 10, the issue seems to go away. We also have noticed that for devices running OS 9, if you pair first through Bluetooth OS settings and then try again through within the app, you can successfully pair to the BLE peripheral.

    For your information, we upgraded Nordic library from v2.1.1 to 2.2.0 and the issue was still existing. We thought upgrading to v2.2.3 might resolve but in vain. Is there something that we are doing wrong?

    opened by SarthakJ10 22
  • Introduces a GATT server example

    Introduces a GATT server example

    The documentation on how to write a server appears to be incomplete and out of date. I thought it'd be useful to have a fully-fledged service implementation to illustrate how the server types can be used. 'hope this PR is helpful as a starting point.

    My motivation here is to also better understand how BLE supposed to operate. I'm also deliberately using encryption for the gatt characteristic as this appears to be a required scenario for reliable re-connects.

    Marked as draft to get feedback on how things should look.

    opened by huntc 21
  • Bonding at initialize() or reading Char that requires bond

    Bonding at initialize() or reading Char that requires bond

    Hello again!

    Thanks for you last fix, it solved my issue. :) I've ran into another strange case. Let's say you want to connect to a device and bond that device. What is the flow for this? I've tried several different ways but ran into different issues.

    • enqueue a bond in the initialization?
    /** BleManagerGattCallback **/
            override fun initialize() {
                super.initialize()
                createBond().enqueue()
                readCharacteristic(bondCharacteristics).with(bondDataCallback).enqueue()            
                readCharacteristic(modeCharacteristics).with(modeCallback).enqueue()
                setNotificationCallback(modeCharacteristics).with(modeCallback)
    
            }
            ...
    

    In the case above everything below createBond() will be ignored.

    • read a characteristic that require bonding, and handle onBondingRequired?
            override fun initialize() {
                super.initialize()
                readCharacteristic(bondCharacteristics).with(bondDataCallback).enqueue()           
            }
            ...
    

    In this case I get:

    E/BleManager: onCharacteristicRead error 8
    

    It does not seem to match the BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION, see https://github.com/NordicSemiconductor/Android-BLE-Library/blob/master/ble/src/main/java/no/nordicsemi/android/ble/BleManager.java#L1316 However, it will log in the nRF Logger: Error (0x8): GATT INSUF AUTHORIZATION.

    Or is the right way to go to create a bond after connect done callback and then do additional reading for characteristics that require bond?

    bug 
    opened by Rawa 18
  • autoConnect stopped working since graduating from pre v1.0 to 1.2

    autoConnect stopped working since graduating from pre v1.0 to 1.2

    Hi,

    My app connects to a sensor which occasionally (after 30 seconds of no use) switches off. When switched off, the phone should continue to try to reconnect to it, so that the moment the sensor turns back on it seamlessly reconnects.

    I have had this app released (with >200 users) for some time using the version before it was released on Maven. This behaviour has been working perfectly with the old version of this library.

    Since upgrading to V1.2 over the weekend, my app no longer reconnects (I have confirmed that the sensor is actually turned on). It looks like the initial connection using autoConnect = false works perfectly, but after the sensor has then turned off, and back on again (so now connecting with autoConnect = true), no connection is made. I have made no changes since upgrading to V1.2 (except importing the new Request class) - am I doing anything wrong?

    I have NRFLogger running with some debug messages on the BLEManager callbacks. A typical debug output looks something like this:

    onDeviceConnecting
    gatt=device.connectGatt(autoConnect = false)
    onDeviceConnected
    onServicesDiscovered
    Notifications Enabled
    onDeviceReady
    Notification Received 
    ... (lots of notification received - 1 every second. This is normal usage)
    Notification Received 
    Connection state changed with status : 8 and new state: 0 (DISCONNECTED)
    Error: (0x8): GATT CONN TIMEOUT (this is expected - the sensor has gone to sleep now)
    Connection Lost
    onLinkLossOccur
    onDeviceConnecting
    gatt.connect()
    (at this point the sensor is turned on, advertising and available for connection - but app doesn't connect)
    

    Currently this version of my app has not been released, and has only been tested on my Pixel 2 development phone - but seems consistent behaviour.

    opened by cirlam 18
  • v2.2.1 breaks connection on some devices, BLE not working at all.

    v2.2.1 breaks connection on some devices, BLE not working at all.

    Released as 2.2.1.

    Originally posted by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/issues/200#issuecomment-651738341

    The original issue merged in PR#209 breaks connection attempts on some devices, where devices will no longer be able to enqueue any requests to characteristics after connecting. Verified to work when downgrading to v2.2.0.

    opened by andybdahl 17
  • Data lost during sync using notifications

    Data lost during sync using notifications

    Hi, I am using this library to connect to a sensor that's using characteristic notification to send data. I enable the notifications and I am able to receive data but the data is getting lost somewhere between being received by Android device and being received in Gattcallbacks. The sensor also uses a nordic processing unit and updates notification characteristic every 20ms. No matter the size of data, BlinkyManager reports data size to be approx 8000 notification updates.

    However, the data size can be up to 10 Mb and I can only receive less than 1 Mb.

    opened by svvashishtha 16
  • Bluetooth disconnects when calling writeCharacteristic on Android 13

    Bluetooth disconnects when calling writeCharacteristic on Android 13

    When I call BleManager.writeCharacteristic where the data has 543 bytes in the array, the call succeeds on Android 12. However, on Android 13 the bluetooth disconnects with the following logs:

    2022-09-15 12:59:30.850 V/Android-BLE-Library: Writing characteristic <custom characteristic UUID> (WRITE REQUEST)
    2022-09-15 12:59:30.850 D/Android-BLE-Library: gatt.writeCharacteristic(<custom characteristic UUID>)
    2022-09-15 12:59:31.685 D/BluetoothAdapter: onBluetoothServiceDown
    2022-09-15 12:59:31.692 D/BluetoothAdapter: onBluetoothServiceDown
    2022-09-15 12:59:31.695 D/Android-BLE-Library: [Broadcast] Action received: android.bluetooth.adapter.action.STATE_CHANGED, state changed to TURNING OFF
    2022-09-15 12:59:31.696 I/Android-BLE-Library: Disconnected
    2022-09-15 12:59:31.712 D/Android-BLE-Library: gatt.close()
    2022-09-15 12:59:31.712 D/BluetoothGatt: close()
    2022-09-15 12:59:31.712 D/BluetoothGatt: unregisterApp() - mClientIf=6
    2022-09-15 12:59:31.714 E/BluetoothGatt: android.os.DeadObjectException
            at android.os.BinderProxy.transactNative(Native Method)
            at android.os.BinderProxy.transact(BinderProxy.java:584)
            at android.bluetooth.IBluetoothGatt$Stub$Proxy.unregisterClient(IBluetoothGatt.java:1506)
            at android.bluetooth.BluetoothGatt.unregisterApp(BluetoothGatt.java:941)
            at android.bluetooth.BluetoothGatt.close(BluetoothGatt.java:799)
            at no.nordicsemi.android.ble.BleManagerHandler.close(BleManagerHandler.java:472)
            at no.nordicsemi.android.ble.BleManagerHandler.notifyDeviceDisconnected(BleManagerHandler.java:1633)
            at no.nordicsemi.android.ble.BleManagerHandler.access$900(BleManagerHandler.java:59)
            at no.nordicsemi.android.ble.BleManagerHandler$1.onReceive(BleManagerHandler.java:279)
            at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$android-app-LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1790)
            at android.app.LoadedApk$ReceiverDispatcher$Args$$ExternalSyntheticLambda0.run(Unknown Source:2)
            at android.os.Handler.handleCallback(Handler.java:942)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loopOnce(Looper.java:201)
            at android.os.Looper.loop(Looper.java:288)
            at android.app.ActivityThread.main(ActivityThread.java:7898)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
    2022-09-15 12:59:31.714 D/BleManagerGattCallback: onServicesInvalidated
    2022-09-15 12:59:31.714 D/BleManagerGattCallback: onDeviceDisconnected
    2022-09-15 12:59:31.995 D/BluetoothAdapter: onBluetoothServiceUp: android.bluetooth.IBluetooth$Stub$Proxy@868fc9d
    

    There are a few earlier calls to writeCharacteristic with 1-2 bytes that succeed, it's only the call with the larger amount of data that fails due to the bluetooth disconnecting.

    For reference, I'm targeting API 32 and using the following library versions:

    implementation 'no.nordicsemi.android.support.v18:scanner:1.6.0'
    implementation "no.nordicsemi.android:ble:2.5.1"
    implementation "no.nordicsemi.android:ble-livedata:2.5.1"
    

    Has anyone else run into this issue on Android 13?

    opened by sara-race-neato 15
  • The request is lost if the manager is not ready

    The request is lost if the manager is not ready

    Hi Ble-Library developers, the library is great I am grateful, thanks a lot.

    I have an issue: when I try to add a request to queue, the request lost if manager is not in isReady = true state so the command is lost. I found a solution for that but I am not proud of it. Because it might be cause a performance issue or memory leak.

    I couldn't figure out what I did wrong. How can I solve this situation? Can you help me?

    ViewModel operations

    /*find and connect to device*/
    val device = bluetoothAdapter.getRemoteDevice(device.deviceAddress)
    bleManager.connect(device)
        .retry(3, 100)
        .enqueue()
    
    /* ...
    some operations
    ...*/
    
    /*this is the solution for guarantee the request delivery*/
    if (bleManager.isConnected) {
            if (bleManager.isReady) {
                bleManager
                    .rename("device-name") /*custom rename write request*/
                    .enqueue()
            } else {
                viewModelScope.launch(Dispatchers.IO) {
                    while (true) {
                        if (bleManager.isReady) {
                            bleManager
                                .rename("device-name") /*custom rename write request*/
                                .enqueue()
                            cancel()
                        }
                        delay(100L)
                    }
                }
            }
    }
    
    

    MyBleManager.kt

    class MyBleManager(
        context: Context,
        private val scope: CoroutineScope
    ) : BleManager(context) {
    
    /* ... gatt operations ...*/
    
    fun rename(name: String): WriteRequest {
            val text = "$name"
            val writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
            val request: WriteRequest =
                writeCharacteristic(characteristicRename, text.toByteArray() + 0, writeType)
            /* I tried suspend version but result is same*/
            return request.with(dataCallback)
    }
    
    /* ... other functions etc. ...*/
    
    }
    

    Thanks and best regards :)

    opened by onatakduman 2
  • Unexpected sensor disconnection raised at Android 13, with 2.6.0-alpha4

    Unexpected sensor disconnection raised at Android 13, with 2.6.0-alpha4

    Hello

    We were testing the connectivity with our Bluetooth peripheral on Android 13, and we encountered an issue where the connection is failing, but it is connected in the android system.

    The log was showing that the read rssi command running successfully, while the connection updated callback was providing a false value.

    The frequency of the issue is not clear enough, so haven't got a chance to identify the steps to reproduce it. Though, thought it would be helpful if there's a log to approach the issue. I'm assuming the error level log from the BleManager is considered critical for the library ass well.

    From my research, the status that is raised from Android OS, which is 22 represents the android device (host device) terminated the connection BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION

    2022-12-29 13:22:04.969 29029-29064 BluetoothGatt           com.sibelhealth.app                  D  onPhyRead() - status=0 address=**:**:**:**:**:** txPhy=1 rxPhy=1
    2022-12-29 13:22:05.206 29029-29461 BluetoothGatt           com.sibelhealth.app                  D  onPhyUpdate() - status=0 address=**:**:**:**:**:** txPhy=2 rxPhy=2
    2022-12-29 13:22:05.988 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:06.106 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:06.530 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:06.889 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:07.012 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  readRssi() - device: **:**:**:**:**:**
    2022-12-29 13:22:07.033 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  readRssi() - device: **:**:**:**:**:**
    2022-12-29 13:22:12.017 29029-29056 BluetoothGatt           com.sibelhealth.app                  D  readRssi() - device: **:**:**:**:**:**
    2022-12-29 13:22:12.196 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:13.490 29029-29461 BluetoothGatt           com.sibelhealth.app                  D  onConnectionUpdated() - Device=**:**:**:**:**:** interval=12 latency=3 timeout=400 status=0
    2022-12-29 13:22:13.691 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: false
    2022-12-29 13:22:17.024 29029-29056 BluetoothGatt           com.sibelhealth.app                  D  readRssi() - device: **:**:**:**:**:**
    2022-12-29 13:22:19.141 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:22.037 29029-29056 BluetoothGatt           com.sibelhealth.app                  D  readRssi() - device: **:**:**:**:**:**
    2022-12-29 13:22:22.859 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:22.964 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:23.356 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: false
    2022-12-29 13:22:23.694 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: false
    2022-12-29 13:22:23.792 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: false
    2022-12-29 13:22:23.948 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:26.622 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: false
    2022-12-29 13:22:27.047 29029-29056 BluetoothGatt           com.sibelhealth.app                  D  readRssi() - device: **:**:**:**:**:**
    2022-12-29 13:22:27.122 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:28.923 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: false
    2022-12-29 13:22:29.343 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  setCharacteristicNotification() - uuid: ********-****-****-**** enable: true
    2022-12-29 13:22:30.549 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  cancelOpen() - device: **:**:**:**:**:**
    2022-12-29 13:22:30.555 29029-29461 BluetoothGatt           com.sibelhealth.app                  D  onClientConnectionState() - status=0 clientIf=7 device=**:**:**:**:**:**
    2022-12-29 13:22:30.562 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  close()
    2022-12-29 13:22:30.564 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  unregisterApp() - mClientIf=7
    2022-12-29 13:22:31.918 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  connect() - device: **:**:**:**:**:**, auto: false
    2022-12-29 13:22:31.918 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  registerApp()
    2022-12-29 13:22:31.918 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  registerApp() - UUID=7ca68460-ae58-4e61-8302-6b78a57b494b
    2022-12-29 13:22:31.922 29029-29461 BluetoothGatt           com.sibelhealth.app                  D  onClientRegistered() - status=0 clientIf=7
    2022-12-29 13:22:31.933 29029-29461 BluetoothGatt           com.sibelhealth.app                  D  onClientConnectionState() - status=0 clientIf=7 device=**:**:**:**:**:**
    2022-12-29 13:22:32.330 29029-29482 BluetoothGatt           com.sibelhealth.app                  D  onConnectionUpdated() - Device=**:**:**:**:**:** interval=12 latency=3 timeout=400 status=22
    **2022-12-29 13:22:32.330 29029-29029 BleManager              com.sibelhealth.app                  E  onConnectionUpdated received status: 22, interval: 12, latency: 3, timeout: 400**
    2022-12-29 13:22:32.333 29029-29482 BluetoothGatt           com.sibelhealth.app                  D  onClientConnectionState() - status=0 clientIf=7 device=**:**:**:**:**:**
    2022-12-29 13:22:33.535 29029-29029 BluetoothGatt           com.sibelhealth.app                  D  discoverServices() - device: **:**:**:**:**:**
    

    Details: Device: Galaxy Tab S8 / SM-X700 OS: Android 13 Library Version: v2.6.0-alpha.4

    opened by junebeans 0
  • Add attachClientConnection method as a server only alternative to connect

    Add attachClientConnection method as a server only alternative to connect

    This is based in part on work from this PR https://github.com/NordicSemiconductor/Android-BLE-Library/pull/231 which references this issue https://github.com/NordicSemiconductor/Android-BLE-Library/issues/229 I have endeavored to cover this use case with the minimum possible code disruption. The current behavior should be exactly the same for code using the connection back to the client. I have only added one method "attachClientConnection" which can be used as a server-only alternative to using "connect" in "onDeviceConnectedToServer". Example use shown below based on a Java version of the server example in this repo (ServerConnection extends BleManager).

    @Override
    public void onDeviceConnectedToServer(BluetoothDevice device) {
        String address = device.getAddress();
        Log.d(TAG, "Device connected " + address);
        ServerConnection newConnection = new ServerConnection(context);
        serverConnections.put(address, newConnection);
        newConnection.useServer(this);
        // either setup as server only or dual connection
        newConnection.attachClientConnection(device); // sets up connection server only
        //newConnection.connect(device).enqueue(); // queues connection back to client for dual connection
    }
    
    opened by CyDragon80 2
  • Failing to connect after upgrading to Android 13

    Failing to connect after upgrading to Android 13

    Hi! On a One plus 8T device running Android 13, it simply won't connect to the BLE peripheral Here are the logs from BleManager and the app is always timing out after initiating a service discovery.

    12-12-2022 12:16:12.038-0500 D | BleManager: gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, LE 2M)
    12-12-2022 12:16:12.110-0500 I | BleManager: Connected to D4:D5:BE:82:CE:31
    12-12-2022 12:16:12.110-0500 D | BleManager: [Callback] Connection state changed with status: 0 and new state: 2 (CONNECTED)
    12-12-2022 12:16:12.113-0500 D | BleManager: wait(300)
    12-12-2022 12:16:12.115-0500 I | BleManager: MTU changed to: 247
    12-12-2022 12:16:12.415-0500 V | BleManager: Discovering services...
    12-12-2022 12:16:12.416-0500 D | BleManager: gatt.discoverServices()
    12-12-2022 12:16:12.776-0500 I | BleManager: Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)
    12-12-2022 12:23:07.385-0500 D | BleManager: [Callback] Connection state changed with status: 8 and new state: 0 (DISCONNECTED)
    12-12-2022 12:23:07.388-0500 W | BleManager: Error: (0x8): GATT CONN TIMEOUT
    

    Here is the connect code:

    fun connectDevice(bluetoothDevice: BluetoothDevice) {
        val request = connect(bluetoothDevice)
            .useAutoConnect(false)         
            .usePreferredPhy(no.nordicsemi.android.ble.PhyRequest.PHY_LE_2M_MASK)
            .retry(3, 100)
            .enqueue()
    }
    

    The device was able to connect successfully while it was running Android 12 but as soon as you update it to Android 13, it fails to connect.

    Details: Device: One plus 8T OS: Android 13 (KB2005_11_F.13) Library version: v2.5.1

    opened by SarthakJ10 14
  • Most of the time the connection does not work

    Most of the time the connection does not work

    I've been trying to find a solution for this error for two days now and I can't understand what happens to the connection not working. I have to try many, many times until the connection works.

    Device: Samsung A13 Android version: 12

    Log from logcat:

    04 12:27:54.427 18420 18551 D BluetoothGatt: connect() - device: FE:EB:A9:02:1B:78, auto: false
    12-04 12:27:54.427 18420 18551 I BluetoothAdapter: isSecureModeEnabled
    12-04 12:27:54.428  1573  3519 D BtConfig.SecureMode: isSecureModeOn:false
    12-04 12:27:54.428 18420 18551 D BluetoothGatt: registerApp()
    12-04 12:27:54.429 18420 18551 D BluetoothGatt: registerApp() - UUID=31e09b9f-c264-41ea-bdd8-b17c8a835759
    12-04 12:27:54.431  1573  3519 D BtGatt.GattService: registerClient(com.cleanproject) - UUID=31e09b9f-c264-41ea-bdd8-b17c8a835759
    12-04 12:27:54.433  1573  3519 D BtGatt.ContextMap: add() - appUid: 10303, appPid: 18420, appName: com.cleanproject
    12-04 12:27:54.435  1573  1672 D BtGatt.GattService: onClientRegistered() - UUID=31e09b9f-c264-41ea-bdd8-b17c8a835759, clientIf=9
    12-04 12:27:54.436 18420 18808 D BluetoothGatt: onClientRegistered() - status=0 clientIf=9
    12-04 12:27:54.443  1573  3519 D BtGatt.GattService: clientConnect(com.cleanproject) - address = FEEBA9_8, isDirect=true transport =2 set own addr = false own addr type:0, clientIf: 9, opportunistic=false, phy: 7
    12-04 12:27:54.444  1573  2347 W bt_btm  : BTM_SecAddBleDevice: dev_type=0x2
    12-04 12:27:54.444  1573  2347 E bt_stack: [ERROR:gatt_api.cc(1237)] GATT_Connectgatt_if=9, address=fe:eb:a9:02:1b:78, is_direct=1, opportunistic=0
    12-04 12:27:54.445  1573  2347 I bt_stack: [INFO:gatt_attr.cc(888)] gatt_sr_init_cl_status: bda=fe:eb:a9:02:1b:78, cl_supp_feat=0000, aware=1
    12-04 12:27:54.445  1573  2347 W bt_btm  : btm_ble_disable_resolving_list() rl_state = 0x0, rl_mask = 0x1, to_resume = 1
    12-04 12:27:54.580  1129  1129 I GestureDetector: handleMessage TAP
    12-04 12:27:54.580  1129  1154 I GestureDetector: handleMessage TAP
    12-04 12:27:54.902   760   798 D BatteryDump: wait_for_battery_event : occurred : change@/devices/platform/samsung_mobile_device/samsung_mobile_device:battery/power_supply/battery 
    12-04 12:27:54.906   760   760 I [email protected]: updateLrpSysfs: write: 292
    12-04 12:27:54.954   820   820 I SurfaceFlinger: SFWD update time=54861089575760
    12-04 12:27:55.214  1129  1479 D NetdEventListenerService: DNS Requested by : 100, 10303, 0
    12-04 12:27:55.810   368   368 D io_stats: !@ 179,0 r 509958 15388139 w 192676 6511972 d 41720 6263184 f 0 0 iot 252256 0 th 0 0 0 pt 0 inp 0 0 54861.945
    12-04 12:27:57.104  1129  2164 D SamsungAlarmManager: Cancel Alarm calling from uid:10179 pid :15801 / OP:PendingIntent{866a8f5: PendingIntentRecord{2fd805e com.google.android.gms/ startService}}
    12-04 12:27:57.106  1129  2164 V SamsungAlarmManager: setLocked to kernel - W:54947402 / NW:54866135, now=54863241
    12-04 12:27:57.110  1129  2164 D SamsungAlarmManager: Cancel Alarm calling from uid:10179 pid :2269 / OP:PendingIntent{daec68a: PendingIntentRecord{48a490c com.google.android.gms/ startService}}
    12-04 12:27:57.111  1129  2164 V SamsungAlarmManager: setLocked to kernel - W:54947402 / NW:54866135, now=54863246
    12-04 12:27:57.242  1129  1479 D NetdEventListenerService: DNS Requested by : 100, 10303, 0
    12-04 12:27:57.281  1129  1183 D PowerManagerService: UserActivityStateListenerState: 0
    12-04 12:27:57.514  1506  1506 I wpa_supplicant: Heartbeat 5468
    12-04 12:27:59.260  1129  1479 D NetdEventListenerService: DNS Requested by : 100, 10303, 0
    12-04 12:27:59.446  1573  2347 I bt_stack: [INFO:gatt_attr.cc(342)] gatt_connect_cback: remove untrusted client status, bda=fe:eb:a9:02:1b:78
    12-04 12:27:59.447  1573  2347 W bt_stack: [WARNING:bta_gattc_act.cc(384)] bta_gattc_open_fail: Cannot establish Connection. conn_id=000000. Return GATT_ERROR(133)
    12-04 12:27:59.454  1573  2347 W bt_btm  : btm_ble_disable_resolving_list() rl_state = 0x0, rl_mask = 0x1, to_resume = 1
    12-04 12:27:59.455  1573  1672 D BtGatt.GattService: onConnected() - clientIf=9, connId=0, status=133, address=FEEBA9_8
    12-04 12:27:59.456 18420 18808 D BluetoothGatt: onClientConnectionState() - status=133 clientIf=9 device=FE:EB:A9:02:1B:78
    12-04 12:27:59.463 18420 18420 D ReactNativeBleManager: onConnectionStateChange to 0 on peripheral: FE:EB:A9:02:1B:78 with status 133
    12-04 12:27:59.464 18420 18420 D BluetoothGatt: close()
    12-04 12:27:59.473 18420 18420 D BluetoothGatt: unregisterApp() - mClientIf=9
    12-04 12:27:59.476  1573  3519 D BtGatt.GattService: unregisterClient(com.cleanproject) - clientIf=9
    12-04 12:27:59.478  1573  3519 D BtGatt.ContextMap: remove() - id: 9
    12-04 12:27:59.478  1573  3519 E BtGatt.ContextMap: remove() - removed: 9
    12-04 12:27:59.479  1573  2347 I bt_stack: [INFO:gatt_api.cc(1102)] GATT_Deregister gatt_if=9
    12-04 12:27:59.479  1573  2347 I bt_stack: [INFO:gatt_api.cc(1155)] Initialize tGATT_REG
    12-04 12:27:59.480 18420 18420 D BluetoothGatt: cancelOpen() - device: FE:EB:A9:02:1B:78
    12-04 12:27:59.480 18420 18420 D BluetoothGatt: close()
    12-04 12:27:59.482 18420 18550 I ReactNativeJS: 'Connection error', 'Connection error'
    12-04 12:27:59.485 18420 18420 D BluetoothGatt: unregisterApp() - mClientIf=0
    12-04 12:27:59.488 18420 18420 D ReactNativeBleManager: Peripheral event (BleManagerDisconnectPeripheral):FE:EB:A9:02:1B:78
    12-04 12:27:59.488 18420 18420 D ReactNativeBleManager: Disconnect
    12-04 12:27:59.489 18420 18550 I ReactNativeJS: Ok
    12-04 12:27:59.555 18420 18550 I ReactNativeJS: Disconnected from FE:EB:A9:02:1B:78
    12-04 12:28:00.000  1129  1250 D SamsungAlarmManager: Expired : 8
    
    question 
    opened by dan-developer 5
Releases(2.6.0-alpha04)
  • 2.6.0-alpha04(Nov 28, 2022)

    What's Changed

    • Don't log written data, as they may not be up-to-date by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/440
    • Don't verify write without response operations in Reliable Write by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/441

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.6.0-alpha03...2.6.0-alpha04

    Source code(tar.gz)
    Source code(zip)
  • 2.6.0-alpha03(Sep 30, 2022)

    Alpha

    This is an alpha 3 release. All new features seems to be working, but more testing is needed. Please test and give us a feedback.

    What's Changed

    • Bug fix: createBondInsecure() cannot be suspended by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/429

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.6.0-alpha02...2.6.0-alpha03

    Source code(tar.gz)
    Source code(zip)
  • 2.6.0-alpha02(Sep 30, 2022)

    Alpha

    This is an alpha 2 release. All new features seems to be working, but more testing is needed. Please test and give us a feedback.

    What's Changed

    New

    • Data provider for read requests by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/427

    Bugs fixed

    • Bug fix: Reset connection flags when Bluetooth goes off by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/428

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.6.0-alpha01...2.6.0-alpha02

    Source code(tar.gz)
    Source code(zip)
  • 2.6.0-alpha01(Sep 29, 2022)

    Alpha

    This is an alpha 1 release. All new features seems to be working, but more testing is needed. Please test and give us a feedback.

    What's Changed

    • Cancellation support by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/423
    • Migration to API 33 by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/424 and https://github.com/NordicSemiconductor/Android-BLE-Library/pull/425
    • Reading PHY if no callback for setting preferred one by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/426

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.5.1...2.6.0-alpha01

    Source code(tar.gz)
    Source code(zip)
  • 2.5.1(Jun 7, 2022)

    What's Changed

    • Dependencies updated by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/394
    • Keep onConnectionUpdated method from being removed by proguard by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/395
    • Null checks for service discovery by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/396
    • Readme fixed by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/397

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.5.0...2.5.1

    Source code(tar.gz)
    Source code(zip)
  • 2.5.0(Jun 3, 2022)

    New features

    • Connection parameters listener added by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/390

    What's Changed

    • Migration to Android API 32 by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/386
    • Gradle plugin fixed by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/387
    • Warnings suppressed by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/388
    • Clearing deprecated battery callback on disconnection by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/389

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.4.1...2.5.0

    Source code(tar.gz)
    Source code(zip)
  • 2.4.1(May 10, 2022)

    What's Changed

    • Allow sending empty packets by @sylwester-zielinski in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/384
    • Increase Gradle to 7.1.3 by @sylwester-zielinski in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/377

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.4.0...2.4.1

    Source code(tar.gz)
    Source code(zip)
  • 2.4.0(Mar 22, 2022)

    Finally, we released the stable version 2.4.0 of the Android BLE Library. It contains lots of improvements and bug fixes. The main changes are:

    • More Kotlin extensions in the ble-ktx module.

      Now, apart from suspend() method, which returns Data for ReadRequest and WriteReqeust (client side) and WaitForValueChangedRequest and WaitForReadRequest (server side), you may use suspendForResponse() and suspendForValidResponse() which return an object extending ReadResponse or WriteResponse. The notifications and indications can also be collected as response Flow using new asResponseFlow() and asValidResponseFlow(). With #371 merged it is also possible to get progress indications as flow for outgoing packets using a splitter and incoming packets using a merger. Use splitWithProgressFlow(Splitter) or mergeWithProgressFlow(Merger).

    • #352 added support for Big Endian encoding in the Data class to make writing and reading values easier. #353 has deprecated FORMAT_xxx constants in favor of FORMAT_xxx_LE or FORMAT_xxx_BE.

    • #370 allowed to filter fully merged packets. Previously, the filter(...) option allowed to filter incoming packets before they were given to the merger. The new filterPacket(...) does similar thing, but with complete, merged, received packet.

    • And, as usual, reported bugs were fixed.

    What's Changed since beta 3

    • Filtering merged packets by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/370
    • Typo in license fixed by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/372
    • Progress indication as flow by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/371

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.4.0-beta03...2.4.0

    Source code(tar.gz)
    Source code(zip)
  • 2.4.0-beta03(Mar 18, 2022)

    What's Changed

    • State mapping fixed by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/368
    • Returning the same instance of state observers in ktx by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/366
    • Making sure then() callback is called for RemoveBond request by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/365

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.4.0.beta02...2.4.0-beta03

    Source code(tar.gz)
    Source code(zip)
  • 2.4.0.beta02(Feb 16, 2022)

    What's Changed

    • Fix issue with BluetoothDevice field being null in ble-ktx. by @sylwester-zielinski in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/359
    • Fix issue when only one record is returned in CGMS profile. by @sylwester-zielinski in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/360

    New Contributors

    • @sylwester-zielinski made their first contribution in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/359

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.4.0-beta01...2.4.0.beta02

    Post Scriptum

    Sorry for naming the version with a dot instead of a dash. Mind, it's 2.4.0.beta02, not 2.4.0-beta02. Next time the dash will return!

    Source code(tar.gz)
    Source code(zip)
  • 2.4.0-beta01(Feb 2, 2022)

    What's Changed

    • Added support for passkey on pairing request by @0xMyon in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/320
    • Option to filter logs by priority by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/348
      • The new version will by default log level INFO and higher. See #348 to check how to restore previous behavior.
    • Possible NPE fixed by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/350
    • Trying to discover services despite initial bonding failure by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/351
    • Improvement: More ktx extensions by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/349
    • Improvement: Big Endian format types added by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/352
    • Deprecating FORMAT_xxx in favor of FORMAT_xxx_LE by @philips77 in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/353

    New Contributors

    • @0xMyon made their first contribution in https://github.com/NordicSemiconductor/Android-BLE-Library/pull/320

    Full Changelog: https://github.com/NordicSemiconductor/Android-BLE-Library/compare/2.3.1...2.4.0-beta01

    Source code(tar.gz)
    Source code(zip)
  • 2.3.1(Sep 23, 2021)

    This version introduces the following changes:

    • Making ObservableBleManager public (#321 which fixes #309).
    • Disabling indications fixed (#322 which fixes #316).
    • Skipping processing requests when MTU changed before services were discovered (#323).
    • Adding write type param to writeCharacteristic methods (#324 which fixes #317).
    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Aug 30, 2021)

    Main changes:

    • Added support for Kotlin in new :ble-ktx module.
    • :ble-livedata module is converted to Java, as :ble-ktx added support for Flow.
    • JsonMerger added, which combines incoming notifications/indications/incoming write requests (as server).
    • Multiple issues fixed.

    Detailed changes:

    • Improve the handling of ConnectRequests to bonded devices w/ autoConnect=true (#253)
    • Fix README (#222, #275)
    • Update connectGatt version logic to handle bug specifically in API 26 (#248)
    • Introduces a GATT server example (#234)
    • Introduces a GATT client example (#238)
    • Remove outdated documentation on getGattCallback() (#277)
    • Bug fix: Reset MTU to 23 on disconnect (#249)
    • Bug fix: setting state to disconnected after Bluetooth goes OFF, of device bond info is removed (#278)
    • Bug fix for #273, and possibly #241 and #120
    • Bug fix: Service discovery is called twice even if they discovered successfully (for some phones) (#279)
    • Bug fix: ConnectionObserver.onDeviceDisconnected() can never report REASON_TERMINATE_PEER_USER (#284)
    • Bug fix: Connection failed with different reason than onDisconnected callback. (#257)
    • Bug fix: Crash in enqueue() (#252)
    • Improvement: Adding option to cancel pending connection (#292)
    • Improvement: Adding "then" callback to Requests (#293)
    • New feature: JsonMerger added, which will combine multiple packets until full JSON object or array is received https://github.com/NordicSemiconductor/Android-BLE-Library/commit/158bc9b2544699c4369f6c5af1e67c56d275ac2a
    • New feature: support for onServiceChanged callback (API 31) https://github.com/NordicSemiconductor/Android-BLE-Library/commit/2ed10f72c5a6e52ecc08c482ea40b2c494a56b21
    • Improvement: Migration to Android Studio 4.2.x and Maven Central (#296)
    • Breaking: :ble-livedata migrated to Java https://github.com/NordicSemiconductor/Android-BLE-Library/commit/a74c98366d2b7d8fe1537186f25eec25bf0887e8
    • Added support for Kotlin (coroutiones and flow) in :ble-ktx module (#297)
    Source code(tar.gz)
    Source code(zip)
  • v2.2.4(Aug 12, 2020)

    Bugs fixed:

    • Null Pointers fixed (#216).
    • Closing manager when disconnect request was executed, but the manager was disconnected.
    • Other minor improvements.
    Source code(tar.gz)
    Source code(zip)
  • v2.2.3(Jul 6, 2020)

    Improvements:

    • BleManager.ensureBond() method added. On all current Android versions it will remove the current bond information and recreate bond again (#214). It will be doing so until BluetoothDevice.createBond() stop returning false on a valid, open and encrypted link (hopefully in Android 11), or when establishing insecure link to a device with bond information will not be possible.
    Source code(tar.gz)
    Source code(zip)
  • v2.2.1(Jun 30, 2020)

    This version introduces the following changes and bug fixes:

    • split() method fixed when used in write request inside atomic queue or as trigger in waitForNotification or waitForIndication (#200).
    • readRssi() takes now at most 1 second and times out if no response is received. This may be an issue with connection longer intervals (#114).
    • createBond() is now deprecated and was renamed to createBondInsecure() (#208).
    • before(...) callback is not called before a request that is executed synchronously, unless the request is put into an atomic queue.

    Other improvements:

    • Migration to Android Studio 4 and Gradle 6.1.1.
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(May 14, 2020)

    This is a stable 2.2.0 release.

    Improvements since 2.1.1:

    • GATT Server support added (not to be confused with Bluetooth LE advertising).
    • ble-common library moved from standalone repository into this one, as a second module.
    • ble-livedata module added.
    • BleGattCallbacks deprecated. Use ConnectionObserver and BondingObserver instead. For application-level callbacks, manage them in your manager.
    • LegacyBleManager added to make migration easier.
    • Option to set handler for callbacks and for request.
    • Option to set handler for ValueChangedCallback.
    • wait-if and wait-until requests added (also #143).
    • BLE operations are no longer called from UI thread (#138).

    Bugs fixed:

    • ConnectionPriorityRequest should now complete at most after 200 ms. There were phones running Android 8+ there didn't seem to have native callback (#186).
    • #184 - this issue, in a bit different form, was there for a long time. The ConnectRequest.fail(..) callback was never reporting NOT SUPPORTED. Since 2.2.0-alpha10 it was only reporting NOT SUPPORTED, even on normal disconnect.
    • Fixed NPE when Request Handler was not initialized. This is a breaking change, as getGattCallbacks() is now called in the constructor, which implicates that it may not return explicitly initialized field .
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0-beta03(May 14, 2020)

  • v2.2.0-beta02(May 7, 2020)

    Improvements:

    • A new LegacyBleManager class added which should make the transition to 2.2.0 easier. It's still a generic class, like BleManager used to be.
    • Readme updated.

    Bugs fixed:

    • ConnectionPriorityRequest should now complete at most after 200 ms. There were phones running Android 8+ there didn't seem to have native callback (#186).
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0-beta01(Apr 3, 2020)

    This release made the API stable. Only bug fixes are predicted for 2.2.x.

    Bugs fixed:

    • #184 - this issue, in a bit different form, was there for a long time. The ConnectRequest.fail(..) callback was never reporting NOT SUPPORTED. Since 2.2.0-alpha10 it was only reporting NOT SUPPORTED, even on normal disconnect.
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0-alpha13(Apr 3, 2020)

  • v2.2.0-alpha10(Apr 2, 2020)

  • v2.2.0-alpha09(Apr 2, 2020)

    This version renames DisconnectCallback to ConnectionObserver and BondingCallback to BondingObserver. Some methods from the deprecated BleManagerCallbacks were restored in the new ConnectionObserver.

    Source code(tar.gz)
    Source code(zip)
  • v2.2.0-alpha08(Apr 2, 2020)

    Improvements:

    • This version adds a new callback to BleManager: setBondingCallback.
    • The BleManagerCallbacks have been deprecated. Use other ways to get corresponding events. You may continue to use this interface, but it will be removed in the future.
    • BleManagerServerCallbacks have been renamed to ServerCallback and moved to callback package.
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0-alpha07(Mar 31, 2020)

    New in this version:

    • Disconnect callback added (#110 fixed with #149)
    • Option to call a method using callback handler
    • #154 fixed
    • #161 and #162 implemented
    • Option to set handler for ValueChangedCallback
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0-alpha06(Jan 31, 2020)

    Bugs fixed:

    • Closing server was causing NPE when managers were closing.
    • Fixed NPE when Request Handler was not initialized. This is a breaking change, as getGattCallbacks() is now called in the constructor, which implicates that it may not return explicitly initialized field .
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0-alpha05(Jan 30, 2020)

  • v2.2.0-alpha04(Jan 28, 2020)

    Bugs fixed:

    • Sending notifications works on pre-Lollipop devices, where onNotificationSent is not present.
    • Few bugs fixed.

    Improvements:

    • All request types got Operation interface, which allows them to be added to RequestQueue or set as a trigger for AwaitingRequests.
    • Maven publication script updated - dependencies were restored in the POM file.
    Source code(tar.gz)
    Source code(zip)
  • v2.2.0-alpha02(Jan 3, 2020)

    New features:

    • support for GATT Server (#143).
    • wait-if and wait-until requests added (also #143).

    Improvements:

    • BLE operations are no longer called from UI thread (#138).
    • option to specify a handler for calling request callbacks, also in per-request manner.
    • BleManager class split into 2. The manager contains now only the public API (#140)
    Source code(tar.gz)
    Source code(zip)
  • v2.1.1(Mar 14, 2019)

    Bugs fixed:

    • #86 - TimeoutableRequest made public, which helps with C# integration.
    • #87 - some try-catches were added to make the library silky-smooth.
    Source code(tar.gz)
    Source code(zip)
Owner
Nordic Semiconductor
Nordic Semiconductor's official GitHub account. Contains officially supported repositories. For additional Nordic repos see https://github.com/NordicPlayground
Nordic Semiconductor
An Android Library for handling Bluetooth Low Energy on Android Easy

An Android Library for handling Bluetooth Low Energy on Android Easy

Leandro SQ 42 Jan 3, 2023
BLESSED Coroutines, a Bluetooth Low Energy (BLE) library for Android using Kotlin Coroutines

BLESSED for Android with Coroutines - BLE made easy BLESSED is a very compact Bluetooth Low Energy (BLE) library for Android 8 and higher, that makes

Martijn van Welie 82 Jan 1, 2023
Kotlin Asynchronous Bluetooth Low-Energy

Kable Kotlin Asynchronous Bluetooth Low Energy provides a simple Coroutines-powered API for interacting with Bluetooth Low Energy devices. Usage is de

JUUL Labs 493 Dec 25, 2022
Android Bluetooth Helper Library, Bluetooth Device Finder

Bluetooth Helper Allows you to access the Bluetooth of your mobile device, manage turn-on - turn off, and discover bluetooth devices around you. Getti

Tolga Bolatcan 44 Jul 15, 2022
[UNMAINTAINED][Android] Bluetooth Serial Port Profile which comfortable to developer application to communication with microcontroller via bluetooth

⚠ WARNING: This project is no longer being maintained Android-BluetoothSPPLibrary Bluetooth Serial Port Profile which comfortable to developer applica

Akexorcist 1.7k Dec 31, 2022
A reactive, interface-driven central role Bluetooth LE library for Android

RxCentralBle RxCentralBle provides a simple reactive paradigm for connecting to and communicating with Bluetooth LE peripherals from the central role.

Uber Open Source 198 Nov 29, 2022
A Bluetooth kotlin multiplatform "Cross-Platform" library for iOS and Android

Blue-Falcon A Bluetooth "Cross Platform" Kotlin Multiplatform library for iOS, Android, MacOS, Raspberry Pi and Javascript. Bluetooth in general has t

Andrew Reed 220 Dec 28, 2022
This library allows for easy access to a Bluetooth LE device's AdRecord and RSSI value. It offers additional functionality for iBeacons.

Bluetooth LE Library for Android This library allows for easy access to a Bluetooth LE device's Advertisement Records. It also offers: A simple runnin

Alexandros Schillings 843 Dec 13, 2022
Smooth communication via bluetooth with other android devices or microcontrollers such as Arduino.

Android Smooth Bluetooth Smooth communication via bluetooth with other android devices or microcontrollers such as Arduino. Getting Started Add Gradle

Mantas Palaima 191 Nov 28, 2022
RxBle: Use Android Bluetooth API in Rx way

RxBle: Use Android Bluetooth API in Rx way A lightweight encapsulation of Android Bluetooth API. Use Android Bluetooth API in Rx way. Support multiple

null 3 Dec 2, 2022
A non-trivial Bluetooth LE app using Kable and app architecture best practices

kable_mvvm_demo The intention of this project is to demonstrate a non-trivial Bluetooth LE app using Kable and app architecture best practices. ⚠️ The

Chris Laplante 14 Aug 18, 2022
BluePass extracts two factor authentication codes (2FA) from SMS and sends them to a paired device via Bluetooth RFCOMM.

BluePass extracts two factor authentication codes (2FA) from SMS and sends them to a paired device via Bluetooth RFCOMM.

Manuel Huber 15 Dec 4, 2022
Open-source weight and body metrics tracker, with support for Bluetooth scales

Open-source weight and body metrics tracker, with support for Bluetooth scales

OliE 1.3k Jan 4, 2023
Simple bluetooth flutter project

bluetooth_simple Simple bluetooth implementation. Getting Started This project is a starting point for a Flutter application. A few resources to get y

Aleksey Vasiliev 0 Nov 25, 2021
The purpose is to share the Internet capability of one device to the entire Bluetooth LAN.

bluenet The purpose is to share the Internet capability of one device to the entire Bluetooth LAN. To make a prototype of a soft bus, or actually, I w

yunlong.wen 1 Jun 28, 2022
User-friendly Lightweight TPM Remote Attestation over Bluetooth

Ultrablue Ultrablue (User-friendly Lightweight TPM Remote Attestation over Bluetooth) is a solution to allow individual users to perform boot state at

ANSSI 32 Jan 2, 2023
A simple, lightweight library intended to take away some of the cruft and tediousness of using the Android BLE.

Blueteeth What Is Blueteeth? Blueteeth is a simple, lightweight library intended to take away some of the cruft and tediousness of using the Android B

Robot Pajamas 103 Nov 26, 2022
Allows Android apps to interact with BLE beacons

Android Beacon Library An Android library providing APIs to interact with beacons. Please visit the project website for how to use this library. IMPOR

AltBeacon 2.7k Dec 28, 2022
🍔 Meals is a small demo app based on modern Android technologies and MVVM architecture

Meals ?? Meals is a small demo app based on modern Android technologies and MVVM architecture. built-in Kotlin, Coroutine, Flow, Retrofit, and Jetpack

Amr Jyniat 4 Nov 6, 2022