38
votes

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

8
Maybe this will help you. stackoverflow.com/questions/5885438/… Cheers,MSA
@ManolescuSebastian -- I want to create secure connection...Sandip Jadhav
Try my answer. I hope it works for youDan Bray
I answered this question on this post: stackoverflow.com/a/22201805/1426021DragonT

8 Answers

26
votes

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.

12
votes

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>
7
votes

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());
}
5
votes

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

3
votes

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)
1
votes

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);
0
votes
    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();
    }
0
votes

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