Giter Site home page Giter Site logo

blessed-android's Introduction

BLESSED for Android - BLE made easy

Downloads Android Build

Update!

A Kotlin version of this library is available here: blessed-kotlin.

Introduction

BLESSED is a very compact Bluetooth Low Energy (BLE) library for Android 5 and higher, that makes working with BLE on Android very easy. It takes care of many aspects of working with BLE you would normally have to take care of yourself like:

  • Queueing commands, so you can don't have to wait anymore for the completion of a command before issueing the next command
  • Bonding correctly, so you don't have to do anything in order to robustly bond devices
  • Easy scanning, so you don't have to setup complex scan filters
  • Managing threading, so you don't have to worry about on which thread to issue commands or receive results
  • Threadsafe, so you don't see weird threading related issues anymore
  • Workarounds for some known Android bugs, so you don't have to research any workarounds
  • Higher abstraction methods for convenience, so that you don't have to do a lot of low-level management to get stuff done
  • Supporting multiple simultaneous connections, so that you can connect to many peripherals

The library consists of 5 core classes and corresponding callback abstract classes:

  1. BluetoothCentralManager, and it companion abstract class BluetoothCentralManagerCallback
  2. BluetoothPeripheral, and it's companion abstract class BluetoothPeripheralCallback
  3. BluetoothPeripheralManager, and it's companion abstract class BluetoothPeripheralManagerCallback
  4. BluetoothCentral, which has no callback class
  5. BluetoothBytesParser

The BluetoothCentralManager class is used to scan for devices and manage connections. The BluetoothPeripheral class is a replacement for the standard Android BluetoothDevice and BluetoothGatt classes. It wraps all GATT related peripheral functionality.

The BluetoothPeripheralManager class is used to create your own peripheral running on an Android phone. You can add service, control advertising and deal with requests from remote centrals, represented by the BluetoothCentral class. For more about creating your own peripherals see the separate guide: creating your own peripheral

The BluetoothBytesParser class is a utility class that makes parsing byte arrays easy. You can also use it construct your own byte arrays by adding integers, floats or strings.

The BLESSED library was inspired by CoreBluetooth on iOS and provides the same level of abstraction, but at the same time it also stays true to Android by keeping most methods the same and allowing you to work with the standard classes for Services, Characteristics and Descriptors. If you already have developed using CoreBluetooth you can very easily port your code to Android using this library.

BLESSED is written in Java but has been optimized for Kotlin as well. When using the library in Kotlin, all types will be correct in (non-)nullability.

This library is also available for Linux, see blessed-bluez

Scanning

The BluetoothCentralManager class has several differrent scanning methods:

public void scanForPeripherals()
public void scanForPeripheralsWithServices(UUID[] serviceUUIDs)
public void scanForPeripheralsWithNames(String[] peripheralNames)
public void scanForPeripheralsWithAddresses(String[] peripheralAddresses)
public void scanForPeripheralsUsingFilters(List<ScanFilter> filters)

They all work in the same way and take an array of either service UUIDs, peripheral names or mac addresses. When a peripheral is found you will get a callback on onDiscoveredPeripheral with the BluetoothPeripheral object and a ScanResult object that contains the scan details. So in order to setup a scan for a device with the Bloodpressure service and connect to it, you do:

private final BluetoothCentralManagerCallback bluetoothCentralManagerCallback = new BluetoothCentralManagerCallback() {
        @Override
        public void onDiscoveredPeripheral(BluetoothPeripheral peripheral, ScanResult scanResult) {
            central.stopScan();
            central.connectPeripheral(peripheral, peripheralCallback);
        }
};

// Create BluetoothCentral and receive callbacks on the main thread
BluetoothCentralManager central = new BluetoothCentralManager(getApplicationContext(), bluetoothCentralManagerCallback, new Handler(Looper.getMainLooper()));

// Define blood pressure service UUID
UUID BLOODPRESSURE_SERVICE_UUID = UUID.fromString("00001810-0000-1000-8000-00805f9b34fb");

// Scan for peripherals with a certain service UUID
central.scanForPeripheralsWithServices(new UUID[]{BLOODPRESSURE_SERVICE_UUID});

Note Only 1 of these 4 types of scans can be active at one time! So call stopScan() before calling another scan.

The method scanForPeripheralsUsingFilters is for scanning using your own list of filters. See Android documentation for more info on the use of ScanFilters.

Connecting to devices

There are 3 ways to connect to a device:

public void connectPeripheral(BluetoothPeripheral peripheral, BluetoothPeripheralCallback peripheralCallback)
public void autoConnectPeripheral(BluetoothPeripheral peripheral, BluetoothPeripheralCallback peripheralCallback)
public void autoConnectPeripheralsBatch(Map<BluetoothPeripheral, BluetoothPeripheralCallback> batch) 

The method connectPeripheral will try to immediately connect to a device that has already been found using a scan. This method will time out after 30 seconds or less depending on the device manufacturer. Note that there can be only 1 outstanding connectPeripheral. So if it is called multiple times only 1 will succeed.

The method autoConnectPeripheral is for re-connecting to known devices for which you already know the device's mac address. The BLE stack will automatically connect to the device when it sees it in its internal scan. Therefore, it may take longer to connect to a device but this call will never time out! So you can issue the autoConnect command and the device will be connected whenever it is found. This call will also work when the device is not cached by the Android stack, as BLESSED takes care of it! In contrary to connectPeripheral, there can be multiple outstanding autoConnectPeripheral requests.

The method autoConnectPeripheralsBatch is for re-connecting to multiple peripherals in one go. Since the normal autoConnectPeripheral may involve scanning, if peripherals are uncached, it is not suitable for calling very fast after each other, since it may trigger scanner limitations of Android. So use autoConnectPeripheralsBatch if the want to re-connect to many known peripherals.

If you know the mac address of your peripheral you can obtain a BluetoothPeripheral object using:

BluetoothPeripheral peripheral = central.getPeripheral("CF:A9:BA:D9:62:9E");

After issuing a connect call, you will receive one of the following callbacks:

public void onConnectedPeripheral(BluetoothPeripheral peripheral)
public void onConnectionFailed(BluetoothPeripheral peripheral, HciStatus status)
public void onDisconnectedPeripheral(BluetoothPeripheral peripheral, HciStatus status)

To disconnect or to cancel an outstanding connectPeripheral() or autoConnectPeripheral(), you call:

public void cancelConnection(BluetoothPeripheral peripheral)

In all cases, you will get a callback on onDisconnectedPeripheral when the disconnection has been completed.

Service discovery

The BLESSED library will automatically do the service discovery for you and once it is completed you will receive the following callback:

public void onServicesDiscovered(BluetoothPeripheral peripheral)

In order to get the services you can use methods like getServices() or getService(UUID). In order to get hold of characteristics you can call getCharacteristic(UUID) on the BluetoothGattService object or call getCharacteristic() on the BluetoothPeripheral object.

This callback is the proper place to start enabling notifications or read/write characteristics.

Reading and writing

Reading and writing to characteristics is done using the following methods:

public boolean readCharacteristic(BluetoothGattCharacteristic characteristic)
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic, byte[] value, WriteType writeType)

Both methods are asynchronous and will be queued up. So you can just issue as many read/write operations as you like without waiting for each of them to complete. You will receive a callback once the result of the operation is available. For read operations you will get a callback on:

public void onCharacteristicUpdate(BluetoothPeripheral peripheral, byte[] value, BluetoothGattCharacteristic characteristic, GattStatus status)

If you want to write to a characteristic, you need to provide a value and a writeType. The writeType is usually WITH_RESPONSE or WITHOUT_RESPONSE. If the write type you specify is not supported by the characteristic you will see an error in your log. For write operations you will get a callback on:

public void onCharacteristicWrite(BluetoothPeripheral peripheral, byte[] value, BluetoothGattCharacteristic characteristic, final GattStatus status)

In these callbacks, the value parameter is the threadsafe byte array that was received. Use this value instead of the value that is part of the BluetoothGattCharacteristic object, since that one may have changed in the mean time because of incoming notifications or write operations.

Turning notifications on/off

BLESSED provides a convenience method setNotify to turn notifications/indications on or off. It will perform all the necessary operations like writing to the Client Characteristic Configuration descriptor for you. So all you need to do is:

BluetoothGattCharacteristic currentTimeCharacteristic = peripheral.getCharacteristic(CTS_SERVICE_UUID, CURRENT_TIME_CHARACTERISTIC_UUID);
if (currentTimeCharacteristic != null) {
     peripheral.setNotify(currentTimeCharacteristic, true);
}

Since this is an asynchronous operation you will receive a callback that indicates success or failure. You can use the method isNotifying to check if the characteristic is currently notifying or not:

@Override
public void onNotificationStateUpdate(BluetoothPeripheral peripheral, BluetoothGattCharacteristic characteristic, GattStatus status) {
     if (status == GattStatus.SUCCESS) {
          if(peripheral.isNotifying(characteristic)) {
               Log.i(TAG, String.format("SUCCESS: Notify set to 'on' for %s", characteristic.getUuid()));
          } else {
               Log.i(TAG, String.format("SUCCESS: Notify set to 'off' for %s", characteristic.getUuid()));
          }
     } else {
          Log.e(TAG, String.format("ERROR: Changing notification state failed for %s", characteristic.getUuid()));
     }
}

When notifications arrive, you will receive a callback on:

public void onCharacteristicUpdate(BluetoothPeripheral peripheral, byte[] value, BluetoothGattCharacteristic characteristic, GattStatus status)

Bonding

BLESSED handles bonding for you and will make sure all bonding variants work smoothly. During the process of bonding, you will be informed of the process via a number of callbacks:

public void onBondingStarted(final BluetoothPeripheral peripheral)
public void onBondingSucceeded(final BluetoothPeripheral peripheral)
public void onBondingFailed(final BluetoothPeripheral peripheral) 
public void onBondLost(final BluetoothPeripheral peripheral) 

In most cases, the peripheral will initiate bonding either at the time of connection, or when trying to read/write protected characteristics. However, if you want you can also initiate bonding yourself by calling createBond on a peripheral. There are two ways to do this:

  • Calling createBond when not yet connected to a peripheral. In this case, a connection is made and bonding is requested.
  • Calling createBond when already connected to a peripheral. In this case, only the bond is created.

It is also possible to remove a bond by calling removeBond. Note that this method uses a hidden Android API and may stop working in the future. When calling the removeBond method, the peripheral will also disappear from the settings menu on the phone.

Lastly, it is also possible to automatically issue a PIN code when pairing. Use the method setPinCodeForPeripheral to register a 6 digit PIN code. Once bonding starts, BLESSED will automatically issue the PIN code and the UI dialog to enter the PIN code will not appear anymore.

Requesting a higher MTU to increase throughput

The default MTU is 23 bytes, which allows you to send and receive byte arrays of MTU - 3 = 20 bytes at a time. The 3 bytes overhead are used by the ATT packet. If your peripheral supports a higher MTU, you can request that by calling:

public void requestMtu(int mtu)

You will get a callback on:

public void onMtuChanged(BluetoothPeripheral peripheral, int mtu, GattStatus status)

