40

I am developing an application where I want to connect a Bluetooth device main issue is I don't want user to enter required pin instead application should do that by himself...I don't have any connection related issue...Only want to insert and complete pin authentication process by application itself.

I found following code I am sure it is working but not sure on how to add pin in this code??

private void pairDevice(BluetoothDevice device) {
        try {
            Log.d("pairDevice()", "Start Pairing...");
            Method m = device.getClass().getMethod("createBond", (Class[]) null);
            m.invoke(device, (Object[]) null);
            Log.d("pairDevice()", "Pairing finished.");
        } catch (Exception e) {
            Log.e("pairDevice()", e.getMessage());
        }
    }

Does anyone know how to enter pin in above code or any similar code to solve problem.. Thank You

Sandip Jadhav
  • 7,377
  • 8
  • 44
  • 76

8 Answers8

27

How can I avoid or dismiss Android's Bluetooth pairing notification when I am doing programmatic pairing?

This seems to give you the answer, with the pin entering and all. It involves sending .setPin() whenever you get the message.

Community
  • 1
  • 1
Mats Willemsen
  • 815
  • 1
  • 9
  • 25
12

So, I had this question, if someone needs the answer to this working in android 4.4.2.

 IntentFilter filter = new IntentFilter(
                "android.bluetooth.device.action.PAIRING_REQUEST");


        /*
         * Registering a new BTBroadcast receiver from the Main Activity context
         * with pairing request event
         */
        registerReceiver(
                new PairingRequest(), filter);

And the code for the Receiver.

  public static class PairingRequest extends BroadcastReceiver {
        public PairingRequest() {
            super();
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("android.bluetooth.device.action.PAIRING_REQUEST")) {
                try {
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    int pin=intent.getIntExtra("android.bluetooth.device.extra.PAIRING_KEY", 0);
                    //the pin in case you need to accept for an specific pin
                    Log.d("PIN", " " + intent.getIntExtra("android.bluetooth.device.extra.PAIRING_KEY",0));
                    //maybe you look for a name or address
                    Log.d("Bonded", device.getName());
                    byte[] pinBytes;
                    pinBytes = (""+pin).getBytes("UTF-8");
                    device.setPin(pinBytes);
                    //setPairing confirmation if neeeded
                    device.setPairingConfirmation(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

And in the manifest file.

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

And the broadcastReceiver.

 <receiver android:name=".MainActivity$PairingRequest">
                <intent-filter>
                    <action android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
                    <action android:name="android.bluetooth.device.action.PAIRING_CANCEL" />
                </intent-filter>
</receiver>
nilsi
  • 10,351
  • 10
  • 67
  • 79
Rodolfo Abarca
  • 565
  • 7
  • 15
  • is this solution working for android pie also ? cause im still getting confirmation dialog – Tejas Pandya Feb 04 '19 at 07:54
  • No, I dont think so this solution was for android 4.4.2 and android 5, not sure about android 6 and up. @TejasPandya – Rodolfo Abarca Feb 04 '19 at 18:13
  • 1
    Does this solution work without Bluetooth_Priveldge permission? Doesn't this device.setPairingConfirmation(true); line need the permisiion mentioned above to work ? – Harrish Selvarajah Apr 15 '20 at 05:05
  • @Harrish it should work, but it will depend on the device, some devices require pairing confirmation sent, and some assume that once you are connected you are paired, also this solution was for android 4.4.2 and android 5, so you should probably do something similar for android 6 and above. – Rodolfo Abarca Apr 15 '20 at 16:12
  • The method setPairingConfirmation needs the BLUETOOTH_PRIVILEDGED permission which is not available to third party apps. But with abortBroadcast it's working on my Pixel 4 XL! – mbo May 10 '20 at 06:23
  • @Marius could you please tell me how to do abortBroadcast. – Arthurghev Jul 09 '20 at 07:41
  • @Arthurghev it's in one of the other answers https://stackoverflow.com/a/59925412/3979479 – mbo Jul 10 '20 at 14:31
7

How to set the pin code has been answered above (and that helped me). Yet, I share my simple code below which works with Android 6:

BluetoothAdapter mBTA = BluetoothAdapter.getDefaultAdapter();
if (mBTA.isDiscovering()) mBTA.cancelDiscovery();
mBTA.startDiscovery();
...

/** In a broadcast receiver: */

if (BluetoothDevice.ACTION_FOUND.equals(action)) { // One device found.

    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    Log.d(TAG, "Start Pairing... with: " + device.getName());
    device.createBond();
}

// If you want to auto-input the pin#:
else if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)){

                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    device.setPin("1234".getBytes());
}
Bruno L.
  • 457
  • 6
  • 8
5

Try this code:

public void pairDevice(BluetoothDevice device)
{
    String ACTION_PAIRING_REQUEST = "android.bluetooth.device.action.PAIRING_REQUEST";
    Intent intent = new Intent(ACTION_PAIRING_REQUEST);
    String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
    intent.putExtra(EXTRA_DEVICE, device);
    String EXTRA_PAIRING_VARIANT = "android.bluetooth.device.extra.PAIRING_VARIANT";
    int PAIRING_VARIANT_PIN = 0;
    intent.putExtra(EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent);
}

Intent intent = new Intent(BluetoothDevice.ACTION_PAIRING_REQUEST);
intent.putExtra(EXTRA_DEVICE, device);
int PAIRING_VARIANT_PIN = 272;
intent.putExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, PAIRING_VARIANT_PIN);
sendBroadcast(intent);

Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
startActivityForResult(intent, REQUEST_PAIR_DEVICE);

I hope this helps

Reference: http://pastebin.com/N8dR4Aa1

Majid Golshadi
  • 2,686
  • 2
  • 20
  • 29
Dan Bray
  • 7,242
  • 3
  • 52
  • 70
  • Please help me.....I want list of device that has BT enabled and after click on particular bluetooth device, it is paired with our device – Denny Sharma Oct 25 '13 at 08:23
  • 4
    I get the first method but what do you suggest we do with the other two blocks of code? – gregm Jan 28 '15 at 19:03
5

Register a BluetoothDevice.ACTION_PAIRING_REQUEST receiver onCreate()

val pairingRequestFilter = IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST)
        registerReceiver(pairingReceiver, pairingRequestFilter)

