Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android bluetooth: Paired devices list

I have a bluetooth device with SPP profile and bluetooth version 2.1.
I have an app which connects to that device and communicates with it. The device uses "Just Works" pairing technique.

I am facing a problem on certain phones like Samsung Galaxy tablet, Galaxy S.

The problem is after the user exits from the app, I am closing the sockets and disconnecting from the device. After successful disconnection, it is observed that the device's entry is removed from the paired devices list.

like image 553
Ashwini Shahapurkar Avatar asked Nov 07 '11 08:11

Ashwini Shahapurkar


1 Answers

I haven't worked with tablets, but I did write an app that used SPP for Android phones. What I found was that in order to get Bluetooth to be stable, I have to manually bond with the device I want to communicate with. We used the code below to initiated bonding from within the app, and it should preserve the bonding just as if you manually paired through the settings menu.

Here is the general flow: 1) Register a BroadcastReceiver to listen for BluetoothDevice.ACTION_BOND_STATE_CHANGED
2) After device discovery you should have a BluetoothDevice object.
3) Use reflection to call 'createBond' method on a BluetoothDeviceObject
3a) Wait for bond state change events before opening sockets

BluetoothDevice device = {obtained from device discovery};
Method m = device.getClass().getMethod("createBond", (Class[])null);
m.invoke(device, (Object[])null);

int bondState = device.getBondState();
if (bondState == BluetoothDevice.BOND_NONE || bondState == BluetoothDevice.BOND_BONDING)
{
    waitingForBonding = true; // Class variable used later in the broadcast receiver

    // Also...I have the whole bluetooth session running on a thread.  This was a key point for me.  If the bond state is not BOND_BONDED, I wait here.  Then see the snippets below
    synchronized(this)
    {
        wait();
    }
}

4) Wait for the bond state to change from BOND_BONDING to BOND_BONDED

Inside a BroadcastReciever:

public void onReceive(Context context, Intent intent)
{
    if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(intent.getAction()))
    {
        int prevBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);
        int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);

        if (waitingForBonding)
        {
            if (prevBondState == BluetoothDevice.BOND_BONDING)
            {
                // check for both BONDED and NONE here because in some error cases the bonding fails and we need to fail gracefully.
                if (bondState == BluetoothDevice.BOND_BONDED || bondState == BluetoothDevice.BOND_NONE)
                {
                    // safely notify your thread to continue
                }
            }
        }
    }
}

5) Open sockets and communicate

You can also you the 'removeBond' method via reflection to remove your device from the pairing list.

Hope this helps!

like image 144
wildcatwarrior Avatar answered Sep 26 '22 11:09

wildcatwarrior