This callback will tell you what the negotiated MTU value is. Note that you may not get the value you requested if the peripheral doesn't accept your offer. If you simply want the highest possible MTU, you can call peripheral.requestMtu(BluetoothPeripheral.MAX_MTU) and that will lead to receiving the highest possible MTU your peripheral supports.

Once the MTU has been set, you can always access it by calling getCurrentMtu(). If you want to know the maximum length of the byte arrays that you can write, you can call the method getMaximumWriteValueLength(). Note that the maximum value depends on the write type you want to use.

Long reads and writes

The library also supports so called 'long reads/writes'. You don't need to do anything special for them. Just read a characteristic or descriptor as you normally do, and if the characteristic's value is longer than MTU - 1, then a series of reads will be done by the Android BLE stack. But you will simply receive the 'long' characteristic value in the same way as normal reads.

Similarly, for long writes, you just write to a characteristic or descriptor and the Android BLE stack will take care of the rest. But keep in mind that long writes only work with WriteType.WITH_RESPONSE and the maximum length of your byte array should be 512 or less. Note that not all peripherals support long reads/writes so this is not guaranteed to work always.

Status codes

When connecting or disconnecting, the callback methods will contain a parameter HciStatus status. This enum class will have the value SUCCESS if the operation succeeded and otherwise it will provide a value indicating what went wrong.

Similarly, when doing GATT operations, the callbacks methods contain a parameter GattStatus status. These two enum classes replace the int status parameter that Android normally passes.

Bluetooth 5 support

As of Android 8, Bluetooth 5 is natively supported. One of the things that Bluetooth 5 brings, is new physical layer options, called Phy that either give more speed or longer range. The options you can choose are:

  • LE_1M, 1 mbit PHY, compatible with Bluetooth 4.0, 4.1, 4.2 and 5.0
  • LE_2M, 2 mbit PHY for higher speeds, requires Bluetooth 5.0
  • LE_CODED, Coded PHY for long range connections, requires Bluetooth 5.0

You can set a preferred Phy by calling:

public boolean setPreferredPhy(PhyType txPhy, PhyType rxPhy, PhyOptions phyOptions)

By calling setPreferredPhy() you indicate what you would like to have but it is not guaranteed that you get what you ask for. That depends on what the peripheral will actually support and give you. If you are requesting LE_CODED you can also provide PhyOptions which has 3 possible values:

  • NO_PREFERRED, for no preference (use this when asking for LE_1M or LE_2M)
  • S2, for 2x long range
  • S8, for 4x long range

The result of this negotiation will be received on:

public void onPhyUpdate(PhyType txPhy, PhyType rxPhy, GattStatus status)

As you can see the Phy for sending and receiving can be different but most of the time you will see the same Phy for both. Note that onPhyUpdate will also be called by the Android stack when a connection is established or when the Phy changes for other reasons. If you don't call setPreferredPhy(), Android seems to pick PHY_LE_2M if the peripheral supports Bluetooth 5. So in practice you only need to call setPreferredPhy if you want to use PHY_LE_CODED.

You can request the current values at any point by calling:

public boolean readPhy()

The result will be again delivered on onPhyUpdate()

Logging

Blessed uses Timber for logging. If you don't want Blessed to do any logging you can disable logging:

central.disableLogging()

Installation

Blessed is available on Jitpack. Modify your gradle file to include the library:

allprojects {
        repositories {
                ...
                maven { url 'https://jitpack.io' }
        }
}

dependencies {
        implementation 'com.github.weliem:blessed-android:2.0.6'
}

Example application

An example application is provided in the repo. It shows how to connect to Blood Pressure meters, Heart Rate monitors, Weight scales, Glucose Meters, Pulse Oximeters and Thermometers, read the data and show it on screen. It only works with peripherals that use the Bluetooth SIG services. Working peripherals include:

  • Beurer FT95 thermometer
  • GRX Thermometer (TD-1241)
  • Masimo MightySat
  • Nonin 3230
  • Indiehealth scale
  • A&D 352BLE scale
  • A&D 651BLE blood pressure meter
  • Beurer BM57 blood pressure meter
  • Soehnle Connect 300/400 blood pressure meter
  • Polar H7/H10/OH1 heartrate monitors
  • Contour Next One glucose meter
  • Accu-Chek Instant glucose meter
  • Omron X4 Smart

blessed-android's People

Contributors

aknabi avatar bbilger avatar bluestormdna avatar fajnydev avatar lorand-brookvale avatar martijnvanwelie avatar paymicro avatar weliem avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blessed-android's Issues

Best method for writing to characteristic outside of callbacks

Hi Martijn,
I have been looking through your example app and I noticed that you only write to characteristics through callbacks in BluetoothHandler.java. If I want to write to a characteristic outside of a callback, like in response to a user pressing a button, what would be the best way to go about doing that? Currently, the best solution that I have thought of is to create a function within BluetoothHandler.java that uses getConnectedPeripherals, select the peripheral I want, and then use writeCharacteristic. Any help would be appreciated.

Need explicit disconnection

Hello and thanks for this API !

We use a foreground service to record bluetooth data from multiple BLE devices and when we stop the recording, we need to explicitly disconnect from all devices. After calling central.close(), we continue to receive callbacks from updated characteristic, even when trying to stop thread and disconnecting callbacks (we are using our own callbacks on top on blessed callbacks)

It seems central.close() do not disconnect connected devices but only clear some device list and callbacks and unregister. Maybe we need an explicit disconnection to stop all BLE gatt/devices connection opened with blessed ?

IsBluetoothEnable Error

Currently in the implementation I see that if I start scan and if Bluetooth is not enabled the method just returns. Can we throw an exception or send a status or make the isBluetoothenable API public.

Connection failed with status 8

Hi, I'll drop some logs that I got that might give you some idea of what's happenning:

Starting scanner
Device is recognized
Scanning stopped
Manually connecting device X
Manually connecting device X
Manually connecting device X
$bluetoothCentralCallback: connection 'X' failed with status 8
Manually connecting device X
Manually connecting device X
$bluetoothCentralCallback: connection 'X' failed with status 8
Manually connecting device X

I know that you wrote in your blog post that this can be normal, but is there anything that I can do? You mentioned that I could do a clean-up. Can you please show me an example of that?
I also can see that I'm doing manual connection more than once (it's with few seconds interval) - could this cause this error? Obv, this I could fix.

Manually connecting:

central.connectPeripheral(peripheral, peripheralCallback)

Connection timeout

Hi!

Weยดre trying to connect our scale: "mi scale 2" with a redmi 5 plus (8.1.0) but we canยดt do the connection.

Try to connect to BLE device D0:96:65:48:E7:F5
connect to 'MIBCS' (D0:96:65:48:E7:F5) using TRANSPORT_LE
device: D0:96:65:48:E7:F5, auto: false
registerApp()
registerApp() - UUID=ca8e1ff7-7c06-4362-9779-27b7e159256e
onClientRegistered() - status=0 clientIf=7
connection timout, disconnecting 'MIBCS'
close()
unregisterApp() - mClientIf=7
disconnected 'MIBCS' with status 8

With others devices work fine. ยฟAny ideas?

Thank you very much!!!!

Scan return null

Hi, Whe Scan always return name of device null and no connect.

Test in Android 9

Keeping Bluetooth in the background?

Thanks for this package!
It looks like it could make using BLE much easier in my application.
Since my application has a significant user interface, and Android suggests that the UI activity be in the foreground for best performance, I'm wondering if you have thoughts on the changes necessary (or a version already exists?) where bluetooth (central) runs in the background as a service? I'm hoping the BLE central will run in the background (collecting data) and make it available from the service.
Thoughts on the changes needed?
Thanks...

autoConnect() takes too long to connect with device

Hi, so I'm using your library and what I do is I create connections with BLE peripheral periodically.

For first implementation I used connect() and it worked very well. Connection was made very fast. Then bug was found - if user toogled bluetooth on/off, bluetooth cache stack was cleared and then connect() did not work anymore. I went through your documentation and found that autoConnect() can be used and with this implementation toogling bluetooth on/off still worked, which was a blast. But then reports came in that sometimes autoConnect() takes up to 10 minutes, which is big delay for our logic.

Question is, is there something that we can do? Is there a possibility to fix bluetooth toogle on/off cache clearing for manualConnection()? Or is there a way to reduce autoConnect() delay to minimum?

Convert callbacks to interface

Is there any specific reason why the Central and Peripheral callbacks are abstract classes, instead of interfaces? Having interfaces (with a default abstract implementation) would be much nicer than having to rely on abstract classes.

lower minSdkVersion to 19

First of all great library. Currently I am trying out your library with my project openScale to replace the RxAndroidBle library but your minSdkVersion is 24 which is not really necessary, isn't it?
I lowered your library to 19 and I had no problems? Is it possible that lower your minSdkVersion to 19, so that I can use your library without increasing my minSdkVersion? ๐Ÿ˜‰

Reconnect device after reboot

