Android – Bluetooth pairing – how to show the simple Cancel/Pair dialog

androidandroid-bluetoothandroid-intentbluetoothbluetooth-oob

I have prepared a simple test project for this question at GitHub.

I am trying to create an Android app, which would scan a QR code from a computer screen and then use the data (MAC address and PIN or hash) for easy pairing (bonding) with a Bluetooth device.

Similar to the popular InstaWifi app – but for Classic Bluetooth.

For testing purposes I don't do any barcode scanning yet, but just display a list of devices:

list of devices

After user touches one of the devices, pairing is tried in MainActivity.java:

private void startBluetoothPairing(BluetoothDevice device) {
    Intent pairingIntent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
    pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
    pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                BluetoothDevice.PAIRING_VARIANT_PIN);
    pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, 1234);
    //device.setPin(new byte[]{1,2,3,4});  <- DOES NOT CHANGE ANYTHING
    //device.setPairingConfirmation(false);
    startActivityForResult(pairingIntent, REQUEST_BT_SETTINGS);
}

Unfortunately, the popup still asks for PIN:

pin dialog

Because I have actually specified a PIN in my source code, I was actually expecting another, simpler system dialog to be shown (this one is shown when doing NFC OOB pairing):

pair dialog

From searching for solutions, I know that there is a setPin() method, but it is not applicable here (or is it?) – because I am trying to pair the whole smartphone to the Bluetooth device and not just the app…

My question: How to make Android OS to show the simple Cancel/Pair dialog?

Searching for Bluetooth pairing request string at GitHub has not shown any hints…

UPDATE: On unrealsoul007's suggestion (thanks) I have update the source code in MainActivity.java and now the simple Cancel/Pair dialog is displayed:

private void startBluetoothPairing(BluetoothDevice device) {
    Intent pairingIntent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
    pairingIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
    pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
        BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION);
    pairingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivityForResult(pairingIntent, REQUEST_BT_PAIRING);
}

However I am not sure how to complete the pairing process – because onActivityResult is called with resultCode=0 even before the dialog is closed:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
    // this is called before user clicks Cancel or Pair in the dialog
    if (requestCode == REQUEST_BT_PAIRING) { 
        if (resultCode == Activity.RESULT_OK) {  // 0 != -1
            Log.d("XXX", "Let#s pair!!!!"); // NOT CALLED
        }

        return;
    }
}

Best Answer

You are being prompted for entering the pin because that is what you are requesting in your pairingIntent.

Instead of using

pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT,
                BluetoothDevice.PAIRING_VARIANT_PIN);
pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_KEY, 1234);

Use

pairingIntent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PASSKEY_CONFIRMATION);

As mentioned here,

The user will be prompted to confirm the passkey displayed on the screen or an app will confirm the passkey for the user.

Related Topic