Javascript required
Skip to content Skip to sidebar Skip to footer

Make Things Continue Playing When Bluetooth Disconnects Android

I'm working on a mobile app that implements Bluetooth LE and communicates with a HC-08 device.

While everything is ok on iOS with CoreBluetooth, i encounter some problems on my Android version.

I start by getting a Bluetooth Device

          BluetoothDevice bluetoothDevice;                  

After that, i connect to it:

          bluetoothDevice.connectGatt(context, false, callback);                  

Which is calling a callback function inside which i wait for STATE_CONNECTED and discover services, then write to characteristic:

          @Override     public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {         super.onConnectionStateChange(gatt, status, newState);           if(status == BluetoothGatt.GATT_SUCCESS){             Log.e("BLE_LOG", "onConnectionStateChange with success");              if(newState == BluetoothProfile.STATE_CONNECTED){                 Log.e("BLE_LOG", "sucessfully connected to device: " + bluetoothDevice.getName() + "/" + bluetoothDevice.getAddress());                  bluetoothGatt = gatt;                 gatt.discoverServices();              }             else if(newState == BluetoothProfile.STATE_DISCONNECTED){                 Log.e("BLE_LOG", "succesfully Disconnected from device: " + bluetoothDevice.getName() + "/" + bluetoothDevice.getAddress());                 gatt.close();             }          }         else{             Log.e("BLE_LOG", "onConnectionStateChange with status: " + status + " and newState: " + newState);         }      }      @Override     public void onServicesDiscovered(BluetoothGatt gatt, int status) {         super.onServicesDiscovered(gatt, status);          if(status == BluetoothGatt.GATT_SUCCESS){             Log.e("BLE_LOG", "sucessfully discovered services for device: " + bluetoothDevice.getName() + "/" + bluetoothDevice.getAddress());              service = bluetoothGatt.getService(UUID.fromString(BLEFunctions.PROPRIETARY_SERVICE));             BluetoothGattCharacteristic characteristic = service.getCharacteristic(UUID.fromString(BLEFunctions.PROPRIETARY_CHARACTERISTIC));              //Souscription notifications             if(bluetoothGatt.setCharacteristicNotification(characteristic, true)){                 Log.e("BLE_LOG", "subscribed to notifications from characteristic");             }              characteristic.setValue(SET_ON);             characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);              bluetoothGatt.writeCharacteristic(characteristic);          }         else{             Log.e("BLE_LOG", "Error discovering services for device: " + bluetoothDevice.getName() + "/" + bluetoothDevice.getAddress() + " with status: " + status);         }      }                  

When services are discovered, i'm writting to characteristic, which actually work because my bluetooth device is acting as expected (it switches on a relay), and onCharacteristicWrite is called:

          @Override     public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {         super.onCharacteristicWrite(gatt, characteristic, status);          if(status == BluetoothGatt.GATT_SUCCESS){             Log.e("BLE_LOG", "sucessfully written characteristic for device: " + bluetoothDevice.getName() + "/" + bluetoothDevice.getAddress());         }         else{             Log.e("BLE_LOG", "Error writing characteristic for device: " + bluetoothDevice.getName() + "/" + bluetoothDevice.getAddress() + " with status: " + status);         }     }                  

The problem is that, as soon as the characteristic is written, the device disconnect and i can't continue my process.

At a point in the program, i've got connectionStateChange with status 8 (which seems to be : GATT_INSUFFICIENT_AUTHORIZATION)

I investigated several potential causes, as :

-Maybe the characteristic needs bonding before writing? I know it is handled automatically on iOS for example.

-Maybe the device i use has some incompatibilities with Android (but it works well with software like 'LightBlue', 'BLE Scanner', etc...

Can't figure out what is wrong.

Please help me solve this problem

Adding the log to help:

          2022-05-05 09:58:25.600 22204-22204/com.******.******E/BLE_LOG:  clicked on device: Hall/B0:B1:13:76:0B:1E  2022-05-05 09:58:26.065 22204-22467/com.******.******E/BLE_LOG: onConnectionStateChange with success  2022-05-05 09:58:26.068 22204-22467/com.******.******E/BLE_LOG: sucessfully connected to device: AAA-000000000001001/B0:B1:13:76:0B:1E  2022-05-05 09:58:26.727 22204-22467/com.******.******E/BLE_LOG: sucessfully discovered services for device: AAA-000000000001001/B0:B1:13:76:0B:1E  2022-05-05 09:58:26.732 22204-22467/com.******.******E/BLE_LOG: subscribed to notifications from characteristic  2022-05-05 09:58:26.754 22204-22467/com.******.******E/BLE_LOG: sucessfully written characteristic for device: AAA-000000000001001/B0:B1:13:76:0B:1E  2022-05-05 09:58:31.854 22204-22467/com.******.******E/BLE_LOG: onConnectionStateChange with status: 8 and newState: 0                  

Using my device with software like nRF Connect or LightBlue works well. (no disconnection)

enter image description here

I made progress and managed to point out a reason why the problem occures.

Actually, i'm discovering services via

          gatt.discoverServices();                  

and as soon as i get the callback method, i get the service and characteristic i need and write to it.

          @Override     public void onServicesDiscovered(BluetoothGatt gatt, int status) {         super.onServicesDiscovered(gatt, status);          if(status == BluetoothGatt.GATT_SUCCESS){             Log.e("BLE_LOG", "successfully discovered services");         }          BluetoothGattService service = gatt.getService(UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb"));          Log.e("BLE_LOG", "got serivce with uuid: " + service.getUuid().toString());          bluetoothGatt = gatt;         characteristic = service.getCharacteristic(UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb"));          Log.e("BLE_LOG", "got characteristic with uuid: " + characteristic.getUuid().toString());          byte[] data = {                 0x24, 0x6F, 0x6E, 0x25         };          characteristic.setValue(data);         characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);         bluetoothGatt.writeCharacteristic(characteristic);     }                  

When i deport the write part in another function, like a button function, it works well and doesn't disconnect.

          public void clicked_open(View v){      byte[] data = {             0x24, 0x6F, 0x6E, 0x25     };      characteristic.setValue(data);     characteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);     bluetoothGatt.writeCharacteristic(characteristic);  }                  

It's as if something wasn't totally finished when i call my write as soon as i get the service discovered callback.

Maybe there is a way to ensure everything is ok before writing...

earsmancappery51.blogspot.com

Source: https://stackoverflow.com/questions/72099997/android-ble-device-keep-disconnecting-after-a-succesfull-characteristic-write