Is there any methods in the library to reconnect the device after reboot.
On iOS it is possible so you library could try to implement this usefull feature.
If it is not in the roadmap, can you please advice how to implement this taking into account new Android 10 constraints related to BLE (no background service if I'm correct)

GATT CONN TERMINATE PEER USER error

Hello Team,

I am trying to extend your code for Blood Sugar reading. I have "Accu-Chek Instant" device. I have set Services and Characteristics in your code but it always gets disconnected. Find below the log:

2020-04-03 18:29:04.594 10737-10737/com.welie.blessedexample D/BluetoothGatt: registerApp() - UUID=235986d8-9cd4-485d-bc21-fc2629117da7
2020-04-03 18:29:04.597 10737-10750/com.welie.blessedexample D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
2020-04-03 18:29:12.762 10737-10750/com.welie.blessedexample D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=90:9A:77:EC:53:1A
2020-04-03 18:29:12.768 10737-10750/com.welie.blessedexample I/BluetoothPeripheral: connected to 'meter+02252924' (BOND_BONDED) in 8.2s
2020-04-03 18:29:12.773 10737-10737/com.welie.blessedexample D/BluetoothPeripheral: discovering services of 'meter+02252924' with delay of 0 ms
2020-04-03 18:29:12.773 10737-10737/com.welie.blessedexample D/BluetoothGatt: discoverServices() - device: 90:9A:77:EC:53:1A
2020-04-03 18:29:13.028 10737-10750/com.welie.blessedexample D/BluetoothGatt: onConnectionUpdated() - Device=90:9A:77:EC:53:1A interval=6 latency=0 timeout=500 status=0
2020-04-03 18:29:13.555 10737-10750/com.welie.blessedexample D/BluetoothGatt: onSearchComplete() = Device=90:9A:77:EC:53:1A Status=0
2020-04-03 18:29:13.559 10737-10750/com.welie.blessedexample I/BluetoothPeripheral: discovered 4 services for 'meter+02252924'
2020-04-03 18:29:13.563 10737-10737/com.welie.blessedexample I/BluetoothHandler: connected to 'meter+02252924'
2020-04-03 18:29:13.564 10737-10737/com.welie.blessedexample I/BluetoothHandler: discovered services
2020-04-03 18:29:13.566 10737-10737/com.welie.blessedexample D/BluetoothGatt: requestConnectionPriority() - params: 1
2020-04-03 18:29:13.569 10737-10737/com.welie.blessedexample D/BluetoothPeripheral: requesting connection priority 1
2020-04-03 18:29:13.573 10737-10737/com.welie.blessedexample D/BluetoothPeripheral: reading characteristic <00002a29-0000-1000-8000-00805f9b34fb>
2020-04-03 18:29:13.587 10737-10737/com.welie.blessedexample I/BluetoothHandler: Received manufacturer: Roche
2020-04-03 18:29:13.590 10737-10737/com.welie.blessedexample D/BluetoothPeripheral: reading characteristic <00002a24-0000-1000-8000-00805f9b34fb>
2020-04-03 18:29:13.592 10737-10750/com.welie.blessedexample D/BluetoothGatt: onConnectionUpdated() - Device=90:9A:77:EC:53:1A interval=36 latency=0 timeout=500 status=0
2020-04-03 18:29:13.705 10737-10737/com.welie.blessedexample I/BluetoothHandler: Received modelnumber: 960
2020-04-03 18:29:13.705 10737-10737/com.welie.blessedexample D/BluetoothGatt: setCharacteristicNotification() - uuid: 00002a18-0000-1000-8000-00805f9b34fb enable: true
2020-04-03 18:29:13.795 10737-10737/com.welie.blessedexample I/BluetoothHandler: SUCCESS: Notify set to 'on' for 00002a18-0000-1000-8000-00805f9b34fb
2020-04-03 18:29:13.837 10737-10750/com.welie.blessedexample D/BluetoothGatt: onConnectionUpdated() - Device=90:9A:77:EC:53:1A interval=6 latency=0 timeout=2000 status=0
2020-04-03 18:29:33.336 10737-10750/com.welie.blessedexample D/BluetoothGatt: onClientConnectionState() - status=19 clientIf=6 device=90:9A:77:EC:53:1A
2020-04-03 18:29:33.340 10737-10750/com.welie.blessedexample I/BluetoothPeripheral: peripheral 'meter+02252924' disconnected with status 'GATT CONN TERMINATE PEER USER'
2020-04-03 18:29:33.340 10737-10750/com.welie.blessedexample D/BluetoothGatt: close()
2020-04-03 18:29:33.341 10737-10750/com.welie.blessedexample D/BluetoothGatt: unregisterApp() - mClientIf=6
2020-04-03 18:29:33.364 10737-10737/com.welie.blessedexample I/BluetoothHandler: disconnected 'meter+02252924' with status 19
2020-04-03 18:29:38.376 10737-10737/com.welie.blessedexample I/BluetoothPeripheral: autoConnect to 'meter+02252924' (90:9A:77:EC:53:1A) using TRANSPORT_LE
2020-04-03 18:29:38.377 10737-10737/com.welie.blessedexample D/BluetoothGatt: connect() - device: 90:9A:77:EC:53:1A, auto: true
2020-04-03 18:29:38.377 10737-10737/com.welie.blessedexample D/BluetoothGatt: registerApp()
2020-04-03 18:29:38.378 10737-10737/com.welie.blessedexample D/BluetoothGatt: registerApp() - UUID=4b613ce0-bc83-49b6-8275-7dda7cf475fd
2020-04-03 18:29:38.380 10737-10750/com.welie.blessedexample D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6

Let me know what's wrong going on.

Thank you so much in advance.

IntentReceiver leaking in BluetoothCentral

E/ActivityThread: Service com.blebackground.android.app.BleService has leaked IntentReceiver com.welie.blessed.BluetoothCentral$10@52c4df4 that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.IntentReceiverLeaked: Service com.blebackground.android.app.BleService has leaked IntentReceiver com.welie.blessed.BluetoothCentral$10@52c4df4 that was originally registered here. Are you missing a call to unregisterReceiver()?
at android.app.LoadedApk$ReceiverDispatcher.(LoadedApk.java:1669)
at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:1446)
at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1614)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1587)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1575)
at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:627)
at com.welie.blessed.BluetoothCentral.(BluetoothCentral.java:337)
at com.blebackground.android.app.BleService.onCreate(BleService.kt:57)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:4521)
at android.app.ActivityThread.access$2600(ActivityThread.java:296)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2243)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:213)
at android.app.ActivityThread.main(ActivityThread.java:8178)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)

Looks like we need some api to stop broadcast receivers to prevent leaking. I think it's caused because adapterStateReceiver is never unregistered.

Crash on connection timeout in BluetoothPeripheral

Crash log:
2020-08-10 19:41:55.658 6704-6903/com.x.x.x.debug D/BluetoothGatt: close()
2020-08-10 19:41:55.658 6704-6903/com.x.x.x.debug D/BluetoothGatt: unregisterApp() - mClientIf=11
2020-08-10 19:41:55.660 7163-7202/? I/bt_stack: [INFO:gatt_api.cc(1212)] GATT_Disconnect conn_id=0
2020-08-10 19:41:55.660 7163-7184/? E/BtGatt.ContextMap: Context not found for ID 11
--------- beginning of crash
2020-08-10 19:41:55.663 6704-6917/com.x.x.x.x E/AndroidRuntime: FATAL EXCEPTION: ThreadHandlerWrapper14
Process: com.tekoia.sure.server.debug, PID: 6704
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.bluetooth.BluetoothGatt.disconnect()' on a null object reference
at com.welie.blessed.BluetoothPeripheral$9.run(BluetoothPeripheral.java:996)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.os.HandlerThread.run(HandlerThread.java:65)

Triggered by the execution of "timeoutRunnable" in startConnectionTimer where the BluetoothGatt.close() invoked and set to null just before BluetoothGatt.disconnect() was executed asynchronously.

How to connect to 2 Devices parallel

I want to build a bikecomputer with heartrate function.
After I implemented the blessed app successfully and expanded the app to get the
batterylevel plus heartrate on the Screen. I enhanced the BluetoothHandler.java
to receive the signals from a combodevice which sends cycling and cadence values.
With your old version I could not receive signals, but after download the newer blessed app
last weekend, I could receive the signals from the combodevice. The problem is,
I could only receive HR- or CSC-signals, not both together.
I think it is necessary to change something in the "blessed App" especially in
the peripheral.java. But I donโ€™t understand the "blessed App" so far that I can
do that.
I hope to get help from you.
Thank You.

Cannot bond BLE device - no popup dialog is shown

So I started off trying to follow android instructions, but I got the same results. Then I thought that I'm implementing something very bad, so I decided to test it with your library.

08-27 15:53:52.283 8853-8853/com.welie.blessedexample W/BluetoothCentral: peripheral with address 'E6:F6:05:7E:6A:5D' is not in the Bluetooth cache, hence connection may fail 08-27 15:53:57.308 8853-8853/com.welie.blessedexample I/BluetoothPeripheral: connect to 'null' (...7E:6A:5D) using TRANSPORT_LE 08-27 15:54:02.350 8853-8866/com.welie.blessedexample I/BluetoothPeripheral: connected to 'null' (BOND_NONE) in 5.0s 08-27 15:54:03.167 8853-8866/com.welie.blessedexample I/BluetoothPeripheral: discovered 5 services for 'null' 08-27 15:54:03.170 8853-8853/com.welie.blessedexample I/BluetoothHandler: connected to 'null' 08-27 15:54:03.170 8853-8853/com.welie.blessedexample I/BluetoothHandler: discovered services 08-27 15:54:04.476 8853-8995/com.welie.blessedexample W/BluetoothPeripheral: read needs bonding, bonding in progress

Well, I get a error 137 which is related with authorization. Kinda makes sense, because I know I have to enter pin for this specific characteristic to be read, but the problem is that I cannot seem to open dialog (it is not shown).

  1. pairingRequestBroadcastReceiver does not receive anything, so I think that text "bonding is in progress" is not correct. I did try to manually do bonding with createBond(); same results.

Back story: When I did this implementation on my side first, I saw a dialog - I entered correct pin and then I unpaired the device to try re-bonding again. After that, there was no pairing dialog shown. I tried different devices - same result. Could it be that device somehow caches bonding or something? Maybe device caches something?

I tested with Samsung S9 (Android 9) and Sony (Android 7.x). Same results.

using custom ScanFilters not possible right now

First of all: great project. Thank you very much. Getting Android BLE right is not an easy task!

I evaluated this library for a project and it would be perfect, if there was an option to provide custom ScanFilters.

Right now there is no public method that takes filters as a parameter. Could be easily added. If you agree that this would be useful and have not time to implement it, I can prepare a PR.

Queue commands

Could you write a bit how the queue command works?

Queueing commands, so you can don't have to wait anymore for the completion of a command before issueing the next command

For example if I send following commands to the Bluetooth device:

writeCharacteristic(A)
writeCharacteristic(B)
setNotify(XYZ)
writeCharacteristic(C)

then I assume all commands are queued executed on each success?
Case A:
invoke write A -> successful written A -> invoke write B -> successful written B -> set notfiy XYZ -> succesful notfied XYZ -> invoke write C -> successful written C

or are they only queued invoked but not wait for a successful completion?
Case B:
invoke write A -> invoke write B ->set notfiy XYZ -> invoke write C-> successful written B -> successful written A -> succesful notfied XYZ -> successful written C

For my program I need the case A but I think you implemented case B, am I right?

scanForPeripheralsWithServices does never return any result

Martijn, I am trying to use your code to connect to a peripheral device with a specific service uuid. I installed your code as is and modified the scan initiation as follows:


    static private String HSS_GATE_SERVICE              = "79ceffa8-cb5c-4b03-a6c5-8e8282928067";
    final  private static UUID UUID_HSS_GATE_SERVICE    = UUID.fromString(HSS_GATE_SERVICE);
    private BluetoothHandler(Context context) {
        this.context = context;

        // Create BluetoothCentral
        central = new BluetoothCentral(context, bluetoothCentralCallback, new Handler());

        // Scan for peripherals with a certain service UUIDs
        central.startPairingPopupHack();
        central.scanForPeripheralsWithServices(new UUID[]{UUID_HSS_GATE_SERVICE});
        // central.scanForPeripherals();
    }

The device (only one) is definitely ready for connection but there is no response to this call. If I scan by MAC or without a filter, I get the response.

Do have an idea what needs to be done to scan for service UUID's

Cannot connect to devices now and then

The flow I've is:

  1. Start scanning
  2. When specific device is found, Stop the scan and do connection
  3. If connection is successful for specific device, do 1.-3. steps again for other devices that are found nearby.

Problem is that, sometimes connection is very easy and works great, but most of the time it fails with error code 8. Is there a way to create bullet-proof solution that connection work 8/10 times? For me it's like 2/10 for now. My logic holds on doing a single connection once to the device to procceed (it does not have to stay in connected state, it's enough for a single successful connection per device to continue). So, making a connection is crucial for my app. Below is the log.

UPDATED: Removed delay function in callbacks and made sure that start/stop has some delay.

From the logs you can see, that first I scan and do connection with found device. It gives back errors and after some time I restart scanning (every 30 secs). In logs u can see that scanner is started, but there's no results after that - multiple tries. This usually happens when I get few connection fails in a row.

