Android Bluetooth BLE onDescriptorWrite GATT_INSUFFICIENT_AUTHENTICATION - android

I have a service that connects to a Bluetooth glucose device directly via the mac address.
if (mBluetoothGatt != null) {
if (mBluetoothGatt.connect()) {
return true;
}
else {
return false;
}
}
 
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
The pairing routine and downloading of data from the device work perfect the first time after pairing, but if I try to re-connect to the device and register for notifications I receive a GATT_INSUFFICIENT_AUTHENTICATION error in my BluetoothGatt.onDescriptorWrite method.
#Override
public void onDescriptorWrite (BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
...
if (status == BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION) {
...
The system then prompts the user for a pin code and asks them to re-authenticate with the device, even though the BONDING STATE shows as BONDED.
I've read quite a few StackOverflow posts about BLE and some of them are conflicting or do not address the question of connection handling directly.
If we are trying to connect to a previously paired device, do we use
auto connect or not?
Do we need to re-enable notifications for a
device each time we connect to it? Or only the first time we
connect?
The device I'm using is a Moto G with KitKat 4.4.

Upgrading to Lollipop fixed the problem. The authentication now works perfectly and I do not get prompted every time I create a new connection.

Related

calling connectGatt() and createBond() together

I'm trying to create a bond between my Android phone and my device. Before they were connected well by calling device.connectGatt() with my gattCallback. But now as I want to also want to add bonding by calling device.createBond(), my onConnectionStateChange shows an alternate pattern of connected and disconnected with the status code 0 when connected and 8 when disconnected. Here is my snippet of code of how I'm trying to use connectGatt and createBond together.
#Override
public void onScanResult(int callbackType, ScanResult result) {
System.out.println("on scan result");
super.onScanResult(callbackType, result);
BluetoothDevice device = result.getDevice();
synchronized (this) {
if (mBluetoothGatt == null) {
if (device.createBond()) {
System.out.println("create bond success");
mBluetoothGatt = device.connectGatt(mListener.retrieveApplicationContext(), true, mGattCallback);
}
else System.out.println("create bond sb");
}
}
}
Is there anything wrong by calling these two methods in this way? I searched the internet for creating bonds but none of the pages uses createBond and connectGatt together. I only got a hint from this post about how to call these two methods this way: Android BLE onCharacteristicChanged() using notify not triggered
Also, my BroadCastReceiver always shows device bonding as well but never shows device bonded.
The createBond method will internally first connect to the device if not connected using autoConnect set to false. That means the bonding attempt will be aborted after 30 seconds if the device never connects successfully during that time. But you connect using autoConnect set to true, which means no timeout. So if it for some reason takes 31 seconds to connect, the bonding will not happen.
If I were you, I'd first connect the device myself, and when the device has successfully connected and services discovered (and checked that it has the desired services), call createBond, to make sure everything seems right before bonding.
Status code 8 means "Connection Timeout". This means the connection was up and running but dropped unexpectedly on the radio level, which is not a software error, but something that happens naturally as you go out of range but also due to bad hw such as buggy firmware or bad crystal clock frequency.

Get last received data after connect to BLE?

I have an android app connects to BLE device and communicate together. after connect and bond app to device via BLE, and disconnect it, i receive last received packet and sometimes connect to device failed. see problem steps:
1. connect to ble device from android app.
2. write a characteristic successfully.
3. read a characteristic successfully.(last received data)
4. disconnect from ble device successfully.
5. try to connect app to ble device, i can't and i face below situation; even sometimes i connect but face below situation too:
I get last received data that i read from characteristic for last time.
i can't find solution anywhere, so find solution and put it here, ENJOY!
I wrote this block of code and call it after disconnect:
public void disconnect() {
if (mBluetoothGatt != null && isConnected()) {
mBluetoothGatt.close();
mBluetoothGatt = null;
}
}
mBluetoothGatt is object from BluetoothGatt Class that implements BluetoothProfile. these classes and interfaces need information about implementation of ble in android app. search the web!

Peripheral device found but can't connect to it

In my application i can scan for peripheral device just fine, but can't connect to it. Here is the code for connecting to the master device:
bleGatt = masterDevice.connectGatt(currentContext,false,gattCallback);
if(bleGatt == null){
Log.w(TAG,"Unable to create GATT client");
}
if i change the autoconnect flag to true, like:
bleGatt = masterDevice.connectGatt(currentContext,true,gattCallback);
then device does connects but, my custom service and characteristics are not discovered onServicesDiscovered call back. I think its some problem with this code running on device with API greater than 21
Any help would be appreciated, Thank you!

Why the App doesn't reconnect to the BLE device when set autoConnect to true in Android?

I am develop in Android and BLE. I want the App automatic reconnect to the BLE device after the BLE device disconnect but come back in the range and advertising.
I use the following code to connect to the BLE device:
public void connect(final String address) {
// TODO Auto-generated method stub
Log.w(TAG, "BluetoothLeService Connect function.");
if(mBluetoothAdapter == null || address == null){
Log.w(TAG, "BluetoothAdapter not initialized or unspecified address.");
//return false;
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
mBluetoothGatt = device.connectGatt(this, true, mGattCallback);
}
I have set the AutoConnect to the true , but it didn't reconnect when the BLE device has disconnect and come back in the range.
Why the App doesn't reconnect to the BLE device when set autoConnect to true in Android?
Did I missing something ?
Thanks in advance.
The auto connect parameter determines whether to actively connect to the remote device (or) rather passively scan and finalize the connection when the remote device is in range.
But this does not mean that a peripheral that's been disconnected for days then reappears will be reconnected.
Generally, the first ever connection to a device should be direct (autoConnect set to false) and subsequent connections to known devices should be invoked with the autoConnect parameter set to true.
Also please note, the auto connect will only work when the device is still broadcasting. If not, then it will not work.
I would prefer that you re-connect manually when the device is disconnected. If in case you do end up following this, you would need a marker to determine whether the device was actually disconnected without the user consent.
If true then unbind/unregister your service/broadcast receiver and connect again using the device address which you must have saved previously.
As per my experimentation with the BLE devices it has different behavior in different builds like Kitkat and Lollipop. Even I have observed, using ScanCallback is not so reliable introduced in API level 24.
For auto connect to work the BLE device must be active.
For me i had to support kitkat and lollipop so while connecting gatt i called as:
if(Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
gatt = device.connectGatt(this, true, executor);
} else {
gatt = device.connectGatt(this, false, executor);
}
Now auto connect is working for me in both Lollipop and Kitkat.

Android Bluetooth LE: Not discovering services after connection

I'm trying to use Android's Bluetooth Low Energy to communicate with a BLE device. The first time I connect, everything works fine (connecting to GATT server works, all services and characteristics are discovered, etc.) But, if I disconnect and try to re-connect, it will connect to the GATT server, but will not be able to discover the services. I have to kill the app and restart it, and sometimes even that doesn't work.
This is the code I'm using to disconnect from the device:
public void close(View view) {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
Is there anything else that I need to do when disconnecting? There seems to be some resource that is still connected that prevents discovery of services when I try and reconnect.
I seem to have found the solution: you need to call both BluetoothGatt.disconnect() AND BluetoothGatt.close().

Categories

Resources