@@ -68,6 +68,7 @@ class Device(
6868 private var device: BluetoothDevice = bluetoothAdapter.getRemoteDevice(address)
6969 private var bluetoothGatt: BluetoothGatt ? = null
7070 private var callbackMap = HashMap <String , ((CallbackResponse ) - > Unit )> ()
71+ private val bondReceiverMap = HashMap <String , BroadcastReceiver >()
7172 private val timeoutQueue = ConcurrentLinkedQueue <TimeoutHandler >()
7273 private var bondStateReceiver: BroadcastReceiver ? = null
7374 private var currentMtu = - 1
@@ -280,6 +281,9 @@ class Device(
280281 super .onDescriptorWrite(gatt, descriptor, status)
281282 val key =
282283 " writeDescriptor|${descriptor.characteristic.service.uuid} |${descriptor.characteristic.uuid} |${descriptor.uuid} "
284+ bondReceiverMap.remove(key)?.let {
285+ context.unregisterReceiver(it)
286+ }
283287 if (status == BluetoothGatt .GATT_SUCCESS ) {
284288 resolve(key, " Descriptor successfully written." )
285289 } else {
@@ -586,16 +590,57 @@ class Device(
586590 BluetoothGattDescriptor .DISABLE_NOTIFICATION_VALUE
587591 }
588592
593+ val bondReceiver = object : BroadcastReceiver () {
594+ override fun onReceive (ctx : Context , intent : Intent ) {
595+ if (intent.action == BluetoothDevice .ACTION_BOND_STATE_CHANGED ) {
596+ val updatedDevice =
597+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .TIRAMISU ) {
598+ intent.getParcelableExtra(
599+ BluetoothDevice .EXTRA_DEVICE ,
600+ BluetoothDevice ::class .java
601+ )
602+ } else {
603+ intent.getParcelableExtra<BluetoothDevice >(BluetoothDevice .EXTRA_DEVICE )
604+ }
605+
606+ // BroadcastReceiver receives bond state updates from all devices, need to filter by device
607+ if (device.address == updatedDevice?.address) {
608+ val prev = intent.getIntExtra(BluetoothDevice .EXTRA_PREVIOUS_BOND_STATE , - 1 )
609+ val state = intent.getIntExtra(BluetoothDevice .EXTRA_BOND_STATE , - 1 )
610+ if (state == BluetoothDevice .BOND_BONDED ) {
611+ ctx.unregisterReceiver(this )
612+ } else if (prev == BluetoothDevice .BOND_BONDING && state == BluetoothDevice .BOND_NONE ) {
613+ ctx.unregisterReceiver(this )
614+ reject(key, " Pairing request was cancelled by the user." )
615+ } else if (state == - 1 ) {
616+ ctx.unregisterReceiver(this )
617+ }
618+ }
619+ }
620+ }
621+ }
622+ bondReceiverMap[key] = bondReceiver
623+ context.registerReceiver(
624+ bondReceiver,
625+ IntentFilter (BluetoothDevice .ACTION_BOND_STATE_CHANGED )
626+ )
627+
589628 if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .TIRAMISU ) {
590629 val statusCode = bluetoothGatt?.writeDescriptor(descriptor, value)
591630 if (statusCode != BluetoothStatusCodes .SUCCESS ) {
631+ bondReceiverMap.remove(key)?.let {
632+ context.unregisterReceiver(it)
633+ }
592634 reject(key, " Setting notification failed with status code $statusCode ." )
593635 return
594636 }
595637 } else {
596638 descriptor.value = value
597639 val resultDesc = bluetoothGatt?.writeDescriptor(descriptor)
598640 if (resultDesc != true ) {
641+ bondReceiverMap.remove(key)?.let {
642+ context.unregisterReceiver(it)
643+ }
599644 reject(key, " Setting notification failed." )
600645 return
601646 }
0 commit comments