I also see that there's a message that as the device is not in cache, it's likely to fail connecting - which is weird, because, as I understand to push device into a cache you have to scan before, but my flow is that I do connection with device after scanning i.e. onDiscoveredPeripheral() callback.

  1. Is there a possibility to enhance the connection (it seems to work worse with 9.0+ android, but it's okay so to say for lower OS versions)?
  2. Is it bad to trust in connections of BLE devices as they fail so much? Or is there a way to improve that?

I thought that scanning one device, connecting to it - waiting for response, and then when connection gives back answer in callbacks - restart scanning works better. Not sure tho.

No data returned - can't find a device

I have been trying to implement your library to a project but having problem with getting any devices found?

    BluetoothCentral central;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        central = new BluetoothCentral(getApplicationContext(), bluetoothCentralCallback, new Handler(Looper.getMainLooper()));

        Runnable helloRunnable = new Runnable() {
            public void run() {
                central.scanForPeripherals();

            }
        };

        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        executor.scheduleAtFixedRate(helloRunnable, 0, 20, TimeUnit.SECONDS);


    }
    private final BluetoothCentralCallback bluetoothCentralCallback = new BluetoothCentralCallback() {
        @Override
        public void onDiscoveredPeripheral(BluetoothPeripheral peripheral, ScanResult scanResult) {

            Timber.d(scanResult.getScanRecord().getDeviceName());
            Timber.d(scanResult.getScanRecord().getManufacturerSpecificData().toString());
            central.stopScan();
        }
    };

    private final BluetoothPeripheralCallback peripheralCallback = new BluetoothPeripheralCallback() {
        @Override
        public void onServicesDiscovered(BluetoothPeripheral peripheral) {
            super.onServicesDiscovered(peripheral);
            Timber.d(peripheral.getAddress());
        }
    };

How to determine which peripheral service UUID when peripheral is discovered

I'm scanning for bluetooth devices with 3 different service UUIDs (cycling power, fitness machine, and heart rate monitors). In the onDiscoveredPeripheral() method, I need to differentiate which service UUID the peripheral belongs to. I don't see a way to do that. peripheral.getService(UUID) returns null in all cases. Is there something else I need to do to see the advertising UUID for each peripheral when it's discovered?

connectPeripheral without stopping the scan

Hi,

I'm quite new to BLE and Android development so please excuse my naiveness!

I'm trying to read a string stored as a characteristic value being advertised by an iOS device.
The issue is the app on the iOS device is in the background state and as the Apple Core Bluetooth documentation goes, it doesn't advertise the local name or any service UUID.

So I decided to connect with every Apple device (filtered by the manufacturer identifier), look for the specific SERVICE_UUID, then look for the CHARACTERISTIC_UUID, and then finally read the characteristic value. Which works pretty neatly using BLESSED actually!

The requirement is that I read and show the string value in 'near' realtime, as and when any iOS peripheral is discovered. I can't start and stop the scan every time a peripheral is discovered, because of this...

As of Android 7, starting and stopping scans more than 5 times in a window of 30 seconds will temporarily disable scanning.

Looking at my log, I think calling connectPeripheral multiple times (once for every onDiscoveredPeripheral callback) without stopping the scan overrides some of the connections, leaves some hanging without reaching the onCharacteristicUpdate callback and causes some havoc.

I have called for cancelConnection in the onCharacteristicUpdate callback after reading the value and also right after calling the connectPeripheral. I have also removed the autoConnectPeripheral from your example code.

The connections happen at their will and fail most of the times without any callback to onConnectionFailed. I'm not sure what I'm doing wrong here.

Do I need to queue each connectPeripheral?
Does the "Queueing commands" feature of BLESSED take care of connectPeripheral?

EDIT:
I've also thought of adding a filter of devices (addresses) once connected and not connecting with them again for a few seconds. Can this help?!

Multiple connects at the same time.

Afternoon Martijn. Am I correct to say your sample app only connects one ble device at a time? How can I connect to multiple? And how many can I connect?

Scan timeout

Hi Martijn,

is it possible to implement a scan timeout? I have the following problem some devices needs to be turned on, otherwise no Bluetooth connection is possible. So I want to notify the user after a timeout. For a direct connection with connectPeripheral it works flawlessly because we have a 30s timeout but if I do scanForPeripheralsWithAddresses there is no timeout, it will result in a endless scan.

Best regards
oli

ble scan for unknown devices

it would be great if you could add a 4th scan method to scan for unknown devices to discover the hardware address or the services of each Bluetooth device. What do you think?

Error writing charactestic with more than 20/23 bytes (MTU changed)

Hello,
I am trying to write a chunk of datas (~40 bytes).
I changed the MTU but it's still refused. any idea why ?

The MTU request change seems to be accepted (to 64 bytes).

2020-09-19 13:44:00.769 6789-8440/com.welie.blessedexample I/BluetoothPeripheral: discovered 3 services for 'SmartLCD'
2020-09-19 13:44:00.772 6789-6789/com.welie.blessedexample I/BluetoothHandler: connected to 'SmartLCD'
2020-09-19 13:44:00.772 6789-6789/com.welie.blessedexample I/BluetoothHandler: discovered services
2020-09-19 13:44:00.774 6789-6789/com.welie.blessedexample D/BluetoothGatt: configureMTU() - device: 30:AE:A4:99:85:CA mtu: 185
2020-09-19 13:44:00.788 6789-8440/com.welie.blessedexample D/BluetoothGatt: onConfigureMTU() - Device=30:AE:A4:99:85:CA mtu=64 status=0
2020-09-19 13:44:00.789 6789-6789/com.welie.blessedexample I/BluetoothHandler: new MTU set: 64 / status: 0
2020-09-19 13:44:00.789 6789-6789/com.welie.blessedexample D/BluetoothGatt: requestConnectionPriority() - params: 1
2020-09-19 13:44:00.791 6789-6789/com.welie.blessedexample D/BluetoothPeripheral: requesting connection priority 1
2020-09-19 13:44:00.792 6789-6789/com.welie.blessedexample D/BluetoothGatt: setCharacteristicNotification() - uuid: beb5483e-36e1-4688-b7f5-ea07361b26a0 enable: true
2020-09-19 13:44:00.828 6789-6789/com.welie.blessedexample I/BluetoothHandler: SUCCESS: Notify set to 'on' for beb5483e-36e1-4688-b7f5-ea07361b26a0

...
2020-09-19 13:44:01.875 6789-6789/com.welie.blessedexample D/BluetoothPeripheral: writing <03010203000600000430303030001161613a62623a63633a64643a65653a6666b4640164020501fb0150001601> to characteristic <beb5483e-36e1-4688-b7f5-ea07361b26a9>
2020-09-19 13:44:06.903 6789-8440/com.welie.blessedexample E/BluetoothPeripheral: writing <03010203000600000430303030001161613a62623a63633a64643a65653a6666b4640164020501fb0150001601> to characteristic <beb5483e-36e1-4688-b7f5-ea07361b26a9> failed, status GATT ERROR
2020-09-19 13:44:06.909 6789-6789/com.welie.blessedexample I/BluetoothHandler: ERROR: Failed writing <03010203000600000430303030001161613a62623a63633a64643a65653a6666b4640164020501fb0150001601> to <beb5483e-36e1-4688-b7f5-ea07361b26a9>
2020-09-19 13:44:06.913 6789-8440/com.welie.blessedexample D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=4 device=30:AE:A4:99:85:CA
2020-09-19 13:44:06.920 6789-8440/com.welie.blessedexample I/BluetoothPeripheral: peripheral 'SmartLCD' disconnected with status 'GATT CONN TIMEOUT'
2020-09-19 13:44:06.921 6789-8440/com.welie.blessedexample D/BluetoothGatt: close()
2020-09-19 13:44:06.926 6789-8440/com.welie.blessedexample D/BluetoothGatt: unregisterApp() - mClientIf=4
2020-09-19 13:44:06.950 6789-6789/com.welie.blessedexample I/BluetoothHandler: disconnected 'SmartLCD' with status 8

Connection after initial pairing fails

I'm running the very latest version of the library and can only connect with an initial pairing. That is working perfectly. If I start the app up again though, eventually it will time out, try to connect again, and that too will time out. This same device works on iPhone after having been paired initially if that helps.

Here is the log file. Note that I added some additional logging.

