9.1 Android and Bluetooth

Hello ReadersJ!! Hope you are doing well. Today we shall know about the most widely used technology in the cell phone arena i.e. Bluetooth. Every one of us is well aware of Bluetooth technology. We share pictures; audio, video files via Bluetooth so let us study this interesting technology.

9.1 Introduction

Bluetooth is a wireless technology standard. It is meant for communication over short range distances. Android framework supports Bluetooth network stack. So device can exchange data wirelessly. We have APIs for Bluetooth with which applications connect wirelessly to other devices. We have four major tasks which are accomplished by the use of Bluetooth API and they are:

  • Set up Bluetooth
  • Find devices
  • Connect devices
  • Transfer data

Following classes and interfaces are used for Bluetooth connections:

  • BluetoothClass: General characteristics and capabilities of Bluetooth devices are described. Device’s major and minor classes and services are defined here. It is a read-only set of features.
  • BluetoothProfile: A Bluetooth profile is a wireless interface specification for devices which communicates via Bluetooth. Hence this is an interface which represents Bluetooth profile.
  • BluetoothSocket: It is the point of connection where applications exchange data.
  • BluetoothServerSocket: It is an open server socket which listens to the incoming requests.
  • BluetoothDevice: It represents a remote device. This is used to request a connection with remote device.
  • BluetoothAdapter: It is the entry point of all Bluetooth interaction.

We require certain permissions for using Bluetooth and they are:

  • android.permission.BLUETOOTH: We need this permission for any Bluetooth communication.
  • android.permission.BLUETOOTH_ADMIN: We need this permission when we want our application to initiate device discovery or manipulate Bluetooth settings.

Let us have a small example of Bluetooth.

9.2 Example

Create a project and name it as you like. I am naming it as BluetoothDiscovery application. This application will prompt you with an option to connect to the Bluetooth. When you press the button saying connect Bluetooth of device will be turned on. The discovery thread will activate itself and discovery will start. And the android logo will appear when the device’s Bluetooth is activated. It will disappear as soon as you deactivate the Bluetooth of device by pressing the button named disconnect. It will again deactivate the Bluetooth of device. There is one problem i.e. you cannot test it on emulator. As soon as you run the application, it will prompt you to force close the application. For this particular section, you need to have a real device. You will copy the apk file on device and install it as any other downloaded application and you are done. It is my 100% guarantee that this application works. So let us not waste any more time and find out the Bluetooth application. This is an important functionality of smart phone hence we are including this section. Open the activity_main.xml file and code it as shown in the following listing:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/bluetooth"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="BLUETOOTH TEXT" />
    <Button
        android:id="@+id/bConnect"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Connect" />
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />
    <Button
        android:id="@+id/bDisconnect"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Disconnect" />
    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.52"
        android:src="@drawable/ic_launcher" />
</LinearLayout>

Figure activity_main.xml file

The graphical layout of application should look similar to the following snapshot:

Figure Graphical layout of application

Open the main activity file and code it as shown in the following listing:

package com.android.tution.BluetoothDiscovery;
import java.util.Set;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
    protected static final int DISCOVERY_REQUEST = 1;
    public Button Connect, Disconnect;
    public ImageView logo;
    public TextView TblueStatus;
    public String toastText;
    private BluetoothDevice remoteDevice;
    // initialise the bluetooth hardware
    private BluetoothAdapter btAdapter;
    // create a broadcastReceiver to receive state changes
    BroadcastReceiver bluetoothState = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            String prevStateExtra = BluetoothAdapter.EXTRA_PREVIOUS_STATE;
            String stateExtra = BluetoothAdapter.EXTRA_STATE;
            int state = intent.getIntExtra(stateExtra, -1);
            @SuppressWarnings("unused")
            int previousState = intent.getIntExtra(prevStateExtra, -1);
            // String toastText = "";
            switch (state) {
            case (BluetoothAdapter.STATE_TURNING_ON): {
                toastText = "BLUETOOTH TURNING ON";
                Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT)
                        .show();
                break;
            }
            case (BluetoothAdapter.STATE_ON): {
                toastText = "BLUETOOTH ON";
                Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT)
                        .show();
                setupURI();
                break;
            }
            case (BluetoothAdapter.STATE_TURNING_OFF): {
                toastText = "BLUETOOTH IS TURNING OFF";
                Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT)
                        .show();
                break;

Figure First part of main activity class

Second part of class is as shown in the following listing:

case (BluetoothAdapter.STATE_OFF): {
                toastText = "BLUETOOTH OFF";
                Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT)
                        .show();
                setupURI();
                break;
            }
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setupURI();
    }
