Wednesday, December 28, 2011

Bluetooth on Android : Part I

This is a part of a series of posts in which I will put forward a full working app what uses bluetooth on your Android device to discover, connect, pair, send and receive files. The source code would be tagged with each part of this series.

Part 1: The app should be able to discover and list out the devices (paired/unpaired).

To start off with learning about bluetooth on Android, visit the official documentation. The documentation is quite lucid and clear. Here I will try to explain parts of my code.

The first activity (HomeActivity), for now, will have a single button "Discover Devices", which will take you to the activity(DiscoverDevicesActivity) where you can see the list of devices that are visible by your device.

This activity does a few things, quite a few if-else conditions.
  • First, you need to check if your device supports bluetooth. If you don't have the hardware capability on your phone, you won't be able to run this application. Eh!! Most of the phones would obviously have bluetooth. Ummm...Yes... But the emulators don't. Arrggghhh!!!!
  • Once you are sure that your device has bluetooth capability, the next thing to check if it is enabled or not. If it's enabled, move on to the next step, else you will need to turn it on first.
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, REQUEST_ENABLE_BT);
  • Once, you click on "Yes" on the confirmation dialog that you will see, bluetooth radio will be switched on for you. On the screen, the "Scan" button will become active. Once you tap the "Scan" button, the ListView will show the list of devices that your device can discover.
That's all for the first part of the series. But, there's a little more to understand abut discovery.

The process of discovery is asynchronous. The list view, currently shows two kinds of devices.
  1. Devices which your phone already knows about (Paired)
  2. Devices which are discovered (Which are not paired with your device)
Getting the already paired devices is simple. The BluetoothAdapter will give you details about such devices.
// Check already discovered devices
Set<BluetoothDevice> devices = bluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : devices) {
       adapter.addDevice(device);
}
adapter.notifyDataSetChanged();
Now comes the actual discovery part. For this, you will need to register a broadcast receiver which will be called whenever a new device is found. After registering the receiver, you need to trigger the discovery by calling the startDiscovery() method of the BluetoothAdapter.
// Scan for new devices
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(devicesReceiver, filter);

bluetoothAdapter.startDiscovery();
On the receiver's onReceive() method, we pick up the details about the new device found, and add it to our ListView.
public void onReceive(Context context, Intent intent) {
      String action = intent.getAction();
      // When discovery finds a device
      if (BluetoothDevice.ACTION_FOUND.equals(action)) {
          Log.i(TAG, "Device found");
               
          // Get the BluetoothDevice object from the Intent
          BluetoothDevice device = intent
                  .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
          // Add the name and address to an array adapter to show in a ListView
          adapter.addDevice(device);
          adapter.notifyDataSetChanged();
}
The DevicesAdapter is a custom adapter for the ListView which we will be updating in the subsequent posts to show more information about the devices.

As always, you should unregister your receiver, once your activity is paused. Also, in addition to this, you should also cancel the discovery if at all you have started by calling the cancelDiscovery() method of the BluetoothAdapter.

The part 1 of the project can be checked out by fetching the source code and checking out the v1.0 tag from the repository. The complete source code can be found here.

Alternately, if you want to download the source of Part 1 as a zip, use this link to Part 1.