2020-08-12 17:39:09.023 17697-17697/com.android.stalkerradar I/PeripheralListAdapter: Firing up RadarEnabled to connect to Radar gun: Stalker Pro IIs 1019
2020-08-12 17:39:09.031 17697-17697/com.android.stalkerradar I/BluetoothCentral: no scan to stop because no scan is running
2020-08-12 17:39:09.118 17697-17697/com.android.stalkerradar I/RadarEnabledActivity: Checking permissions
2020-08-12 17:39:09.118 17697-17697/com.android.stalkerradar I/RadarEnabledActivity: Has location permission granted
2020-08-12 17:39:09.119 17697-17697/com.android.stalkerradar D/BluetoothHandler: Creating Central
2020-08-12 17:39:09.120 17697-17697/com.android.stalkerradar D/BluetoothHandler: Initiating popup hack
2020-08-12 17:39:09.120 17697-17697/com.android.stalkerradar D/BluetoothCentral: Not on a Samung device...hack needed
2020-08-12 17:39:09.123 17697-17697/com.android.stalkerradar I/BluetoothHandler: Alive and about to scan for Stalker Pro IIs 1019
2020-08-12 17:39:09.123 17697-17697/com.android.stalkerradar D/BluetoothAdapter: isLeEnabled(): ON
2020-08-12 17:39:09.125 17697-17744/com.android.stalkerradar D/BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=7 mScannerId=0
2020-08-12 17:39:09.127 17697-17697/com.android.stalkerradar I/BluetoothCentral: scan started
2020-08-12 17:39:09.358 17697-17697/com.android.stalkerradar I/BluetoothHandler$bluetoothCentralCallback: Found peripheral Stalker Pro IIs 1019
2020-08-12 17:39:09.358 17697-17697/com.android.stalkerradar D/BluetoothAdapter: isLeEnabled(): ON
2020-08-12 17:39:09.360 17697-17697/com.android.stalkerradar I/BluetoothCentral: scan stopped
2020-08-12 17:39:09.371 17697-17782/com.android.stalkerradar D/FA: Connected to remote service
2020-08-12 17:39:09.463 17697-17697/com.android.stalkerradar I/BluetoothPeripheral: connect to 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B) using TRANSPORT_LE
2020-08-12 17:39:09.464 17697-17697/com.android.stalkerradar D/BluetoothGatt: connect() - device: 00:A0:50:30:C9:6B, auto: false
2020-08-12 17:39:09.464 17697-17697/com.android.stalkerradar D/BluetoothGatt: registerApp()
2020-08-12 17:39:09.464 17697-17697/com.android.stalkerradar D/BluetoothGatt: registerApp() - UUID=623b0bf7-061a-45b0-bc85-52ed6ea482e9
2020-08-12 17:39:09.468 17697-17744/com.android.stalkerradar D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
2020-08-12 17:39:09.789 17697-17697/com.android.stalkerradar D/SelectRadarGunActivity: BLE: ScanDeviceActivity onStop()
2020-08-12 17:39:09.789 17697-17697/com.android.stalkerradar D/BluetoothAdapter: isLeEnabled(): ON
2020-08-12 17:39:09.789 17697-17697/com.android.stalkerradar D/BluetoothLeScanner: could not find callback wrapper
2020-08-12 17:39:10.124 17697-17697/com.android.stalkerradar D/BluetoothCentral: popup hack completed
2020-08-12 17:39:10.178 17697-17744/com.android.stalkerradar D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=7 device=00:A0:50:30:C9:6B
2020-08-12 17:39:10.180 17697-17744/com.android.stalkerradar I/BluetoothPeripheral: connected to 'Stalker Pro IIs 1019' (BOND_BONDED) in 0.7s
2020-08-12 17:39:10.182 17697-17697/com.android.stalkerradar D/BluetoothPeripheral: discovering services of 'Stalker Pro IIs 1019' with delay of 0 ms
2020-08-12 17:39:10.182 17697-17697/com.android.stalkerradar D/BluetoothGatt: discoverServices() - device: 00:A0:50:30:C9:6B
2020-08-12 17:39:10.484 17697-17697/com.android.stalkerradar D/BluetoothPeripheral: starting bonding with 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B)
2020-08-12 17:39:10.490 17697-17697/com.android.stalkerradar D/BluetoothPeripheral: bonded with 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B)
2020-08-12 17:39:10.491 17697-17697/com.android.stalkerradar D/BluetoothPeripheral: discovering services of 'Stalker Pro IIs 1019' with delay of 0 ms
2020-08-12 17:39:10.491 17697-17697/com.android.stalkerradar D/BluetoothGatt: discoverServices() - device: 00:A0:50:30:C9:6B
2020-08-12 17:39:10.925 17697-17744/com.android.stalkerradar D/BluetoothGatt: onConnectionUpdated() - Device=00:A0:50:30:C9:6B interval=6 latency=0 timeout=500 status=0
2020-08-12 17:39:40.582 17697-17744/com.android.stalkerradar D/BluetoothGatt: onSearchComplete() = Device=00:A0:50:30:C9:6B Status=0
2020-08-12 17:39:40.584 17697-17744/com.android.stalkerradar I/BluetoothPeripheral: discovered 0 services for 'Stalker Pro IIs 1019'
2020-08-12 17:39:40.587 17697-17744/com.android.stalkerradar D/BluetoothGatt: onClientConnectionState() - status=22 clientIf=7 device=00:A0:50:30:C9:6B
2020-08-12 17:39:40.587 17697-17697/com.android.stalkerradar I/BluetoothHandler$bluetoothCentralCallback: connected to 'Stalker Pro IIs 1019'
2020-08-12 17:39:40.587 17697-17697/com.android.stalkerradar I/BluetoothHandler$peripheralCallback: discovered services
2020-08-12 17:39:40.588 17697-17697/com.android.stalkerradar E/BluetoothPeripheral: cannot request MTU, peripheral not connected
2020-08-12 17:39:40.589 17697-17744/com.android.stalkerradar I/BluetoothPeripheral: peripheral 'Stalker Pro IIs 1019' disconnected with status 'GATT CONN TERMINATE LOCAL HOST' before completing service discovery
2020-08-12 17:39:40.589 17697-17744/com.android.stalkerradar D/BluetoothGatt: close()
2020-08-12 17:39:40.589 17697-17744/com.android.stalkerradar D/BluetoothGatt: unregisterApp() - mClientIf=7
2020-08-12 17:39:40.592 17697-17744/com.android.stalkerradar I/BluetoothCentral: retrying connection to 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B)
2020-08-12 17:39:40.694 17697-17697/com.android.stalkerradar I/BluetoothPeripheral: connect to 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B) using TRANSPORT_LE
2020-08-12 17:39:40.705 17697-17697/com.android.stalkerradar D/BluetoothGatt: connect() - device: 00:A0:50:30:C9:6B, auto: false
2020-08-12 17:39:40.705 17697-17697/com.android.stalkerradar D/BluetoothGatt: registerApp()
2020-08-12 17:39:40.705 17697-17697/com.android.stalkerradar D/BluetoothGatt: registerApp() - UUID=5e6c029f-deec-4834-ae54-b2c1edf07842
2020-08-12 17:39:40.707 17697-17744/com.android.stalkerradar D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
2020-08-12 17:40:10.711 17697-17744/com.android.stalkerradar D/BluetoothGatt: onClientConnectionState() - status=133 clientIf=7 device=00:A0:50:30:C9:6B
2020-08-12 17:40:10.712 17697-17744/com.android.stalkerradar I/BluetoothPeripheral: connection failed with status 'GATT ERROR' (TIMEOUT)
2020-08-12 17:40:10.712 17697-17744/com.android.stalkerradar D/BluetoothGatt: close()
2020-08-12 17:40:10.712 17697-17744/com.android.stalkerradar D/BluetoothGatt: unregisterApp() - mClientIf=7
2020-08-12 17:40:10.717 17697-17744/com.android.stalkerradar I/BluetoothCentral: connection to 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B) failed
2020-08-12 17:40:10.719 17697-17697/com.android.stalkerradar E/BluetoothHandler$bluetoothCentralCallback: connection 'Stalker Pro IIs 1019' failed with status 8

Is there anything I could be doing to cause this? Some implementation detail I missed perhaps?

Again though, it works perfectly if I go into setting, forget the device, fire up the app and let it pair. It just fails if I have already paired.

Logo Proposal

Hi
Just came across your cool project, As logo/icon designer who loves utilize my design skills to help contribute to awesome open source projects, I want to help contribute by creating a LOGO for your project...

Already working on some logo idea concepts... I will post it here once I complete it, so you can give me your feedback on any adjustment you may want...

Regards...

writeCharacteristic fails

Hello !

Glad I found this library. Great job !

I added this simple function in BluetoothHandler.java... but the write operation fails.
I checked the UUID, and it's good.
I can write it with some BluetoothScanner app.
What be wrong ?

public void setValue(byte value) {

        BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361b26a8"), PROPERTY_WRITE, 0);

        central.getConnectedPeripherals().get(0).writeCharacteristic(characteristic, new byte[]{0}, WRITE_TYPE_DEFAULT);

 }

Here is the trace :