private void setupURI() {
        // TODO Auto-generated method stub
        final TextView TblueStatus = (TextView) findViewById(R.id.bluetooth);
        final Button Connect = (Button) findViewById(R.id.bConnect);
        final Button Disconnect = (Button) findViewById(R.id.bDisconnect);
        final ImageView logo = (ImageView) findViewById(R.id.imageView1);
        // set up display
        // Connect.setVisibility(View.GONE);
        Disconnect.setVisibility(View.GONE);
        logo.setVisibility(View.GONE);
        // going to retrieve the default values of your hardware interface
        btAdapter = BluetoothAdapter.getDefaultAdapter();
        if (btAdapter.isEnabled()) {
            String address = btAdapter.getAddress();
            String name = btAdapter.getName();
            String statusText = name + ":" + address;
            TblueStatus.setText(statusText);
            Disconnect.setVisibility(View.VISIBLE);
            logo.setVisibility(View.VISIBLE);
            Connect.setVisibility(View.GONE);
        } else {
            TblueStatus.setText("BLUETOOTH IS NOT TURNED ON!!!");
            Connect.setVisibility(View.VISIBLE);
        }
        Connect.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                // String actionStateChanged =
                // BluetoothAdapter.ACTION_STATE_CHANGED;
                // String actionRequestEnabled =
                // BluetoothAdapter.ACTION_REQUEST_ENABLE;
                // IntentFilter filter = new IntentFilter(actionStateChanged);
                // registerReceiver(bluetoothState, filter);
                // startActivityForResult(new Intent(actionRequestEnabled), 0);
                // register for discover events
                String scanModeChanged = BluetoothAdapter.ACTION_SCAN_MODE_CHANGED;
                String btDiscoverable = BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
                IntentFilter filter = new IntentFilter(scanModeChanged);
                registerReceiver(bluetoothState, filter);
                startActivityForResult(new Intent(btDiscoverable),
                        DISCOVERY_REQUEST);
            }
        });

Figure Second part of main activity class

Third part of class is as shown in the following listing:

Disconnect.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                btAdapter.disable();
                Disconnect.setVisibility(View.GONE);
                logo.setVisibility(View.GONE);
                Connect.setVisibility(View.VISIBLE);
                TblueStatus.setText("BLUETOOTH OFF!!!");
            }
        });
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // TODO Auto-generated method stub
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == DISCOVERY_REQUEST) {
            Toast.makeText(MainActivity.this, "Discovery is in progress",
                    Toast.LENGTH_SHORT).show();
            setupURI();
            findDevices();
        }
    }
    private void findDevices() {
        // TODO Auto-generated method stub
        String lastUsedRemoteDevice = getLastUsedRemoteDevice();
        if (lastUsedRemoteDevice != null) {
            toastText = "Checking for known paired devices,namely: "
                    + lastUsedRemoteDevice;
            Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT)
                    .show();
            // see if this device is in the list of currently visible(?),paired
            // devices
            Set<BluetoothDevice> pairedDevices = btAdapter.getBondedDevices();
            for (BluetoothDevice pairedDevice : pairedDevices) {
                if (pairedDevice.getAddress().equals(lastUsedRemoteDevice)) {
                    toastText = "Found Device : " + pairedDevice.getName()
                            + "@" + lastUsedRemoteDevice;
                    Toast.makeText(MainActivity.this, toastText,
                            Toast.LENGTH_SHORT).show();
                    remoteDevice = pairedDevice;
                }
            }
        }
        if (remoteDevice == null) {
            toastText = "Startng discovery for remote devices.....";
            Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT)
                    .show();
            // start discovery
            if (btAdapter.startDiscovery()) {
                toastText = "Discovery thread started......Scanning for devices";
                Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT)
                        .show();
                registerReceiver(discoveryresult, new IntentFilter(
                        BluetoothDevice.ACTION_FOUND));
            }
        }
    }

Figure Third part of class

 

BroadcastReceiver discoveryresult = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            // TODO Auto-generated method stub
            String remoteDeviceName = intent
                    .getStringExtra(BluetoothDevice.EXTRA_NAME);
            BluetoothDevice remoteDevice;
            remoteDevice = intent
                    .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            toastText = "Discovered: " + remoteDeviceName;
            Toast.makeText(MainActivity.this, toastText, Toast.LENGTH_SHORT)
                    .show();
        }
    };
    private String getLastUsedRemoteDevice() {
        // TODO Auto-generated method stub
        SharedPreferences prefs = getPreferences(MODE_PRIVATE);
        String result = prefs.getString("LAST_REMOTE_DEVICE_ADDRESS", null);
        return result;
    }
}

Figure Final part of class

So buddies we are done with the java class. Now it’s the time for manifest. Open your manifest file and code it as shown in the following listing:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.tution.BluetoothDiscovery"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.android.tution.BluetoothDiscovery.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

Figure manifest file

When you run this application in emulator it will prompt us to force close the application. Don’t worry this application works absolutely fine on real device. It is a tested application. We cannot test these hardware dependent applications on emulator. Hence we shall conclude this subsection with this example. .

Congratulations buddiesJ!! We are done with Bluetooth application. See you in the next section. Till then keep practicing. Happy App developing!!