Bluetooth Programming with Java

author-image
CIOL Bureau
Updated On
New Update

Anadi Misra

Bluetooth provides the easiest way to create Ad-hoc networks for portable devices. The requirements for Bluetooth programming are more than just the API.

There are two basic things that you need. One is the programming environment, which could be Java or .NET based. And two, you need a hardware toolkit, specific to the device you want your program to work on. e.g. you could create a generic Bluetooth program for say, file transfer, but if you want it to work on a Nokia phone, then you'll need to get a Nokia toolkit for it. Likewise, for other devices.

In this series of articles, we will look into generic programming using the JSR-82 reference implementations. The JSR-82 is the Java community process for standardizing a specification for Bluetooth programming using Java APIs.

The Bluetooth APIs
It is a non-proprietary implementation and concentrates on application development only. In other words, the APIs abstract the underlying complexities of the Bluetooth protocol and services stack for developers. This API consists of two packages-the Bluetooth Core API (optional) and the OBEX (Object Exchange) API. OBEX is a transport independent API, which can be used without the core API being Bluetooth necessarily. The respective packages are 'javax.bluetooth' and 'javax.obex'.

Direct Hit!
Applies To: Java ME developers
USP: Introduces Bluetooth programming in Java
Primary Link:www.javabluetooth.com
Google Keywords: java Bluetooth, JSR-82
On DVD: PCQ Xtreme System\ Labs\bluetooth apps

A point to note here is that these APIs do not implement the Bluetooth Specification. They provide Bluetooth capabilities to Java ME enabled devices.

Getting started
There are quite a few toolkits available for Bluetooth programming as per JSR-82. There is also a selective list of devices that are enabled for these
capabilities. In this first part of the series, we will develop a 'Hello World!' example. We will be using the Net Beans IDE along with Net Beans Mobility extension for demo. The Java ME WTK implements both the JSR APIs, so it will suffice our needs. Our app will contain a Bluetooth client and a server. These are basically two Bluetooth devices, out of which one (client) will query the other (server) for Bluetooth services, and on being run successfully, the client will send a 'Hello World' message to the server.We've given the source code on this month's PCQ Xtreme DVD.

Advertisment

The client side
We will first implement a simple MIDlet that initiates a background thread when started. The Client Java Class for this looks like the following:

public class HelloClient extends PCQBluetoothMidlet {
...
public void run() {
Form f = new Form("Client");
f.addCommand(new Command("Exit", Command.EXIT, 1));
f.setCommandListener(this);
Display.getDisplay(this).setCurrent(f);
}

The first step in programming the application is 'Stack Initialization'. It initializes the Bluetooth stack for controlling the device. This initialization consists of a number of steps including initialization of BCC (Bluetooth Control Center) which is left for the vendor to implement and, hence, is a vendor specific step whose code differs accordingly. Next step is 'Device Management'. The API has two classes for the purpose viz. LocalDevice and RemoteDevice. They provide device management as per the Generic Access Profile.

The class LocalDevice is used to obtain a reference to the device running the client application using the static method 'getLocalDevice()'. The method retrieves information such as type of local device and the services it offers. After we receive the reference to this device, we can extract its address and name using the following code snippet.

LocalDevice local = LocalDevice.getLocalDevice();
String addr = local.getBluetoothAddress();
String name = local.getFriendlyName();

Next step is 'Device Discovery' wherein the local device finds out other Bluetooth devices in its range and gains access to its capabilities. This provides the 'DiscoveryAgent' class and 'DiscoveryListener' interface for this purpose.

Advertisment

The discovery agent can retrieve a list of devices in three ways all of which use static methods. First uses startInquiry() method that puts the device in inquiry mode, and event listeners defined in the application then respond to the inquiry-events. The 'deviceDiscovered()' is called when a device is discovered and handles the process following and 'inquiryCompleted()' is invoked when the inquiry completes successfully or unsuccessfully. The getDiscoveryAgent() method gives a handle to the 'DiscoveryAgent' object.

DiscoveryAgent agent = local.getDiscoveryAgent();

What follows is ServiceDiscovery and Service Registration. We will look into their details in the upcoming parts of the series. For this application, we now try to connect to the server using a non-authenticated, non-encrypted connection. This is done as follows.

String conStr = agent.selectService(
new UUID("86b4d249fb8844d6a756ec265dd1f6a3", false),
ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);

Advertisment

The selectService() method performs the service discovery task here, and takes UUID (the security policy used) which is indicated using any of the fields ServiceRecord.NOAUTHENTICATE_NOENCRYPT that we have used, and ServiceRecord. AUTHENTICATE_ENCRYPT which means an encrypted service that requires authentication. The last parameter is a Boolean variable indicating if this client must be the master of the connection. Its value is 'true' if the client must is master; and 'false' if the client can be the master or the slave. Next we open a connection to the server using StreamConnection, Connector, and OutputStream classes if the service is found successfully on the server it will send 'Hello World!' message to it.

The server
The server implementation also follows the same steps. The only difference is that the tasks to be performed in a few steps are different. These include the following:

if (!local.setDiscoverable(DiscoveryAgent.GIAC)) {
f.append("Failed to change to the " +
"discoverable mode");
return;
}
StreamConnectionNotifier notifier =
(StreamConnectionNotifier) Connector.open("btspp://localhost:" +
"86b4d249fb8844d6a756ec265dd1f6a3");
StreamConnection conn = notifier.acceptAndOpen();
...
}

Advertisment

Device discovery is facilitated by providing the “btspp” protocol URL that uses the same UUID as of client. The StreamConnectionNotifier class handles the connection opening with the 'openAndAccept() method to complete the connection and accept the string message. For running the examples, you can use the emulators provided in WTK or the free emulator by 'Rococo Software' available at www.rococosoft.com. For device specific purposes, check the toolkits made available by various vendors.

In the upcoming parts of the series, we will take some advanced topics like file transfers and messaging.

Source: PCQuest

tech-news