2020-09-09 00:50:54.626 19806-19806/com.welie.blessedexample D/BluetoothAdapter: STATE_ON
2020-09-09 00:50:54.626 19806-19806/com.welie.blessedexample D/BluetoothAdapter: STATE_ON
2020-09-09 00:50:54.627 19806-19806/com.welie.blessedexample D/BluetoothAdapter: STATE_ON
2020-09-09 00:50:54.627 19806-19806/com.welie.blessedexample D/BluetoothAdapter: BLE support array set: 111111
2020-09-09 00:50:54.627 19806-19806/com.welie.blessedexample D/BluetoothLeScanner: Start Scan with callback
2020-09-09 00:50:54.630 19806-19832/com.welie.blessedexample D/BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=4 mScannerId=0
2020-09-09 00:50:54.634 19806-19806/com.welie.blessedexample I/BluetoothCentral: scan started
2020-09-09 00:50:54.650 19806-19806/com.welie.blessedexample D/ViewRootImpl@347c263[MainActivity]: setView = com.android.internal.policy.DecorView@65ea000 TM=true MM=false
2020-09-09 00:50:54.692 19806-19806/com.welie.blessedexample D/ViewRootImpl@347c263[MainActivity]: Relayout returned: old=(0,0,1080,2280) new=(0,0,1080,2280) req=(1080,2280)0 dur=6 res=0x7 s={true 540908756992} ch=true
2020-09-09 00:50:54.692 19806-19848/com.welie.blessedexample D/OpenGLRenderer: createReliableSurface : 0x7d5d41d0c0(0x7df0aca000)
2020-09-09 00:50:54.703 19806-19848/com.welie.blessedexample D/OpenGLRenderer: makeCurrent EglSurface : 0x0 -> 0x0
2020-09-09 00:50:54.708 19806-19848/com.welie.blessedexample I/mali_winsys: new_window_surface() [1080x2280] return: 0x3000
2020-09-09 00:50:54.716 19806-19848/com.welie.blessedexample D/OpenGLRenderer: makeCurrent EglSurface : 0x0 -> 0x7d5d410800
2020-09-09 00:50:54.718 19806-19848/com.welie.blessedexample W/Gralloc3: mapper 3.x is not supported
2020-09-09 00:50:54.721 19806-19848/com.welie.blessedexample I/gralloc: Arm Module v1.0
2020-09-09 00:50:54.801 19806-19806/com.welie.blessedexample D/ViewRootImpl@347c263[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1 1
2020-09-09 00:50:54.802 19806-19806/com.welie.blessedexample D/InputMethodManager: prepareNavigationBarInfo() DecorView@65ea000[MainActivity]
2020-09-09 00:50:54.802 19806-19806/com.welie.blessedexample D/InputMethodManager: getNavigationBarColor() -14538930
2020-09-09 00:50:54.816 19806-19806/com.welie.blessedexample D/InputMethodManager: prepareNavigationBarInfo() DecorView@65ea000[MainActivity]
2020-09-09 00:50:54.817 19806-19806/com.welie.blessedexample D/InputMethodManager: getNavigationBarColor() -14538930
2020-09-09 00:50:54.817 19806-19806/com.welie.blessedexample V/InputMethodManager: Starting input: tba=com.welie.blessedexample ic=null mNaviBarColor -14538930 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false
2020-09-09 00:50:54.817 19806-19806/com.welie.blessedexample D/InputMethodManager: startInputInner - Id : 0
2020-09-09 00:50:54.817 19806-19806/com.welie.blessedexample I/InputMethodManager: startInputInner - mService.startInputOrWindowGainedFocus
2020-09-09 00:50:54.844 19806-19806/com.welie.blessedexample D/ViewRootImpl@347c263[MainActivity]: MSG_RESIZED: frame=(0,0,1080,2280) ci=(0,117,0,144) vi=(0,117,0,144) or=1
2020-09-09 00:50:54.857 19806-19806/com.welie.blessedexample I/BluetoothHandler: Found peripheral 'SmartLCD'
2020-09-09 00:50:54.859 19806-19806/com.welie.blessedexample D/BluetoothAdapter: STATE_ON
2020-09-09 00:50:54.859 19806-19806/com.welie.blessedexample D/BluetoothLeScanner: Stop Scan with callback
2020-09-09 00:50:54.862 19806-19806/com.welie.blessedexample I/BluetoothCentral: scan stopped
2020-09-09 00:50:54.872 19806-19806/com.welie.blessedexample D/InputMethodManager: prepareNavigationBarInfo() DecorView@65ea000[MainActivity]
2020-09-09 00:50:54.872 19806-19806/com.welie.blessedexample D/InputMethodManager: getNavigationBarColor() -14538930
2020-09-09 00:50:54.873 19806-19806/com.welie.blessedexample V/InputMethodManager: Starting input: tba=com.welie.blessedexample ic=null mNaviBarColor -14538930 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false
2020-09-09 00:50:54.873 19806-19806/com.welie.blessedexample D/InputMethodManager: startInputInner - Id : 0
2020-09-09 00:50:54.972 19806-19806/com.welie.blessedexample I/BluetoothPeripheral: connect to 'SmartLCD' (30:AE:A4:99:85:CA) using TRANSPORT_LE
2020-09-09 00:50:54.975 19806-19806/com.welie.blessedexample D/BluetoothAdapter: STATE_ON
2020-09-09 00:50:54.977 19806-19806/com.welie.blessedexample D/BluetoothGatt: connect() - device: 30:AE:A4:99:85:CA, auto: false
2020-09-09 00:50:54.977 19806-19806/com.welie.blessedexample D/BluetoothAdapter: isSecureModeEnabled
2020-09-09 00:50:54.977 19806-19806/com.welie.blessedexample D/BluetoothGatt: registerApp()
2020-09-09 00:50:54.978 19806-19806/com.welie.blessedexample D/BluetoothGatt: registerApp() - UUID=688f6eed-2347-4dda-a8fa-852b8d6cee69
2020-09-09 00:50:54.980 19806-19832/com.welie.blessedexample D/BluetoothGatt: onClientRegistered() - status=0 clientIf=4
2020-09-09 00:50:55.224 19806-19832/com.welie.blessedexample D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=4 device=30:AE:A4:99:85:CA
2020-09-09 00:50:55.228 19806-19832/com.welie.blessedexample I/BluetoothPeripheral: connected to 'SmartLCD' (BOND_NONE) in 0,2s
2020-09-09 00:50:55.231 19806-19806/com.welie.blessedexample D/BluetoothPeripheral: discovering services of 'SmartLCD' with delay of 0 ms
2020-09-09 00:50:55.231 19806-19806/com.welie.blessedexample D/BluetoothGatt: discoverServices() - device: 30:AE:A4:99:85:CA
2020-09-09 00:50:55.708 19806-19832/com.welie.blessedexample D/BluetoothGatt: onConnectionUpdated() - Device=30:AE:A4:99:85:CA interval=6 latency=0 timeout=500 status=0
2020-09-09 00:50:55.928 19806-19832/com.welie.blessedexample D/BluetoothGatt: onSearchComplete() = Device=30:AE:A4:99:85:CA Status=0
2020-09-09 00:50:55.930 19806-19832/com.welie.blessedexample I/BluetoothPeripheral: discovered 3 services for 'SmartLCD'
2020-09-09 00:50:55.931 19806-19806/com.welie.blessedexample I/BluetoothHandler: connected to 'SmartLCD'
2020-09-09 00:50:55.931 19806-19806/com.welie.blessedexample I/BluetoothHandler: discovered services
2020-09-09 00:50:55.932 19806-19806/com.welie.blessedexample D/BluetoothGatt: configureMTU() - device: 30:AE:A4:99:85:CA mtu: 185
2020-09-09 00:50:55.948 19806-19832/com.welie.blessedexample D/BluetoothGatt: onConfigureMTU() - Device=30:AE:A4:99:85:CA mtu=185 status=0
2020-09-09 00:50:55.948 19806-19806/com.welie.blessedexample I/BluetoothHandler: new MTU set: 185
2020-09-09 00:50:55.948 19806-19806/com.welie.blessedexample D/BluetoothGatt: requestConnectionPriority() - params: 1
2020-09-09 00:50:55.950 19806-19806/com.welie.blessedexample D/BluetoothPeripheral: requesting connection priority 1
2020-09-09 00:50:56.032 19806-19832/com.welie.blessedexample D/BluetoothGatt: onConnectionUpdated() - Device=30:AE:A4:99:85:CA interval=39 latency=0 timeout=500 status=0
2020-09-09 00:50:56.580 19806-19832/com.welie.blessedexample D/BluetoothGatt: onConnectionUpdated() - Device=30:AE:A4:99:85:CA interval=9 latency=0 timeout=500 status=0
2020-09-09 00:51:04.153 19806-19806/com.welie.blessedexample D/ViewRootImpl@347c263[MainActivity]: ViewPostIme pointer 0
2020-09-09 00:51:04.249 19806-19806/com.welie.blessedexample D/ViewRootImpl@347c263[MainActivity]: ViewPostIme pointer 1
2020-09-09 00:51:04.253 19806-19806/com.welie.blessedexample D/MainActivity: onClickMode
2020-09-09 00:51:04.254 19806-19806/com.welie.blessedexample D/MainActivity: lcdMode sent : 0
2020-09-09 00:51:04.255 19806-19806/com.welie.blessedexample E/BluetoothPeripheral: writeCharacteristic failed for characteristic: beb5483e-36e1-4688-b7f5-ea07361b26a9

writeCharacteristic Success but not received on target device

Dear Martijn. I use the following command sequence:
val parserValue1 = BluetoothBytesParser()
parserValue1.setIntValue(1, FORMAT_UINT8)
//parserValue1.setString("01", FORMAT_UINT8)
tagPeripheral.writeCharacteristic(tagCharacteristicList[1], parserValue1.value ,BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT)

The tagCharacteristic list is what I get from:
val tagCharacteristicList: MutableList = tagService.characteristics

LogCat shows on this writeCharacteristic command, from callback:
2020-07-15 06:45:08.346 22426-22426/com.itesseract.smartTag D/BluetoothPeripheral: writing <01> to characteristic <00002b29-0000-1000-8000-00805f9b34fb>
2020-07-15 06:45:08.352 5801-5913/? V/MARsPolicyManager: onAlertToastWindowStarted pkgName = com.itesseract.smartTag, userId = 0
2020-07-15 06:45:08.355 22426-22426/com.itesseract.smartTag D/ViewRootImpl@285206b[Toast]: setView = android.widget.LinearLayout{5197c8 V.E...... ......I. 0,0-0,0} TM=true MM=false
2020-07-15 06:45:08.355 22426-22426/com.itesseract.smartTag V/Toast: Text: Twit in android.widget.Toast$TN@bacc061
2020-07-15 06:45:08.367 22426-22426/com.itesseract.smartTag D/ViewRootImpl@285206b[Toast]: Relayout returned: old=[0,110][1080,2154] new=[86,1827][993,1986] req=(907,159)0 dur=6 res=0x7 s={true 487576141824} ch=true
2020-07-15 06:45:08.367 22426-22456/com.itesseract.smartTag D/OpenGLRenderer: createReliableSurface : 0x71eb96f140, 0x7185cd8000
2020-07-15 06:45:08.369 22426-22456/com.itesseract.smartTag I/mali_winsys: new_window_surface() [907x159] return: 0x3000
2020-07-15 06:45:08.372 22426-22456/com.itesseract.smartTag D/OpenGLRenderer: SurfaceChanged : 0x71eb9ae300 -> 0x727a462980
2020-07-15 06:45:08.384 22426-22426/com.itesseract.smartTag D/ViewRootImpl@285206b[Toast]: MSG_RESIZED: frame=[86,1827][993,1986] ci=[0,0][0,0] vi=[0,0][907,159] or=1
2020-07-15 06:45:08.416 22426-22426/com.itesseract.smartTag I/BluetoothHandler$peripheralCallback: SUCCESS: Writing <01> to <00002b29-0000-1000-8000-00805f9b34fb>

So:

  • Blessed callback says received OK.
  • Callback on nrf52 do not get triggered. Does not show receive.
  • I can use Blue Light app from punchthrough, send hex 01 and 00, same nrf device and code. It changes LED. It works.

I guess it is how I make up the packet with Blessed, I tried the other formats in BluetoothParser, string, long, UINT and SINT, 8 to 32 bits, offsets, same result.

Is there anything you can suggest? Please help.
Jakes

Bluetooth On/Off and reconnections

First of all, congratulations on your library. It certainly makes working with Ble much easier.

On the topic:

My use case relies on sending specific packets to the ble device before succesfully disconnecting (I assume its not a rare case) so i need to take in account some user behaviour like turning off BT on purpose to try to turn it on again and reconnect.

Have you considered exposing the On/Off status from the adapterStateReceiver to the BluetoothCentralCallback?

Not getting onCharacteristicUpdate callback with Bluno Beetle

I have a Samsung Galaxy S7 running Android 8, and trying to read from a Bluno beetle using the following service UUID and characteristic UUIDs:

private static final UUID REWIRE_SERVICE_UUID = UUID.fromString("0000dfb0-0000-1000-8000-00805f9b34fb");
private static final UUID REWIRE_CHARACTERISTIC_UUID = UUID.fromString("0000dfb1-0000-1000-8000-00805f9b34fb");

It's able to connect to the device and discover the service. However, the characteristic callback is never called for this characteristic.

Within the onServicesDiscovered, I'm setting up the notification like this:

if (peripheral.getService(REWIRE_SERVICE_UUID) != null) {
   peripheral.setNotify(peripheral.getCharacteristic(REWIRE_SERVICE_UUID, REWIRE_CHARACTERISTIC_UUID), true);
}

The only way I can read the characteristic is if I force it like this:
peripheral.readCharacteristic(peripheral.getCharacteristic(REWIRE_SERVICE_UUID, REWIRE_CHARACTERISTIC_UUID));

But I need to get it automatically every time with notifications. I have an iOS app that's able to read the Bluno beetle fine, so something is different either with the Android device, or possibly the library. I'm also able to read heart rate monitors and other devices fine with the Blessed library. Any ideas?

Notifications not working

I have a BLE device that has notifications working for Apple and am using blessed-android to attempt to do the same on an Android device.

Scanning, pairing, service discovery, and the write to turn on the notification service appear to function flawlessly, but no notification is ever received.

Here is some output from a run I did with added logging to help see what the issue may be:

2020-08-02 20:03:58.151 8672-8672/com.welie.blessedexample I/BluetoothPeripheral: connect to 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B) using TRANSPORT_LE
2020-08-02 20:03:58.151 8672-8672/com.welie.blessedexample I/BluetoothPeripheral: connect to 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B) using TRANSPORT_LE
2020-08-02 20:03:58.153 8672-8672/com.welie.blessedexample D/BluetoothGatt: connect() - device: 00:A0:50:30:C9:6B, auto: false
2020-08-02 20:03:58.153 8672-8672/com.welie.blessedexample D/BluetoothGatt: registerApp()
2020-08-02 20:03:58.153 8672-8672/com.welie.blessedexample D/BluetoothGatt: registerApp() - UUID=e552d944-1891-4522-9d24-97a00f53e690
2020-08-02 20:03:58.156 8672-8702/com.welie.blessedexample D/BluetoothGatt: onClientRegistered() - status=0 clientIf=7
2020-08-02 20:03:58.249 8672-8702/com.welie.blessedexample D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=7 device=00:A0:50:30:C9:6B
2020-08-02 20:03:58.254 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: starting bonding with 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B)
2020-08-02 20:03:58.254 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: starting bonding with 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B)
2020-08-02 20:03:58.257 8672-8702/com.welie.blessedexample I/BluetoothPeripheral: connected to 'Stalker Pro IIs 1019' (BOND_BONDING) in 0.1s
2020-08-02 20:03:58.257 8672-8702/com.welie.blessedexample I/BluetoothPeripheral: connected to 'Stalker Pro IIs 1019' (BOND_BONDING) in 0.1s
2020-08-02 20:03:58.257 8672-8702/com.welie.blessedexample I/BluetoothPeripheral: waiting for bonding to complete
2020-08-02 20:03:58.258 8672-8702/com.welie.blessedexample I/BluetoothPeripheral: waiting for bonding to complete
2020-08-02 20:03:58.258 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: pairing request received , pairing variant: PAIRING_VARIANT_CONSENT (3)
2020-08-02 20:03:58.258 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: pairing request received , pairing variant: PAIRING_VARIANT_CONSENT (3)
2020-08-02 20:03:58.713 8672-8705/com.welie.blessedexample D/BluetoothGatt: onConnectionUpdated() - Device=00:A0:50:30:C9:6B interval=6 latency=0 timeout=500 status=0
2020-08-02 20:03:58.878 8672-8672/com.welie.blessedexample D/BluetoothCentral: popup hack completed
2020-08-02 20:03:58.878 8672-8672/com.welie.blessedexample D/BluetoothCentral: popup hack completed
2020-08-02 20:03:59.029 8672-8705/com.welie.blessedexample D/BluetoothGatt: onConnectionUpdated() - Device=00:A0:50:30:C9:6B interval=36 latency=0 timeout=500 status=0
2020-08-02 20:03:59.954 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: pairing request received , pairing variant: PAIRING_VARIANT_PIN (0)
2020-08-02 20:03:59.954 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: pairing request received , pairing variant: PAIRING_VARIANT_PIN (0)
2020-08-02 20:04:08.386 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: bonded with 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B)
2020-08-02 20:04:08.386 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: bonded with 'Stalker Pro IIs 1019' (00:A0:50:30:C9:6B)
2020-08-02 20:04:08.388 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: discovering services of 'Stalker Pro IIs 1019' with delay of 0 ms
2020-08-02 20:04:08.388 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: discovering services of 'Stalker Pro IIs 1019' with delay of 0 ms
2020-08-02 20:04:08.388 8672-8672/com.welie.blessedexample D/BluetoothGatt: discoverServices() - device: 00:A0:50:30:C9:6B
2020-08-02 20:04:08.401 8672-8702/com.welie.blessedexample D/BluetoothGatt: onSearchComplete() = Device=00:A0:50:30:C9:6B Status=0
2020-08-02 20:04:08.407 8672-8702/com.welie.blessedexample I/BluetoothPeripheral: discovered 4 services for 'Stalker Pro IIs 1019'
2020-08-02 20:04:08.407 8672-8702/com.welie.blessedexample I/BluetoothPeripheral: discovered 4 services for 'Stalker Pro IIs 1019'
2020-08-02 20:04:08.408 8672-8672/com.welie.blessedexample I/BluetoothHandler: connected to 'Stalker Pro IIs 1019'
2020-08-02 20:04:08.408 8672-8672/com.welie.blessedexample I/BluetoothHandler: connected to 'Stalker Pro IIs 1019'
2020-08-02 20:04:08.409 8672-8672/com.welie.blessedexample I/BluetoothHandler: discovered services
2020-08-02 20:04:08.409 8672-8672/com.welie.blessedexample I/BluetoothHandler: discovered services
2020-08-02 20:04:08.409 8672-8672/com.welie.blessedexample I/BluetoothHandler: Here is the list of supported services
2020-08-02 20:04:08.409 8672-8672/com.welie.blessedexample I/BluetoothHandler: Here is the list of supported services
2020-08-02 20:04:08.409 8672-8672/com.welie.blessedexample I/BluetoothHandler: Service: 00001800-0000-1000-8000-00805f9b34fb
2020-08-02 20:04:08.409 8672-8672/com.welie.blessedexample I/BluetoothHandler: Service: 00001800-0000-1000-8000-00805f9b34fb
2020-08-02 20:04:08.409 8672-8672/com.welie.blessedexample I/BluetoothHandler: Service: 00001801-0000-1000-8000-00805f9b34fb
2020-08-02 20:04:08.410 8672-8672/com.welie.blessedexample I/BluetoothHandler: Service: 00001801-0000-1000-8000-00805f9b34fb
2020-08-02 20:04:08.410 8672-8672/com.welie.blessedexample I/BluetoothHandler: Service: 4880c12c-fdcb-4077-8920-a450d7f9b907
2020-08-02 20:04:08.410 8672-8672/com.welie.blessedexample I/BluetoothHandler: Service: 4880c12c-fdcb-4077-8920-a450d7f9b907
2020-08-02 20:04:08.410 8672-8672/com.welie.blessedexample I/BluetoothHandler: Service: 0000180a-0000-1000-8000-00805f9b34fb
2020-08-02 20:04:08.410 8672-8672/com.welie.blessedexample I/BluetoothHandler: Service: 0000180a-0000-1000-8000-00805f9b34fb
2020-08-02 20:04:08.410 8672-8672/com.welie.blessedexample I/BluetoothHandler: Attempting to read manufacturer name
2020-08-02 20:04:08.410 8672-8672/com.welie.blessedexample I/BluetoothHandler: Attempting to read manufacturer name
2020-08-02 20:04:08.411 8672-8672/com.welie.blessedexample I/BluetoothHandler: Searching the services list for 4880c12c-fdcb-4077-8920-a450d7f9b907
2020-08-02 20:04:08.411 8672-8672/com.welie.blessedexample I/BluetoothHandler: Searching the services list for 4880c12c-fdcb-4077-8920-a450d7f9b907
2020-08-02 20:04:08.411 8672-8672/com.welie.blessedexample I/BluetoothHandler: Attempting to turn on notifications
2020-08-02 20:04:08.411 8672-8672/com.welie.blessedexample I/BluetoothHandler: Attempting to turn on notifications
2020-08-02 20:04:08.411 8672-8672/com.welie.blessedexample D/BluetoothGatt: requestConnectionPriority() - params: 1
2020-08-02 20:04:08.412 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: requesting connection priority 1
2020-08-02 20:04:08.412 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: requesting connection priority 1
2020-08-02 20:04:08.413 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: reading characteristic <00002a29-0000-1000-8000-00805f9b34fb>
2020-08-02 20:04:08.413 8672-8672/com.welie.blessedexample D/BluetoothPeripheral: reading characteristic <00002a29-0000-1000-8000-00805f9b34fb>
2020-08-02 20:04:08.571 8672-8672/com.welie.blessedexample I/BluetoothHandler: Received manufacturer: Stalker
2020-08-02 20:04:08.571 8672-8672/com.welie.blessedexample I/BluetoothHandler: Received manufacturer: Stalker
2020-08-02 20:04:08.572 8672-8672/com.welie.blessedexample D/BluetoothGatt: setCharacteristicNotification() - uuid: fec26ec4-6d71-4442-9f81-55bc21d658d6 enable: true
2020-08-02 20:04:08.750 8672-8672/com.welie.blessedexample I/BluetoothHandler: SUCCESS: Notify set to 'on' for fec26ec4-6d71-4442-9f81-55bc21d658d6
2020-08-02 20:04:08.751 8672-8672/com.welie.blessedexample I/BluetoothHandler: SUCCESS: Notify set to 'on' for fec26ec4-6d71-4442-9f81-55bc21d658d6
2020-08-02 20:04:08.883 8672-8702/com.welie.blessedexample D/BluetoothGatt: onConnectionUpdated() - Device=00:A0:50:30:C9:6B interval=12 latency=0 timeout=500 status=0

