J2ME and Bluetooth
J2ME provides several classes to aid developers in adding Bluetooth functionality to their applications. These classes are contained within the javax.bluetooth package. The classes are used to gain information about the Bluetooth capabilities of the device on which the software is running, seek other devices and services, then make and receive connections.
One of the fundamental aims of this project is to implement a reusable package and interface, and design and demonstrate a wrapper class that can easily be re-factored for use in a diferent program. The following information will be useful for anyone wishing to delve beyond the interfaces and into the classes that will actually do the Bluetooth programming in our game.
5.1 Local Device
The LocalDevice class provides the basic functions for gaining information
about the Bluetooth capabilities of the host device. These functions include:
getBluetoothAddress(); – String
getDiscoveryAgent(); – DiscoveryAgent
getFriendlyName(); – String
The Bluetooth address is set by the device itself. The Friendly Name” is set by the user. The friendly name normally defaults to the device name, e.g. Sony Ericsson k800i”. The function returning the DiscoveryAgent is the way in which discovery services can be accessed.
Discovery and Discovery Listeners
The Discovery Agent is responsible for the discovery functions of the local device. To access the DiscoveryAgent class you must get the LocalDevice,
from a static method of the LocalDevice class and then retrieve the DiscoveryAgent:
DiscoveryAgent mDiscAg =
A DiscoveryAgent contains the functions that start and stop a device inquiry, and can register classes implementing the DiscoveryListener interface for call-back on several discovery related events. A class implementing the DiscoveryListener interface must have the following methods:
deviceDiscovered(RemoteDevice rd, DeviceClass dc) – Fired when a device is found during an inquiry. The RemoteDevice object yields the same information as the LocalDevice class, and can be used to set up connection details.
inquiryCompleted(int discType) – Fired when the inquiry phase is completed, either due to a timeout as per the device default (set by the manufacturer, adjustable by the user in some cases), or by a cancel method call on the DiscoveryAgent.
servicesDiscovered(int trans, ServiceRecord svRc) – Fired when a service search fnds new matching services. The service record array holds details of these services for further interrogation.
serviceSearchCompleted(int trans, int respCode – Fired when a service search is completed.
5.3 Searching for Services
There are several techniques that may be used when searching for devices and services. Each of these varies in processing requirements, functional application requirements, and the complexity of code required for implementation. The method with the highest reliability of yielding the intended results (i.e. discovering a device with a specifed service) allows the Bluetooth search to complete, and then searches the services of each device. This may take several seconds, depending on the Bluetooth implementations of the devices that are involved. Once a search has yielded results then the program or the user can choose the specifc device or service that they require.
A quicker method used by some programmers is to initially perform a service search, without explicitly specifying a device search to precede it. The result of this is that normally the frst matching service to be found is used, rather than presenting a list of options to the program. Programs may also terminate a device search after a particular period of time. The list of devices and services can then be retrieved by passing the static identifer ServiceRecord.CACHED to the retrieveDevices() method of the discovery agent. The agent will then use devices that are stored in the memory.
There is always a risk in using this method that the devices or services that you are seeking do not respond in time. Care must be taken to ensure that an application developer considers the required robustness and exibility of the fnal system as well as response time.
Roaming or social” applications may make use of this service search feature where it doesn’t matter which specifc device you are connected to – in fact, there may be some beneft or not choosing – e.g. date fnder, social networking software.
Publishing a Service
Publishing a service record is easy with J2ME. The MIDlet needs to register a Service Record in the Service Discovery Database. The Generic Connection Framework is used, and a StreamConnectionNotifier object is created. The connection object then opens a software connection to the localhost, using the UUID of the application. Other details can be included in the localhost connection URL, including requirements for authorisation and encryption.
The connection to the SDDB then needs to be monitored to handle incoming connections. A worker thread continuously polls the StreamConnection- Notifer using the acceptAndOpen() method. If a connection is detected then it can be passed on to a processing method which can open an InputStream or a DataInputStream object to process the incoming messages.