on receiver set your pin using setPin() and call abortBroadcast()

val PAIRING_PIN=1234

private var pairingReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            val action = intent!!.action
            if (BluetoothDevice.ACTION_PAIRING_REQUEST == action) {
                val device: BluetoothDevice? =intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                val type =intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR)
                if (type == BluetoothDevice.PAIRING_VARIANT_PIN) {
                    device?.setPin(PAIRING_PIN.toByteArray())
                    abortBroadcast()
                }
            }
        }
    }

Don't forget to unregister receiver on onDestroy()

override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(pairingReceiver)
    }

if it doesn't work for you, try setting hight priority to receiver

val pairingRequestFilter = IntentFilter(BluetoothDevice.ACTION_PAIRING_REQUEST)          
pairingRequestFilter.priority = IntentFilter.SYSTEM_HIGH_PRIORITY - 1
            registerReceiver(pairingReceiver, pairingRequestFilter)

Also you can register a receiver with BluetoothDevice.ACTION_BOND_STATE_CHANGED to read status of pairing

val filter = IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED)
        registerReceiver(receiver, filter)
  • Best answer to this problem. It's working on my Pixel 4 XL with Android 10! If I don't call abortBroadcast the dialog pops up and closes again after 2 seconds. – mbo May 10 '20 at 06:27
1

Try this,

BluetoothDevice device = intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
device.getClass().getMethod("cancelPairingUserInput", boolean.class).invoke(device);
No_Rulz
  • 2,679
  • 1
  • 20
  • 33
0
    BluetoothSocket bluetoothSocket = null;
    try {
        bluetoothSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(UUID_DIVING));
    } catch (IOException e) {
        Log.i("Bluetooth", "IOException = " + e.getMessage());
        e.printStackTrace();
    }

    try {
        byte[] pin = (byte[]) BluetoothDevice.class.getMethod("convertPinToBytes", String.class).invoke(BluetoothDevice.class, "0000");
        Method m = device.getClass().getMethod("setPin", byte[].class);
        m.invoke(device, (Object) pin);
        device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
    } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
        Log.i("Bluetooth", "IOException = " + e.getMessage());
        e.printStackTrace();
    }

    try {
        if (bluetoothSocket != null) {
            bluetoothSocket.connect();
            Log.i("Bluetooth", "bluetoothSocket.connect() ");
            InputStream inputStream = bluetoothSocket.getInputStream();
            OutputStream outputStream = bluetoothSocket.getOutputStream();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
The Archetypal Paul
  • 41,321
  • 20
  • 104
  • 134
0

bluetoothDevice.createBond method , you can use for paring

For checking paring status , you have to register broadcast receiver BluetoothDevice.ACTION_BOND_STATE_CHANGED

In your receiver class, you can check blueToothDevice.getBondState

user2851150
  • 397
  • 5
  • 12