Anything I can do to help you debug this?
Screenshot_20200802-193641
Screenshot_20200802-193858

scanForPeripherals choose from a list?

I am modifying the default example in the library for my application, and I am trying to connect to a UART service example from Nordic. I have a few questions:

// Scan for peripherals with a certain service UUIDs
central.startPairingPopupHack();
central.scanForPeripherals();

What does the startPairingPopupHack do? And when I call the scanForPeripherals, there is no pop up window that allows me to choose which BLE device to connect to.

In the app log, instead I see:
Found peripheral 'null'
scan stopped
peripheral with address XXXXXXXXX is not in the Bluetooth cach, hence connection may fail
connected to 'null' (XXXXXXXXXXX) using TRANSPORT_LE

I want to be able to choose which device to connect to. How can I do that?

Disconnecting from a device

How would you properly disconnect from a periferal?

central.cancelConnection(periferal)

disconnects from the device, but several seconds later device reconnects by itself.
Is that a bug or am i doing something wrong?

Cheers

Walking out and back in range doesn't trigger onCharacteristicUpdate

Upon initial connection, onCharacteristicUpdate is called and I can see the data flowing thru.

When I walk out of range, onDisconnectedPeripheral is called.

When I walk back into range, onConnectedPeripheral is called, onServicesDiscovered is then called, and I again call peripheral.setNotify(myCharacteristic, true);.

onCharacteristicUpdate is not called again upon that reconnect.

Any ideas on how to fix this?

Make BluetoothPeripheral parceable

When i do scan i tried to pass an arraylist of BluetoothPeripheral through intent extra but give error, saying:

java.lang.RuntimeException: Parcel: unable to marshal value com.welie.blessed.BluetoothPeripheral@4cb318e
at android.os.Parcel.writeValue(Parcel.java:1680)
at android.os.Parcel.writeList(Parcel.java:979)
at android.os.Parcel.writeValue(Parcel.java:1627)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:891)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1579)
at android.os.Bundle.writeToParcel(Bundle.java:1233)
at android.os.Parcel.writeBundle(Parcel.java:931)
at android.content.Intent.writeToParcel(Intent.java:10646)
at android.app.IActivityManager$Stub$Proxy.broadcastIntent(IActivityManager.java:3729)
at android.app.ContextImpl.sendBroadcast(ContextImpl.java:1071)
at android.content.ContextWrapper.sendBroadcast(ContextWrapper.java:449)

Maybe it would be good make that class parceable

Scanning returns no results after a few connections

Okay, so my approach is to use scanForPeripherals() and then wait for the results. When I get results, first thing I do is call stopScan() and after that I do connectPeripheral(). Nonetheless, if the connection request failed/succeed I restart my scanning again with scanForPeripherals() and it works okay, but after few scans I don't get any results.
I can see that I successfully start the scanning but thats it.

