0

I'm making an app that needs to connect with a bluetooth device and get data from it... that device is set as master, so I needed to implement a Thread, where I listenUsingRfcommWithServiceRecord and wait for a connection from it:

    public AcceptThread(Context context, String serverName, UUID myUUID) {
    this.context = context;
    BluetoothServerSocket tmp = null;

    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    try {

        // MY_UUID is the app's UUID string, also used by the client code
        tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(serverName, myUUID);
    } catch (IOException e) { }
    mmServerSocket = tmp;
}

Then on run I run the code socket = mmServerSocket.accept(5000) to wait until it starts pairing with the device:

    public void run() {
    BluetoothSocket socket = null;
    while (true) {
        try {
            socket = mmServerSocket.accept(5000);
        } catch (IOException e) {
            Log.e(TAG,"IOException: " + e);
        }

        // If a connection was accepted
        if (socket != null) {

            // Manage the connection
            ManageConnectedSocket manageConnectedSocket = new ManageConnectedSocket(socket);
            manageConnectedSocket.run();

            try {
                mmServerSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "IOException: " + e);
            }
            break;
        }
    }
}

The Device asks for an authentication PIN, and I need to have an automatic procedure... for that I though of implementing a broadcast receiver to know when the device is asked to par with another device:

IntentFilter filter = new IntentFilter(ACTION_PAIRING_REQUEST);
context.registerReceiver(mPairReceiver, filter);

and receive it:

private final BroadcastReceiver mPairReceiver = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_PAIRING_REQUEST.equals(action)) {
            Log.e(TAG,"ACTION_PAIRING_REQUEST");
            setBluetoothPairingPin(device);
        }
    }
};

In my setBluetoothPairingPin method I receive a BluetoothDevice object :

public void setBluetoothPairingPin(BluetoothDevice device) {
    byte[] pinBytes = convertPinToBytes("0000");
    try {
        Log.e(TAG, "Try to set the PIN");
        Method m = device.getClass().getMethod("setPin", byte[].class);
        m.invoke(device, pinBytes);
        Log.e(TAG, "Success to add the PIN.");
        try {
            device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, false);
            Log.e(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();
    }

}

The problem is that I can't know when my socket receives information, and consecutively, can't know what is my BluetoothDevice to set Pairing Pin before it's connected... Can someone help me on how to surpass this? Or is there other way to put the pin authentication when I'm listenning from BluetoothServerSocket?

If I'm not explaining correctly, please let me know...

Thanks in advance

slyzer
  • 215
  • 1
  • 19
  • Why not use Push Button Configuration instead of entering pin. You will just need to click on Pair button and not enter a pin. Does this help? – unrealsoul007 Jul 04 '15 at 10:37
  • Hi, thanks for the answer. not really... I do not control the other device requirements, it asks for a pin confirmation and it's set has master. So in order for me to connect I need to listen to the device, but I also need to insert a pin when I'll connect with it... any suggestions? – slyzer Jul 06 '15 at 09:42

1 Answers1

0

With the help from this and this, I was able to make work for me...

My confusion was with the method setBluetoothPairingPin that I couldn't understand that the ACTION_PAIRING_REQUEST is actually called when the device is being starting to pairing, and that is when the PIN is asked from the user... so invoking BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);, and changing a bit of the set pairing method I manage to make it work...

Here's my final code:

public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
    if (ACTION_PAIRING_REQUEST.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                String PIN = "0000";

                byte[] pin = new byte[0];
                try {
                    pin = (byte[]) BluetoothDevice.class.getMethod("convertPinToBytes", String.class).invoke(BluetoothDevice.class, PIN);
                    BluetoothDevice.class.getMethod("setPin", byte[].class).invoke(device, pin);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
    }
}
Community
  • 1
  • 1
slyzer
  • 215
  • 1
  • 19