Search code examples
androidbluetoothbluetooth-lowenergyandroid-bluetoothandroid-ble

Android - BLE bonding programmatically doesn't work on all CoolPad Note 3


I am using below broadcast receiver to catch bond request and bond it without user popup request.

private static BroadcastReceiver pairingBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(intent.getAction())) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);

                Toast.makeText(context, "broadcast type "+type, Toast.LENGTH_LONG).show();

                if (type == BluetoothDevice.PAIRING_VARIANT_PIN) {
                    if(devicePin != null) {
                        CommonStuff.Log("bond pin "+devicePin);
                        Toast.makeText(context, "broadcast bond pin "+devicePin, Toast.LENGTH_LONG).show();
                        byte[] pin = new byte[10];
                        try {
                            pin = (byte[]) BluetoothDevice.class.getMethod("convertPinToBytes", String.class)
                                    .invoke(BluetoothDevice.class, devicePin);
                        } catch (IllegalAccessException e) {

                        } catch (InvocationTargetException e) {

                        } catch (NoSuchMethodException e) {

                        }
                        /*for (int i=0; i< pin.length; i++) {
                            CommonStuff.Log("byte bond pin "+pin[i]);
                        }*/
                        device.setPin(pin);
                        /*if(type == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION || type == 1) {
                            device.setPairingConfirmation(true);
                        }*/
                        abortBroadcast();
                    }
                }
            } else if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction())) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);

                if(state == BluetoothDevice.BOND_BONDING)
                    return;

                    if(state == BluetoothDevice.BOND_BONDED) {
                        Toast.makeText(context, "Bond success",  Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(context, "Bond failed",  Toast.LENGTH_LONG).show();
                    }
            }
        }
    };

Assume devicePin is initialized globally. This works for most of the phones. But in coolpad note 3, i got BluetoothDevice.EXTRA_PAIRING_VARIANT value as 1. And when i try to bond this device using setPin() without considering EXTRA_PAIRING_VARIANT value, bonding fails.

Does anyone faced this same issue? Please help me to sort this out.


Solution

  • BluetoothDevice.EXTRA_PAIRING_VARIANT as 1 denotes only user can enter the passkey. But programmatically we can set the passkey using private method named setpasskey.

    Add below code as an else if case for type in above code

    else if(type == 1) {
        int pin = Integer.parseInt(devicePin);
        try {
            device.getClass().getMethod("setPasskey", int.class)
                    .invoke(device, pin);
            abortBroadcast();
        } catch (IllegalAccessException e) {
    
        } catch (InvocationTargetException e) {
    
        } catch (NoSuchMethodException e) {
    
        }
    }