Advertisment

Bluetooth Programming with Java

author-image
PCQ Bureau
New Update

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.

Advertisment

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.

Advertisment

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.

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);


}





Advertisment

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();

Advertisment

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.

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();

Advertisment

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);

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.

Advertisment

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();


...


}








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.

Advertisment