@@ -335,6 +335,9 @@ public void onReceive(final Context context, final Intent intent) {
335335 return ;
336336 }
337337 } else if (previousBondState == BluetoothDevice .BOND_BONDED ) {
338+ // Removing the bond will cause disconnection.
339+ userDisconnected = true ;
340+
338341 if (request != null && request .type == Request .Type .REMOVE_BOND ) {
339342 // The device has already disconnected by now.
340343 log (Log .INFO , () -> "Bond information removed" );
@@ -345,7 +348,15 @@ public void onReceive(final Context context, final Intent intent) {
345348 // or in Android Settings), the BluetoothGatt object should be closed, so
346349 // the library won't reconnect to the device automatically.
347350 // See: https://github.com/NordicSemiconductor/Android-BLE-Library/issues/157
348- close ();
351+ if (!isConnected ())
352+ close ();
353+
354+ // Due to https://github.com/NordicSemiconductor/Android-BLE-Library/issues/363,
355+ // the call to close() here has been placed behind an if statement.
356+ // Instead, the 'userDisconnected' flag is set to true (here and in
357+ // 'internalRemoveBond()'.
358+ // When the device gets disconnected, close() method will be called from
359+ // 'notifyDeviceDisconnected(...)'.
349360 }
350361 break ;
351362 case BluetoothDevice .BOND_BONDING :
@@ -764,6 +775,8 @@ private boolean internalRemoveBond() {
764775 //noinspection JavaReflectionMemberAccess
765776 final Method removeBond = device .getClass ().getMethod ("removeBond" );
766777 log (Log .DEBUG , () -> "device.removeBond() (hidden)" );
778+ // Removing a call will initiate disconnection.
779+ userDisconnected = true ;
767780 return removeBond .invoke (device ) == Boolean .TRUE ;
768781 } catch (final Exception e ) {
769782 Log .w (TAG , "An exception occurred while removing bond" , e );
@@ -1577,12 +1590,17 @@ private void notifyDeviceDisconnected(@NonNull final BluetoothDevice device, fin
15771590 // ConnectRequest was already notified
15781591 } else if (userDisconnected ) {
15791592 log (Log .INFO , () -> "Disconnected" );
1580- close ();
1593+ // If Remove Bond was called, the broadcast may be called AFTER the device has disconnected.
1594+ // In that case, we can't call close() here, as that would unregister the broadcast
1595+ // receiver. Instead, close() will be called from the receiver.
1596+ if (request == null || request .type != Request .Type .REMOVE_BOND )
1597+ close ();
15811598 postCallback (c -> c .onDeviceDisconnected (device ));
15821599 postConnectionStateChange (o -> o .onDeviceDisconnected (device , status ));
15831600 final Request request = this .request ;
15841601 if (request != null && request .type == Request .Type .DISCONNECT ) {
15851602 request .notifySuccess (device );
1603+ this .request = null ;
15861604 }
15871605 } else {
15881606 log (Log .WARN , () -> "Connection lost" );
0 commit comments