Android, How can I make BLE device to paired device (bonded)

android, bluetooth-lowenergy, gatt

Solution

As far as I know, to initiate a pairing procedure in BLE there are two ways:

1) From API 19 and up you can start the pairing by calling the `mBluetoothDevice.createBond()`. You don't need to be connected with the remote BLE device to start the pairing process.

2) When you try to do a Gatt operation, let's take for example the method

mBluetoothGatt.readCharacteristic(characteristic)

If the remote BLE device needs to be bonded to do any communication then when the callback

`onCharacteristicRead( BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)`

gets called its `status` parameter value will be equal to either `GATT_INSUFFICIENT_AUTHENTICATION` or `GATT_INSUFFICIENT_ENCRYPTION`, and not equal to `GATT_SUCCESS`. If this happens then the pairing procedure will start automatically.

Here is an example to find out when it fails once the `onCharacteristicRead` callback gets called

@Override
public void onCharacteristicRead(
        BluetoothGatt gatt,
        BluetoothGattCharacteristic characteristic,
        int status)
{

    if(BluetoothGatt.GATT_SUCCESS == status)
    {
        // characteristic was read successful
    }
    else if(BluetoothGatt.GATT_INSUFFICIENT_AUTHENTICATION == status ||
            BluetoothGatt.GATT_INSUFFICIENT_ENCRYPTION == status)
    {
        /*
         * failed to complete the operation because of encryption issues,
         * this means we need to bond with the device
         */

        /*
         * registering Bluetooth BroadcastReceiver to be notified
         * for any bonding messages
         */
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        mActivity.registerReceiver(mReceiver, filter);
    }
    else
    {
        // operation failed for some other reason
    }
}

Other people mentioning that this operation starts the pairing procedure automatically: Android Bluetooth Low Energy Pairing

And this is how the receiver can be implemented

private final BroadcastReceiver mReceiver = new BroadcastReceiver()
{
    @Override
    public void onReceive(Context context, Intent intent)
    {
        final String action = intent.getAction();

        if (action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED))
        {
            final int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);

            switch(state){
                case BluetoothDevice.BOND_BONDING:
                    // Bonding...
                    break;

                case BluetoothDevice.BOND_BONDED:
                    // Bonded...
                    mActivity.unregisterReceiver(mReceiver);
                    break;

                case BluetoothDevice.BOND_NONE:
                    // Not bonded...
                    break;
            }
        }
    }
};

Problem

Before GATT, createRfcommSocketToServiceRecord, createInsecureRfcommSocketToServiceRecord methods can make paired device, but GATT has no option about paired device, only use BluetoothDevice.connectGatt(...) I want to make a paired device if it's connected already. thx.

Original source

Related problems