Search code examples
bluetooth-lowenergyuartnrf51nrf52

Bluetooth Pairing with Nrf UART is not working properly


The Bluetooth pairing is not working properly. I am developing the Application based on Bluetooth pairing with UART. Here I have included my concept and Program.Help me out to fix the problem.

My Expected Result is If the user is press the Connect button. It should be pair without user input and Confirmation Screen for Pair Request and PIN. Finally The Device is Respond back to Connected.

My Actual Result is The Confirmation Screen and User Input Popup will open .After that the Device is Paired. Finally the Device is not responded back to I am connected.

I am Stuck in that Problem More than 2 days. Help me out of this Problem.

1. Register the PAIRING in onstart() method

          IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
         this.registerReceiver(mPairingRequestReceiver, filter);

2. BroadcastReceiver for Receive the PairingRequest.

  private BroadcastReceiver mPairingRequestReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action.equals(BluetoothDevice.ACTION_PAIRING_REQUEST)) {
            try {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                int pin = intent.getIntExtra("android.bluetooth.device.extra.PAIRING_KEY", 123456);
                //the pin in case you need to accept for an specific pin
                byte[] pinBytes;
                pinBytes = ("" + pin).getBytes("UTF-8");
                device.setPin(pinBytes);


        } catch (Exception e) {
                Log.e(TAG, "Error occurs when trying to auto pair");
                e.printStackTrace();
            }
        }
    }
};

/* After devices is connected I am creating the Bond*/

     @Override
     public void onDeviceConnected(BluetoothDevice device) {

        device.createBond();

      }

Solution

  • You can bypass the native Bluetooth pairing process and pair with Bluetooth peripheral pro-grammatically. Try this:

    Register a receiver for BluetoothDevice.ACTION_PAIRING_REQUEST with the highest priority.

    private void notPaired(){
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST);
        filter.setPriority(SYSTEM_HIGH_PRIORITY-1);
        registerReceiver(mReceiver, filter);
        mDevice.createBound();// OR establish connection with the device and read characteristic for triggering the pairing process 
        getBoundState();
    }
    
    private final BroadcastReceiver mReceiver = new BroadcastReceiver()
    {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if(BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)){
                final BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                int type = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
    
                if(type == BluetoothDevice.PAIRING_VARIANT_PIN){
                    byte[] pin = "123456".getBytes();
                    device.setPin(pin);
                    Log.i("Pairing Process ", "Pairing Key Entered");
                    abortBroadcast();
                }else
                    Log.i("Pairing Process: ", "Unexected Pairing type");
            }
        }
    };
    

    To make sure that device is paired register a receiver for BluetoothDevice.ACTION_BOND_STATE_CHANGED

    private void getBoundState(){
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        registerReceiver(boundStateReciver, filter);
    }
    
    private final BroadcastReceiver boundStateReciver= new BroadcastReceiver()
    {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
                final int d = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,-1);
                switch(d){
                    case BluetoothDevice.BOND_BONDED:
                        Log.i("Pairing Process ", "Paired successfully");
                    break;
                }
            }
        }
    };
    

    In Manifests add this permission

    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />