Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programmatically pair Bluetooth device without the user entering pin

Tags:

The Bluetooth device I am trying to connect has always the same pincode. This should make it possible to pair the device by setting the pin programmatically.

After trying to search how this could be done, I ended up with the code below:

BluetoothDevice device = getDevice();

//To avoid the popup notification:
device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
device.getClass().getMethod("cancelPairingUserInput", boolean.class).invoke(device, true);
byte[] pin = ByteBuffer.allocate(4).putInt(1234).array();
//int pinn = 1234;

//Entering pin programmatically:  
Method ms = device.getClass().getMethod("setPin", byte[].class);
//Method ms = device.getClass().getMethod("setPasskey", int.class);
ms.invoke(device, pin);

//Bonding the device:
Method mm = device.getClass().getMethod("createBond", (Class[]) null);
mm.invoke(device, (Object[]) null);

cancelPairingUserInput gives me a NoSuchMethodException, which is weird because the method does exist in BluetoothDevice class.

Is looks like Setpin or SetPasskey doesn't do anything. The device just wont pair. It only pairs after manually entering the pin.

So the only line of code that works is:

//Bonding the device:
Method mm = device.getClass().getMethod("createBond", (Class[]) null);
mm.invoke(device, (Object[]) null);

Logcat output:

09-27 12:34:46.408: ERROR/App(11671): cancelPairingUserInput [boolean]
        java.lang.NoSuchMethodException: cancelPairingUserInput [boolean]
        at java.lang.Class.getConstructorOrMethod(Class.java:460)
        at java.lang.Class.getMethod(Class.java:915)
        at test.app.bluetooth.model.BluetoothDiscoveryAndPairing.pair(BluetoothDiscoveryAndPairing.java:97)
        at test.app.bluetooth.model.BluetoothDiscoveryAndPairing.access$000(BluetoothDiscoveryAndPairing.java:25)
        at test.app.bluetooth.model.BluetoothDiscoveryAndPairing$1.onReceive(BluetoothDiscoveryAndPairing.java:79)
        at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:756)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4921)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
        at dalvik.system.NativeStart.main(Native Method)

So what am I doing wrong?

like image 468
user1816451 Avatar asked Sep 27 '13 10:09

user1816451


People also ask

Can Bluetooth pair without permission?

The BLUETOOTH_ADVERTISE , BLUETOOTH_CONNECT , and BLUETOOTH_SCAN permissions are runtime permissions. Therefore, you must explicitly request user approval in your app before you can look for Bluetooth devices, make a device discoverable to other devices, or communicate with already-paired Bluetooth devices.

Can you force Bluetooth pairing?

Go to the Policies tab, you can either create a new policy or edit an already existing one. Navigate to Android–> Restrictions–> Allow Network Settings. Enable the 'Force Bluetooth' option to prevent the users from turning OFF the blue tooth and the 'Force Wi-Fi' option to prevent turning OFF the Wi-Fi.

Does Bluetooth require PIN?

If a passkey* is required on the display of the BLUETOOTH device, enter “0000.” A passkey may be called “Passcode”, “PIN code”, “PIN number” or “Password.” Make the BLUETOOTH connection from the BLUETOOTH device. When the BLUETOOTH connection is established, the (BLUETOOTH) indicator stays lit.

What is the default PIN for Bluetooth pairing?

Use the code 0000 when pairing with another Bluetooth® device. The passcode may appear as Pass key, PIN code, PIN number, or Password depending on the Bluetooth device used.


2 Answers

The hidden method cancelPairingUserInput does not exist in your device. Don't use it.

  1. You should register BroadcastReceiver for android.bluetooth.device.action.PAIRING_REQUEST
  2. Call createBond()
  3. Wait for BroadcastReceiver to trigger
  4. In BroadcastReceiver if action is android.bluetooth.device.action.PAIRING_REQUEST call this method
public void setBluetoothPairingPin(BluetoothDevice device)
{
    byte[] pinBytes = convertPinToBytes("0000");
    try {
          Log.d(TAG, "Try to set the PIN");
          Method m = device.getClass().getMethod("setPin", byte[].class);
          m.invoke(device, pinBytes);
          Log.d(TAG, "Success to add the PIN.");
          try {
                device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
                Log.d(TAG, "Success to setPairingConfirmation.");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                Log.e(TAG, e.getMessage());
                e.printStackTrace();
            } 
        } catch (Exception e) {
          Log.e(TAG, e.getMessage());
          e.printStackTrace();
        }
}

It also works on a device with Jelly Bean version (4.1.2) of Android.

like image 195
KRiadh Avatar answered Sep 27 '22 22:09

KRiadh


this is works for me:

    IntentFilter filter2 = new IntentFilter(
            "android.bluetooth.device.action.PAIRING_REQUEST");
    mActivity.registerReceiver(
            pairingRequest, filter2);

private final BroadcastReceiver pairingRequest = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals("android.bluetooth.device.action.PAIRING_REQUEST")) {
            mBluetoothDevice = needed;
                try {
                    byte[] pin = (byte[]) BluetoothDevice.class.getMethod("convertPinToBytes", String.class).invoke(BluetoothDevice.class, "1234");
                    Method m = mBluetoothDevice.getClass().getMethod("setPin", byte[].class);
                    m.invoke(mBluetoothDevice, pin);
                    mBluetoothDevice.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(mBluetoothDevice, true);
}
    catch(Exception e)
{

    e.printStackTrace();

}
like image 41
Péter Hidvégi Avatar answered Sep 27 '22 22:09

Péter Hidvégi