nordicsemiconductor / android-ble-library Goto Github PK
View Code? Open in Web Editor NEWA library that makes working with Bluetooth LE on Android a pleasure. Seriously.
License: BSD 3-Clause "New" or "Revised" License
A library that makes working with Bluetooth LE on Android a pleasure. Seriously.
License: BSD 3-Clause "New" or "Revised" License
The Android Jetpack is stable now. This lib would only use the annotations from AndroidX.
Importing the lib as a module to projects already migrated requires the lib also to be migrated.
Hi,
I ran into the mentioned issue using version 1.2.0 of the library. The app is running on a Nexus 5 with Android 8.1.
I'm trying to connect to a nRF52840 dongle, then bond. After bonding I want to change MTU size and write some characteristics on the device.
The flow in details:
BleManager.connect(BluetoothDevice)
BleManagerGattCallback.initGatt
implementation, I push a single bond request (Request.createBond()
) into the requests queueBleManageCallbacks.onBondingRequired(BluetoothDevice)
is invoked, Android pops up the Pairing notification, where I choose to pair. In the nRF Connect app, I also confirm that the pins match.BleManagerCallbacks.onBonded(BluetoothDevice)
is invoked. In my implementation I enqueue a new MTU change request here: enqueue(Request.newMtuRequest(128))
The request never gets processed since the BleManager.BleManagerGattCallback.mOperationInProgress
flag is still true
.
I actually checked out the source of the library and modified the BleManager
implementation to reset the mOperationInProgress
flag to false
on successful bonding in the BroadcastReceiver
's BOND_BONDED
case:
Logger.i(mLogSession, "Device bonded");
mGattCallback.mOperationInProgress = false; // added this line
mCallbacks.onBonded(device);
// If the device started to pair just after the connection was established the services were not discovered.
if (mBluetoothGatt.getServices().isEmpty()) {
mHandler.post(() -> {
Logger.v(mLogSession, "Discovering Services...");
Logger.d(mLogSession, "gatt.discoverServices()");
mBluetoothGatt.discoverServices();
});
return;
}
break;
With the modifications above I managed to run the MTU change and other requests after bonding.
Is my solution valid or did I do something wrong in my intitial flow?
Thanks in advance!
We are sometimes getting the following stack trace if we turn off bluetooth while communicating with a device:
no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.nextRequest(boolean)' on a null object reference
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.access$1300(BleManager.java:2071)
at no.nordicsemi.android.ble.BleManager.internalDisconnect(BleManager.java:869)
at no.nordicsemi.android.ble.BleManager.onRequestTimeout(BleManager.java:2056)
at no.nordicsemi.android.ble.TimeoutableRequest.lambda$notifyStarted$0(TimeoutableRequest.java:188)
at no.nordicsemi.android.ble.-$$Lambda$TimeoutableRequest$LRW3H3z9m1CuZHgzj67Qxd_-s8Y.run(lambda)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6816)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1563)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1451)
I'm trying to disconnect from a device with a connection attempt in progress, but apparently the disconnect is never executed (I never receive any callback) and the autoConnect=true causes an undesired reconnect attempt
Steps
disconnect()
.done { Timber.d("disconnect success") }
.fail { device, status ->
Timber.d("disconnect fail")
close()
}
.enqueue()
Is this working as intended or is it a bug?
As a user, I'd like to choose the logging framework on my own.
Hello,
I'm using we are using your library for managing my BT connections and mostly it is working great. But I seem to run into some problems with the bonding process. It seems like the enqueue gets two callbacks, done and fail.
In short what happens is, I connect, create a bond, get success (done). I then disconnect and remove the bond and receive a fail.
I added a random number to log to just clarify I'm not calling the function twice.
D/RxBt: createBond 0.6858416588166597
I/BluetoothDevice: createBond() for device 91:3 called by pid: 623 tid: 623
E/RxBt: Bonding required
E/RxBt: Bonded!
D/RxBt: Already Bond success 0.6858416588166597
D/BluetoothDevice: bond, retrieved method: public boolean android.bluetooth.BluetoothDevice.removeBond()
I/BluetoothDevice: removeBond() for device 91:3 called by pid: 623 tid: 623
D/RxBt: Already Bond Fail 0.6858416588166597
Great to see all this code in a separate repo! I'll be migrating to it ASAP.
One feature request though: it would be great to see some integration with the bond management service so that I can request the deletion of the current bond with deleteBond() or some such method.
Hi,
As you may have seen, most of the methods in the BleManager
are package protected and final. My intention was to allow the final user to define the their manager's API without bringing all other methods with it. For example, the MySuperCoolManager extends BleManager
would have a method enableFancyLED()
, bond()
, etc. and internal methods, like writeNotification
would not be visible from outside. There are 2 methods exposed: connect(..)
and disconnect(..)
, but not more.
The question is: is it a good idea, or does it make more troubles than good?
There are 3 solutions:
As I'm thinking now, making them non-final is the best idea. Some methods could be made public by overriding them without actually changing functionality.
CC: @eliotstock, @maragues-kolibree, @sztomek, @balazsnemeth, @balazsnemeth, ...
Version: Beta5
Scenario
Attempt to connect to an offline device. After the connection attempt times out, switch the device on
bleManager.connect(bluetoothDevice)
.useAutoConnect(true)
.retry(3, 600)
.enqueue();
Expected
The connection is attempted after the timeout
Got
The connection is never attempted after the timeout
Logs
13:58:41 BluetoothGatt: connect() - device: C0:4B:24:4B:11:A7, auto: false
13:58:41 BluetoothGatt: registerApp()
13:58:41 BluetoothGatt: registerApp() - UUID=1cc136ae-1d6f-4633-894a-5cf88ce20c60
13:58:41 BluetoothGatt: onClientRegistered() - status=0 clientIf=7
13:58:41 MyBleManagerCallback: onDeviceConnecting: C0:4B:24:4B:11:A7
13:59:12 BluetoothGatt: onClientConnectionState() - status=133 clientIf=7 device=C0:4B:24:4B:11:A7
13:59:12 BluetoothGatt: close()
13:59:12 BluetoothGatt: unregisterApp() - mClientIf=7
13:59:12 MyBleManagerCallback: onDeviceDisconnected: C0:4B:24:4B:11:A7
13:59:12 MyBleManagerCallback: onError: a BLE error has occurred message = Error on connection state change, code = 133
Related #31 (comment)
This task would be useful to ensure that the device gets disconnected.
Calling gatt.disconnect()
only closes the virtual connection associated with BluetoothGatt
object. If there is another app connected to the same device, or the connection was opened multiple times in the application, the device will remain connected. The solution, to ensure disconnection, may be to implement a Disconnect Op Code on some Control Point characteristic on the remote device and then send this Op Code from the mobile phone.
Add a new request that will complete when the phone gets disconnected without calling gatt.disconnect()
.
Consider renaming onLinklossOccur [0] to onLinklossOccurred for consistency.
Hi,
I was running Nordic ATT MTU throughput test on nRF52840 between two boards. The test comes with SDK.
I want to do similar test with phone and nRF52840. I am using this library in my app. I can make connection to Nordic board which runs ATT MTU throughput. I have Samsung S9 which has BT5. I can see that 2MBPS phy is set. But it looks like there is no interface in this library to set GAP event length.
NRF_SDH_BLE_GAP_EVENT_LENGTH - GAP event length
The time set aside for this connection on every connection interval in 1.25 ms units.
Can you tell how to set this parameter from this android library ?
Also it looks like characteristic write is not synchronous. It means those are queued up. Is there any interface which does synchronous writes ?
Thanks,
Rahul
Hi,
I unbind the BLE device from android setting page after the BLE device have connected with a correct bonding request.
Then I get Authentication required (5).
I need to restart the app to reconnect the BLE device.It will have correct behavior like normal use.
APP: nRF Toolbox (in develop branch)
Android-BLE-Library version : 2.0-alpha5
Phone: HTC Desire 820u with android 6.0.1
TEST BLE Device situation: the device send the bond request when we enable the TXCharacteristic notification.
nRF Toolbox UART, 2018-08-02
OTOHTR (E3:F8:E0:1C:61:39)
D 10:06:56.404 Creating service...
D 10:06:56.419 Binding to the service...
I 10:06:56.489 Service started
V 10:06:56.506 Connecting...
D 10:06:56.510 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE)
D 10:06:56.549 Activity bound to the service
D 10:06:57.073 [Callback] Connection state changed with status: 0 and new state: 2 (CONNECTED)
I 10:06:57.078 Connected to E3:F8:E0:1C:61:39
D 10:06:57.085 wait(300)
V 10:06:57.400 Discovering services...
D 10:06:57.406 gatt.discoverServices()
I 10:06:57.436 Services discovered
V 10:06:57.441 Primary service found
V 10:06:57.547 Requesting new MTU...
D 10:06:57.550 gatt.requestMtu(260)
I 10:06:57.654 MTU changed to: 23
D 10:06:57.657 gatt.setCharacteristicNotification(6e400003-b5a3-f393-e0a9-e50e24dcca9e, true)
V 10:06:57.662 Enabling notifications for 6e400003-b5a3-f393-e0a9-e50e24dcca9e
D 10:06:57.665 gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x01-00)
D 10:06:58.421 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_BONDING (11)
D 10:06:58.526 [Broadcast] Action received: android.bluetooth.device.action.PAIRING_REQUEST, pairing variant: PAIRING_VARIANT_PASSKEY_CONFIRMATION (2)
D 10:07:06.536 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_BONDED (12)
I 10:07:06.543 Device bonded
D 10:07:06.549 gatt.setCharacteristicNotification(6e400003-b5a3-f393-e0a9-e50e24dcca9e, true)
V 10:07:06.556 Enabling notifications for 6e400003-b5a3-f393-e0a9-e50e24dcca9e
D 10:07:06.560 gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x01-00)
I 10:07:06.668 Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 01-00
A 10:07:06.672 Notifications enabled
D 10:07:13.888 Activity unbound from the service
D 10:07:16.520 [Callback] Connection state changed with status: 22 and new state: 0 (DISCONNECTED)
W 10:07:16.527 Error: (0x16): GATT CONN TERMINATE LOCAL HOST
W 10:07:16.533 Connection lost
V 10:07:16.543 Connecting...
D 10:07:16.548 gatt.connect()
D 10:07:16.574 [Broadcast] Action received: android.bluetooth.device.action.BOND_STATE_CHANGED, bond state changed to: BOND_NONE (10)
D 10:07:17.691 [Callback] Connection state changed with status: 0 and new state: 2 (CONNECTED)
I 10:07:17.697 Connected to E3:F8:E0:1C:61:39
D 10:07:17.705 wait(300)
V 10:07:18.012 Discovering services...
D 10:07:18.017 gatt.discoverServices()
I 10:07:18.029 Services discovered
V 10:07:18.033 Primary service found
V 10:07:18.038 Requesting new MTU...
D 10:07:18.042 gatt.requestMtu(260)
I 10:07:18.166 MTU changed to: 23
D 10:07:18.170 gatt.setCharacteristicNotification(6e400003-b5a3-f393-e0a9-e50e24dcca9e, true)
V 10:07:18.175 Enabling notifications for 6e400003-b5a3-f393-e0a9-e50e24dcca9e
D 10:07:18.179 gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x01-00)
D 10:07:18.714 [Callback] Connection state changed with status: 19 and new state: 0 (DISCONNECTED)
W 10:07:18.730 Error: (0x13): GATT CONN TERMINATE PEER USER
W 10:07:18.736 Connection lost
D 10:07:18.875 Activity bound to the service
D 10:07:43.007 [Callback] Connection state changed with status: 0 and new state: 2 (CONNECTED)
I 10:07:43.018 Connected to E3:F8:E0:1C:61:39
D 10:07:43.024 wait(300)
V 10:07:43.330 Discovering services...
D 10:07:43.334 gatt.discoverServices()
I 10:07:43.347 Services discovered
V 10:07:43.352 Primary service found
V 10:07:43.456 Requesting new MTU...
D 10:07:43.460 gatt.requestMtu(260)
I 10:07:43.589 MTU changed to: 23
D 10:07:43.595 gatt.setCharacteristicNotification(6e400003-b5a3-f393-e0a9-e50e24dcca9e, true)
V 10:07:43.600 Enabling notifications for 6e400003-b5a3-f393-e0a9-e50e24dcca9e
D 10:07:43.604 gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x01-00)
W 10:07:43.701 Authentication required (5)
I got the following build error after using Android-BLE-Library
Invoke-customs are only supported starting with Android O (--min-api 26)
Message{kind=ERROR, text=Invoke-customs are only supported starting with Android O (--min-api 26), sources=[Unknown source file], tool name=Optional.of(D8)}
Then I change the Source Compatibility and Target Compatibility to 1.8 as suggested from the Internet
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
and got the following error
Process 'command '/Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java'' finished with non-zero exit value 1
Does Android-BLE-Library require a certain minSdkVersion? My project has minSdkVersion 19
@philips77
Version : v2.0 alpha 5
I am using the Profile Service Ready Activity in the nRF Toolbox/develop project. Everything is working as excepted but when I disconnect the bluetooth I am getting this error. Auto connect is turned off and also service is stopped after disconnect.
java.lang.NullPointerException: Attempt to invoke virtual method 'void no.nordicsemi.android.ble.WriteRequest.notifyPacketSent(android.bluetooth.BluetoothDevice, byte[])' on a null object reference
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.onCharacteristicWriteSafe(BleManager.java:2348)
at no.nordicsemi.android.ble.MainThreadBluetoothGattCallback.lambda$onCharacteristicWrite$3$MainThreadBluetoothGattCallback(MainThreadBluetoothGattCallback.java:119)
at no.nordicsemi.android.ble.MainThreadBluetoothGattCallback$$Lambda$3.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:836)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6269)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
When using beta6, trying to connect to a device from the onScanResult() method in the scan callback as follows:
BleDeviceManager bleDeviceManager = BleDeviceManager.getInstance(context.getApplicationContext());
BleDevice2 device = new BleDevice2();
bleDeviceManager.setGattCallbacks(device);
try {
bleDeviceManager.connect(result.getDevice())
.retry(3, 100)
.useAutoConnect(false)
.enqueue();
}
catch (Exception e) {
Logg.e(TAG, "Can't connect to device: " + e.getMessage());
}
I get the following stack trace:
2018-10-26 17:06:47.480 20222-20222/cc.biketracker.android I/BleScanCallback: Scan result: Device name: 00228892, address: C7:56:60:F0:56:58, RSSI: -59
2018-10-26 17:06:47.493 20222-20222/cc.biketracker.android D/BleScanCallback: Bond state: BOND_BONDED
2018-10-26 17:06:47.498 20222-20222/cc.biketracker.android D/BleScanCallback: Found device. Stopping scanning.
2018-10-26 17:06:47.503 20222-20222/cc.biketracker.android D/BluetoothAdapter: isLeEnabled(): ON
2018-10-26 17:06:47.543 20222-20222/cc.biketracker.android D/AndroidRuntime: Shutting down VM
2018-10-26 17:06:47.558 20222-20222/cc.biketracker.android E/AndroidRuntime: FATAL EXCEPTION: main
Process: cc.biketracker.android, PID: 20222
java.lang.BootstrapMethodError: Exception from call site #9 bootstrap method
at no.nordicsemi.android.ble.BleManager.enqueue(BleManager.java:1860)
at no.nordicsemi.android.ble.Request.enqueue(Request.java:751)
at cc.biketracker.android.ble.BleScanCallback.onScanResult(BleScanCallback.java:173)
at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:484)
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.app.ActivityThread.main(ActivityThread.java:6680)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.ClassCastException: Bootstrap method returned null
at no.nordicsemi.android.ble.BleManager.enqueue(BleManager.java:1860)ย
at no.nordicsemi.android.ble.Request.enqueue(Request.java:751)ย
at cc.biketracker.android.ble.BleScanCallback.onScanResult(BleScanCallback.java:173)ย
at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:484)ย
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.app.ActivityThread.main(ActivityThread.java:6680)ย
at java.lang.reflect.Method.invoke(Native Method)ย
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)ย
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)ย
2018-10-26 17:06:47.565 20222-20222/cc.biketracker.android E/UncaughtException: java.lang.BootstrapMethodError: Exception from call site #9 bootstrap method
at no.nordicsemi.android.ble.BleManager.enqueue(BleManager.java:1860)
at no.nordicsemi.android.ble.Request.enqueue(Request.java:751)
at cc.biketracker.android.ble.BleScanCallback.onScanResult(BleScanCallback.java:173)
at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:484)
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.app.ActivityThread.main(ActivityThread.java:6680)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: java.lang.ClassCastException: Bootstrap method returned null
at no.nordicsemi.android.ble.BleManager.enqueue(BleManager.java:1860)ย
at no.nordicsemi.android.ble.Request.enqueue(Request.java:751)ย
at cc.biketracker.android.ble.BleScanCallback.onScanResult(BleScanCallback.java:173)ย
at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:484)ย
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.app.ActivityThread.main(ActivityThread.java:6680)ย
at java.lang.reflect.Method.invoke(Native Method)ย
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)ย
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)ย
It could be I'm using the API incorrectly. It seems strange that this is supposed to happen on the UI thread, given I'm scanning in the background from a service. I did try using await() rather than enqueue, but that failed with another exception indicating I should be using enqueue().
Hi, I send 2 packages but after the first package, flag mOperationInProgress became true and when I send the second package, package doesn't sending because mOperationInProgress == true. How I can fix it?
Version of library: 1.2.0
Would be great to have out of the box integer formatting (like in BluetoothGattCharacteristic#setValue(int value, int formatType, int offset)).
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.
/** 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.
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?
I received a crash stacktrace that points to BleManager.enqueue
protected final void enqueue(@NonNull final Request request) {
if (mGattCallback == null) {
mGattCallback = getGattCallback();
}
// Add the new task to the end of the queue.
mGattCallback.enqueue(request);
runOnUiThread(() -> mGattCallback.nextRequest(false)); <-- NPE
}
When executing that Runnable, mGattCallback is null. It obviously wasn't null in the line above, which means we nullified the gattCallback instance. If I'm not mistaken, this can only happen due to a close invocation.
The easiest way is to add a null check on mGattCallback after locking mLock. If you are fine with this solution, I can create the PR, but you may want to analyze if there are other consequences.
Reading an encrypted characteristic will trigger the bonding process to start. However, the read/write that triggered it sometimes fails. I see this happening a lot on Android 6 and far less on 7 & 8. When it happens I get a GATT_AUTH_FAIL (error 137) and I re-try the operation which then always succeeds.
It seems that on later Android versions (7 & 8), the stack retries the operation itself. I don't have proof for it other than I don't see any read/write failed errors on those Android versions.
So my suggestion would be to add an extra check and to retry the operation that triggered the bonding process. That way the users of the BleManager don't have to worry about it. Here is what I do:
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
// Perform some checks on the status field
if(status!= GATT_SUCCESS) {
if (status == GATT_AUTH_FAIL) {
// Characteristic encrypted and needs bonding, so retry operation
// This only seems to happen on Android 6
HBLogger.v(TAG, "Write failed (Authentication failed), bonding in progress so retrying write command");
retryCommand();
return;
} else if (status == GATT_INSUFFICIENT_AUTHENTICATION) {
// Characteristic encrypted and needs bonding, so retry operation
// This only seems to happen on Android < 6
HBLogger.v(TAG, "Write failed (Insufficient authentication), bonding in progress so retrying write command");
retryCommand();
return;
}
...
Same thing is done in onCharacteristicRead of course....
Developer should use ApplicationContext instead of Activity to construct BleManager
in general.
I am hoping to find a work around on a BLE bug using the BleManager and the GS9.
I find after a few connect/disconnect cycles that the peripheral device remains connected.
The almost unbelievable part is that toggling the BT icon on the phone does not disconnect the device. When I restart the GS9 I can then see the device disconnect.
Perhaps you might have a more reliable way I should be disconnecting where I call disconnect() and wait for a callback to ensure the device really disconnected?
Hi,
I'm trying to use the library to get communication between an Android mobile and a BLE peripheral
which utilises the extended PDU.
To understand things I wrote the central using the Nordic SDK 15.x. With the Nordic central I found it was
necessary to get the central to send a LL_LENGTH_REQ, to get the peripheral to extend the length of
the PDU. This was required in addition to the request to increase the MTU size.
Does the library support making such a request from an Android device?
Is it possible to make this request from and Android device?
I'm not certain whether this is the real problem, as there seems to be discussion about
Android transparently chunking characteristics over 20 bytes length. Is it also necessary
to tell Android not to employ this mechanism, to ensure it utilises the full PDU
once its enabled?
I'm noticing that currently extended length notification is being transferred in fragments.
Again is the control of the chunking within Android something the library supports?
Grateful for any help you can provide on this matter!
First of all, thank you for a great library. In our app we provide the ability to download the firmware from our device. We do this be sending a certain command and the device will consistently send back a batch of packets until the firmware has been fully received. We verify each batch using a checksum to ensure it's correct when receiving it. We recently switched to this library and noticed that the functionality was broken as it would send back packets that didn't make sense (the data was different on every request, the number of packets were erratic and the checksum values never validated). After many hours debugging I found that it all related back to the connectGatt method in the BleManager.java file.
This was tested on a Samsung Galaxy S9+.
This causes the issue:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
...
mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback,
BluetoothDevice.TRANSPORT_LE, preferredPhy, mHandler);
}
However, this fixes the issue:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
...
mBluetoothGatt = device.connectGatt(mContext, false, mGattCallback,
BluetoothDevice.TRANSPORT_LE, preferredPhy); //, mHandler);
}
For now we will have to keep the module in our project to ensure it works across multiple devices, but it would be nice to pull this out and just use Gradle.
Appreciate it.
[EDIT] - The code didn't save correctly. Essentially I commented out the mHandler in the connectGatt method.
Hi,
I've had 2 of my users recently crash with the following null object crash on beta5 version of the library. I'm unsure what exactly is happening at the moment in time before it crashes as I've never seen this on my devices, but wanted to share it in case there is something obvious you can spot?
I have several hundred other users all using the app (and library) without problem, so don't think this is a huge problem.
Fatal Exception: java.lang.NullPointerException: Attempt to invoke virtual method 'void no.nordicsemi.android.ble.a$a.a(android.os.Handler)' on a null object reference
at no.nordicsemi.android.ble.BleManager.getGattCallback(BleManager.java:680)
at no.nordicsemi.android.ble.BleManager.getGattCallback(BleManager.java:114)
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.lambda$onConnectionStateChangeSafe$1(BleManager.java:2237)
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.lambda$hHV_dPbGJHyD-KM5FND5GY7KZA0(Unknown Source)
at no.nordicsemi.android.ble.-$$Lambda$a$a$hHV_dPbGJHyD-KM5FND5GY7KZA0.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Hi,
I need to send/receive more than 20 bytes of data through BLE. I read #3 for sending more than 20 bytes. However I would like to use Android-BLE-Library 1.2.0 for some reason. Could you let me know where to modify in 1.2.0 ?
Anyway did you try all 3 approaches in #3 at Android-BLE-Library 2..?
Thanks.
Device: Nexus 4 running 5.1.1
java.util.NoSuchElementException
at java.util.LinkedList.removeFirstImpl(LinkedList.java:689)
at java.util.LinkedList.removeFirst(LinkedList.java:676)
at java.util.LinkedList.poll(LinkedList.java:895)
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.nextRequest(BleManager.java:2864)
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.onCharacteristicWriteSafe(BleManager.java:2482)
at no.nordicsemi.android.ble.MainThreadBluetoothGattCallback.lambda$onCharacteristicWrite$3(MainThreadBluetoothGattCallback.java:128)
at no.nordicsemi.android.ble.-$$Lambda$MainThreadBluetoothGattCallback$dAnXisth7CAlJFFhbDJ5X_192I0.run(lambda)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)```
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.
The request that fails is
fun disconnectWithoutReconnect() {
disconnect()
.done { Timber.d("disconnect success") }
.fail { device, status ->
Timber.d("disconnect fail")
close()
}
.enqueue()
}
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter it
at com.mycompany.MyNordicBleManager$disconnectWithoutReconnect$1.onRequestCompleted(Unknown Source:2)
at no.nordicsemi.android.ble.Request.notifySuccess(Request.java:829)
at no.nordicsemi.android.ble.BleManager.internalDisconnect(BleManager.java:665)
at no.nordicsemi.android.ble.BleManager.access$2100(BleManager.java:113)
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.nextRequest(BleManager.java:2812)
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.access$1300(BleManager.java:1812)
at no.nordicsemi.android.ble.BleManager.lambda$enqueue$4(BleManager.java:1786)
at no.nordicsemi.android.ble.-$$Lambda$BleManager$KDSxdgn5nClZRFe_FvyLUfX8mWc.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Scenario
On Beta3, it happened after I tried to connect and received a TimeoutException
Process: com.mycompany, PID: 20828
java.lang.NullPointerException: Attempt to invoke direct method 'void no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.nextRequest(boolean)' on a null object reference
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.access$1300(BleManager.java:1836)
at no.nordicsemi.android.ble.BleManager.lambda$enqueue$4(BleManager.java:1804)
at no.nordicsemi.android.ble.-$$Lambda$BleManager$KDSxdgn5nClZRFe_FvyLUfX8mWc.run(Unknown Source:2)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Might it be that I immediately tried to connect again, even before receiving bluetoothgatt close callback?
//Exception stack trace
2018-10-01 14:51:21.872 D/MyClass: Invoking connect
2018-10-01 14:51:21.873 D/BluetoothGatt: close()
2018-10-01 14:51:21.873 D/BluetoothGatt: unregisterApp() - mClientIf=7
2018-10-01 14:51:21.881 D/MyClass: onError: a BLE error has occurred message = Error on connection state change, code = 133
When a connection is disconnected by remote side (status 8), and the manager calls notifyDeviceDisconnected()
, it first calls close()
, then onDeviceDisconnected()
.
If a new connection request was added in onDeviceDisconnected()
is will be proceeded immediately, as the mOperationInProgress` flag was cleared.
The new request fail callback would be invoked a moment later with the old's request status (8).
I saw you recently added a delay in onConnectionStateChange before calling discoverServices for bonded devices. I also observed the need for this during testing with several devices so this is definately needed in some cases!
I have a couple of questions:
I only have a limited set of devices and phones at my disposal and I only observed this issue on Android 6. On Android 7 & 8 the delay doesn't seem necessary. Your code doesn't look at the Android version but I think this is only needed for Android < 7. Did you also observe the need for a delay on Android 7 & 8?
You use a 1600 ms delay. The device I encountered that needed a delay was the A&D UA-651BLE and with that one 600 ms seemed enough. Why are you suggesting 1600 ms? Seems quite long...
What is your theory about why the delay is needed? My guess is that Android is doing the key exchange with the bonded peripheral and service discovery cannot be started until this has finished. I don't know enough about low-level Bluetooth to be sure...
Looking at class BleManager<E extends BleManagerCallbacks> I wonder if the generic part <...> is more than a historic left-over? It seems E is only ever used to keep a reference to mCallbacks. The field itself seems to only be accessed as type BleManagerCallbacks. Maybe it's possible to replace the <...> part with a simple setter method to set the callback of type BleManagerCallbacks (without E)?
It might be worth adding to the instructions to use this, the need for adding
+ compileOptions {
+ targetCompatibility JavaVersion.VERSION_1_8
+ sourceCompatibility JavaVersion.VERSION_1_8
+ }
to the gradle files for all the modules that include this. I was getting a fairly cryptic error
code com.android.dx.cf.code.SimException: invalid opcode ba (invokedynamic requires --min-sdk-version >= 26)
that I eventually tracked down to this. Alternatively, I'm not sure how necessary the lambda
expression in BleManager is since without that this restriction might not be required.
When implementing a Manager it seems to be required to access mCallbacks (https://github.com/NordicSemiconductor/Android-BLE-Library/blob/develop/ble/src/main/java/no/nordicsemi/android/ble/BleManager.java#L134). This direct access can be somewhat confusing (to me at least, it is, every time I come across it). How about converting the field to a method, to make it more explicit that it's a part of the inherited interface?
I have a Motorola G5S with Android 7.1. The Nordic NRF Toolbox app and the NRF Connect and also this library, disconnects automatically inmediately after it connects. I cannot establish a connection. In Android 7.0 it works. Does it make sense?
When my device is just on the edge of range and ultimately probably won't establish a reliable connection I get this error stack from the Android-BLE-Library:
04-12 16:53:03.586 8991-9590/org.sralab.emgimu W/BluetoothGatt: Unhandled exception in callback
java.lang.NullPointerException: Attempt to invoke virtual method 'android.bluetooth.BluetoothDevice android.bluetooth.BluetoothGatt.getDevice()' on a null object reference
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.onDeviceReady(BleManager.java:1276)
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.nextRequest(BleManager.java:1734)
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.nextRequest(BleManager.java:1834)
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.nextRequest(BleManager.java:1834)
at no.nordicsemi.android.ble.BleManager$BleManagerGattCallback.onCharacteristicRead(BleManager.java:1550)
at android.bluetooth.BluetoothGatt$1$6.run(BluetoothGatt.java:364)
at android.bluetooth.BluetoothGatt.runOrQueueCallback(BluetoothGatt.java:725)
at android.bluetooth.BluetoothGatt.-wrap0(Unknown Source:0)
at android.bluetooth.BluetoothGatt$1.onCharacteristicRead(BluetoothGatt.java:358)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:124)
at android.os.Binder.execTransact(Binder.java:697)
In my case I get a link loss callback so I close the BleManager. This sets the GattCallback to null. It seems like when the BleManager is in this state, it should not attempt to go through the initialization requests.
All getters in response package are annotated with NonNull, when truth is that that's not guaranteed.
In fact, in the past I have received WriteResponse's with rawData null. I think they were caused by #48, but still, it's possible
I created a PR to change annotations to Nullable
#49
I'm having CLA signing issues, I'll look into that later.
Given the current code, we are very limited on how much we can test our BleManager descendants.
Making the code testable would be a daunting task, but maybe we could start with something simple such as exposing a constructor that takes a Handler as parameter. There's a VisibleForTesting annotation that will flag the usage as a lint error if used outside from test sourceset. VisibleForTesting lives in an independent package (com.android.support:support-annotations:XXX, maybe it's androidx now?)
I'm eager to listen to other ideas, I'm sure I'm not the only one having this issue.
Thanks!
Hi @philips77,
I just noticed that the autoConnect
flag is always passed with false
value to BluetoothDevice.connectGatt(Context, boolean, BleManagerGattCallback)
in the BleManager.internalConnect
method.
Because of this, android won't try to connect automatically to a previously connected (and paired in my case) device when it comes online.
Could you please have a look on this issue?
Thanks in advance, cheers!
Hi,
Great library! It helped us a lot to set up our BLE services.
Do you have any plans for distributing the library to Maven?
It's a bit time consuming (in case of time compilation) to use your library as a module within the project.
Best regards,
Marcin
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.
I am seeing a situation where onConnectionStateChangeSafe
in BleManager
gets called with newState == BluetoothProfile.STATE_CONNECTED
after I do a disconnect (call BleManager.disconnect()
).
This causes mConnected
to be set to true, but mBluetoothDevice
is null. This makes both connect do nothing (since mConnected
is true) and disconnect to nothing (since mBluetoothDevice
is null), so the BleManager is no longer of much use.
Some more rough details on what I'm doing:
BleManager.connect()
).This is not done in quick succession - between the disconnect and the next connect for instance there is a pause several seconds long.
This works fine most of the time, but sometimes, there is a call to onConnectionStateChangeSafe
after the disconnect, which causes the problem described above.
Side note: The purpose for this is to implement a communications protocol where characteristics are used to transfer data, and the error handling is specified as disconnecting, reconnecting, and starting over.
I have been using version 2.0-beta10.
Hi all,
I am facing some connection problems with the library. I downloaded it 4 days ago and yesterday I started calling the BLEManager connect(device) method. All devices are correctly scanned but when I start the connection, I can connect to the device but immediately it disconnects from the device. I have no clue about what can be causing this problem. Here is the trace I get from logcat:
D/TEST-LP: onDeviceConnecting: LUIS-05B6
D/BluetoothGatt: connect() - device: DB:AB:2A:56:B6:05, auto: false registerApp()
D/BluetoothGatt: registerApp() - UUID=282d31c8-d3d0-4969-88a7-b233d4c2babc
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=6
D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=DB:AB:2A:56:B6:05
D/TEST-LP: onDeviceConnected: LUIS-05B6
D/BluetoothGatt: discoverServices() - device: DB:AB:2A:56:B6:05
D/BluetoothGatt: onConnectionUpdated() - Device=DB:AB:2A:56:B6:05 interval=6 latency=0 Timeout=500 status=0
D/BluetoothGatt: onSearchComplete() = Device=DB:AB:2A:56:B6:05 Status=0
D/BluetoothGatt: cancelOpen() - device: DB:AB:2A:56:B6:05
D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=6 device=DB:AB:2A:56:B6:05
D/TEST-LP: onDeviceDisconnected: LUIS-05B6
If you want to see some part of the code just let me know. Any help is apreciated!
*Edit: logcat formatted
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.
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?
This was tested on the develop branch (v2 library - 2.0-alpha6) and everything seems to be working correctly in all cases, except for when bluetooth is disabled on the device (after connection has been made). When bluetooth is re-enabled, connection is no longer possible.
I have debugged it and it seems that the issue is related to mOperationInProgress
flag in `BleManagerGattCallback'. When call for connection is made:
Android-BLE-Library/ble/src/main/java/no/nordicsemi/android/ble/BleManager.java
Lines 1778 to 1786 in 135a777
flag is checked and call is silently skipped (none of the callbacks will be called in this case):
Android-BLE-Library/ble/src/main/java/no/nordicsemi/android/ble/BleManager.java
Lines 2739 to 2747 in 135a777
When bluetooth is disabled on device, broadcast receiver is called:
which then prevents all further calls by setting this flag.
I haven't seen it turned back to false to enable new connections.
I want to send more than 20 bytes in the data, how to deal with.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.