2019-09-16 12:42:25.798 19002-19038/com.projectX D/BluetoothGatt: onConnectionUpdated() - Device=E6:F6:05:7E:6A:5D interval=40 latency=20 timeout=500 status=0 2019-09-16 12:42:25.800 19002-19410/com.projectX I/BluetoothCentral: scan started 2019-09-16 12:42:28.167 19002-19413/com.projectX I/XBeaconManager: XBeacon recognized! Minor ID: 196 recognized! 2019-09-16 12:42:28.183 19002-19413/com.projectX I/XBeaconManager$saveXBeacon: Saving XBeacon: 196 minorId! 2019-09-16 12:42:28.210 19002-19413/com.projectX I/IBDatabaseHelper: Beacon saved to DB: majorId - 0 minorId - 196 2019-09-16 12:42:28.337 19002-19412/com.projectX I/XBeaconManager: XBeacon recognized! Minor ID: 37 recognized! 2019-09-16 12:42:28.371 19002-19412/com.projectX I/XBeaconManager: XBeacon is trying to create a connection! Minor ID: 37! 2019-09-16 12:42:28.382 19002-19412/com.projectX D/BluetoothAdapter: STATE_ON 2019-09-16 12:42:28.383 19002-19412/com.projectX D/BluetoothLeScanner: Stop Scan with callback 2019-09-16 12:42:28.385 19002-19412/com.projectX I/BluetoothCentral: scan stopped 2019-09-16 12:42:33.395 19002-19002/com.projectX I/BluetoothPeripheral: connect to 'null' (D4:5B:88:FC:89:40) using TRANSPORT_LE 2019-09-16 12:42:33.397 19002-19002/com.projectX I/BluetoothDevice: removeBond() for device D45B88 called by pid: 19002 tid: 19002 2019-09-16 12:42:33.411 19002-19002/com.projectX D/BluetoothAdapter: STATE_ON 2019-09-16 12:42:33.415 19002-19002/com.projectX D/BluetoothGatt: connect() - device: D4:5B:88:FC:89:40, auto: false 2019-09-16 12:42:33.415 19002-19002/com.projectX D/BluetoothAdapter: isSecureModeEnabled 2019-09-16 12:42:33.416 19002-19002/com.projectX D/BluetoothGatt: registerApp() 2019-09-16 12:42:33.418 19002-19002/com.projectX D/BluetoothGatt: registerApp() - UUID=305fc72e-99c0-456c-8036-1c41f9e5c030 2019-09-16 12:42:33.422 19002-19002/com.projectX D/BluetoothGatt: refresh() - device: D4:5B:88:FC:89:40 2019-09-16 12:42:33.424 19002-19018/com.projectX D/BluetoothGatt: onClientRegistered() - status=0 clientIf=20 2019-09-16 12:42:38.386 19002-19018/com.projectX D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=20 device=D4:5B:88:FC:89:40 2019-09-16 12:42:38.403 19002-19018/com.projectX I/BluetoothPeripheral: connected to 'D4:5B:88:FC:89:40' (BOND_NONE) in 5,0s 2019-09-16 12:42:38.407 19002-19002/com.projectX D/BluetoothPeripheral: discovering services of 'null' with delay of 0 ms 2019-09-16 12:42:38.407 19002-19002/com.projectX D/BluetoothGatt: discoverServices() - device: D4:5B:88:FC:89:40 2019-09-16 12:42:39.228 19002-19018/com.projectX D/BluetoothGatt: onConnectionUpdated() - Device=D4:5B:88:FC:89:40 interval=6 latency=0 timeout=500 status=0 2019-09-16 12:42:39.476 19002-19018/com.projectX D/BluetoothGatt: onSearchComplete() = Device=D4:5B:88:FC:89:40 Status=0 2019-09-16 12:42:39.480 19002-19018/com.projectX I/BluetoothPeripheral: discovered 5 services for 'null' 2019-09-16 12:42:39.482 19002-19002/com.projectX I/XBeaconManager: discovered services 2019-09-16 12:42:39.505 19002-19412/com.projectX I/XBeaconManager$bluetoothCentralCallback$1$onConnectedPeripheral: XBeacon connected! Minor ID: 37! Updating... 2019-09-16 12:42:39.524 19002-19018/com.projectX D/BluetoothGatt: onConnectionUpdated() - Device=D4:5B:88:FC:89:40 interval=40 latency=20 timeout=500 status=0 2019-09-16 12:42:39.526 19002-19412/com.projectX I/XBeaconManager: Restarting XBeacon Manager 2019-09-16 12:42:39.534 19002-19412/com.projectX D/BluetoothAdapter: STATE_ON 2019-09-16 12:42:39.535 19002-19412/com.projectX D/BluetoothLeScanner: could not find callback wrapper 2019-09-16 12:42:39.535 19002-19412/com.projectX I/BluetoothCentral: scan stopped 2019-09-16 12:42:39.538 19002-19412/com.projectX D/BluetoothAdapter: STATE_ON 2019-09-16 12:42:39.539 19002-19412/com.projectX D/BluetoothAdapter: STATE_ON 2019-09-16 12:42:39.540 19002-19412/com.projectX D/BluetoothLeScanner: Start Scan with callback 2019-09-16 12:42:39.543 19002-19018/com.projectX D/BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=24 mScannerId=0 2019-09-16 12:42:39.548 19002-19412/com.projectX I/BluetoothCentral: scan started 2019-09-16 12:42:41.532 19002-19410/com.projectX I/XBeaconManager: XBeacon recognized! Minor ID: 196 recognized! 2019-09-16 12:42:41.554 19002-19410/com.projectX I/XBeaconManager: XBeacon is trying to create a connection! Minor ID: 196! 2019-09-16 12:42:41.565 19002-19410/com.projectX D/BluetoothAdapter: STATE_ON 2019-09-16 12:42:41.565 19002-19410/com.projectX D/BluetoothLeScanner: Stop Scan with callback 2019-09-16 12:42:41.568 19002-19410/com.projectX I/BluetoothCentral: scan stopped 2019-09-16 12:42:46.584 19002-19002/com.projectX I/BluetoothPeripheral: connect to 'null' (EC:29:F0:D6:F1:25) using TRANSPORT_LE 2019-09-16 12:42:46.588 19002-19002/com.projectX I/BluetoothDevice: removeBond() for device EC29F0 called by pid: 19002 tid: 19002 2019-09-16 12:42:46.618 19002-19002/com.projectX D/BluetoothAdapter: STATE_ON 2019-09-16 12:42:46.622 19002-19002/com.projectX D/BluetoothGatt: connect() - device: EC:29:F0:D6:F1:25, auto: false 2019-09-16 12:42:46.622 19002-19002/com.projectX D/BluetoothAdapter: isSecureModeEnabled 2019-09-16 12:42:46.623 19002-19002/com.projectX D/BluetoothGatt: registerApp() 2019-09-16 12:42:46.626 19002-19002/com.projectX D/BluetoothGatt: registerApp() - UUID=6834a9a4-8054-47f6-b808-cdb8f6ca15f3 2019-09-16 12:42:46.631 19002-19002/com.projectX D/BluetoothGatt: refresh() - device: EC:29:F0:D6:F1:25 2019-09-16 12:42:46.631 19002-19018/com.projectX D/BluetoothGatt: onClientRegistered() - status=0 clientIf=24 2019-09-16 12:42:48.235 19002-19018/com.projectX D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=24 device=EC:29:F0:D6:F1:25 2019-09-16 12:42:48.257 19002-19018/com.projectX I/BluetoothPeripheral: connected to 'EC:29:F0:D6:F1:25' (BOND_NONE) in 1,6s 2019-09-16 12:42:48.262 19002-19002/com.projectX D/BluetoothPeripheral: discovering services of 'null' with delay of 0 ms 2019-09-16 12:42:48.262 19002-19002/com.projectX D/BluetoothGatt: discoverServices() - device: EC:29:F0:D6:F1:25 2019-09-16 12:42:49.070 19002-19018/com.projectX D/BluetoothGatt: onConnectionUpdated() - Device=EC:29:F0:D6:F1:25 interval=6 latency=0 timeout=500 status=0 2019-09-16 12:42:49.329 19002-19018/com.projectX D/BluetoothGatt: onSearchComplete() = Device=EC:29:F0:D6:F1:25 Status=0 2019-09-16 12:42:49.333 19002-19018/com.projectX I/BluetoothPeripheral: discovered 5 services for 'null' 2019-09-16 12:42:49.335 19002-19002/com.projectX I/XBeaconManager: discovered services 2019-09-16 12:42:49.359 19002-19415/com.projectX I/XBeaconManager$bluetoothCentralCallback$1$onConnectedPeripheral: XBeacon connected! Minor ID: 196! Updating... 2019-09-16 12:42:49.371 19002-19415/com.projectX I/XBeaconManager: Restarting XBeacon Manager 2019-09-16 12:42:49.377 19002-19415/com.projectX D/BluetoothAdapter: STATE_ON 2019-09-16 12:42:49.377 19002-19415/com.projectX D/BluetoothLeScanner: could not find callback wrapper 2019-09-16 12:42:49.378 19002-19415/com.projectX I/BluetoothCentral: scan stopped 2019-09-16 12:42:49.380 19002-19415/com.projectX D/BluetoothAdapter: STATE_ON 2019-09-16 12:42:49.381 19002-19415/com.projectX D/BluetoothAdapter: STATE_ON 2019-09-16 12:42:49.381 19002-19415/com.projectX D/BluetoothLeScanner: Start Scan with callback 2019-09-16 12:42:49.385 19002-19018/com.projectX D/BluetoothLeScanner: onScannerRegistered() - status=0 scannerId=25 mScannerId=0 2019-09-16 12:42:49.394 19002-19415/com.projectX I/BluetoothCentral: scan started 2019-09-16 12:42:49.415 19002-19018/com.projectX D/BluetoothGatt: onConnectionUpdated() - Device=EC:29:F0:D6:F1:25 interval=40 latency=20 timeout=500 status=0 2019-09-16 12:43:24.828 19002-19017/com.projectX I/com.projectX: Background concurrent copying GC freed 147945(5MB) AllocSpace objects, 4(208KB) LOS objects, 49% free, 6MB/12MB, paused 494us total 159.860ms 2019-09-16 12:43:28.044 19002-19416/com.projectX I/XBeaconManager: XBeacon recognized! Minor ID: 0 recognized!

Retry mechanism isn't working correctly

I haven't used the pull requests yet, so that's why i'm posting it here.
The retry mechanism starts a nextCommand, but nextCommand sets the retry count to 0, this should only set the retry count to 0 when it's not a retry message.

/**
 * Execute the next command in the subscribe queue.
 * A queue is used because the calls have to be executed sequentially.
 * If the read or write fails, the next command in the queue is executed.
 */
private void nextCommand() {
    // Make sure only one thread can execute this method
    synchronized (this) {
        // If there is still a command being executed then bail out
        if (commandQueueBusy) {
            return;
        }

        // Check if we still have a valid gatt object
        if (bluetoothGatt == null) {
            Timber.e("gatt is 'null' for peripheral '%s', clearing command queue", getAddress());
            commandQueue.clear();
            commandQueueBusy = false;
            return;
        }

        // Execute the next command in the queue
        final Runnable bluetoothCommand = commandQueue.peek();
        if (bluetoothCommand != null) {
            commandQueueBusy = true;

if(!isRetrying)
nrTries = 0;

IllegalArgumentException: Receiver not registered

Hello! Thanks for this hard work.
Your library works great. This makes using BLE easier for me.
But sometimes I come across this problem: java.lang.IllegalArgumentException: Receiver not registered.
One of several method sequences is as follows: BluetoothCentral.cancelAllConnectionsWhenBluetoothOff -> BluetoothPeripheral.disconnectWhenBluetoothOff -> BluetoothPeripheral.completeDisconnect -> android.content.ContextWrapper.unregisterReceiver -> android.app.ContextImpl.unregisterReceiver -> android.app.LoadedApk.forgetReceiverDispatcher -> java.lang.IllegalArgumentException: Receiver not registered.
Please can you investigate this case? Perhaps you just need to add a try/catch block to the BluetoothPeripheral.completeDisconnect method when calling Context.unregisterReceiver.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.