How to discover bluetooth devices using J2ME
Author : Abernala
From TechnologicalWiki
Contents |
[edit] Introduction
While the Bluetooth hardware had grown a lot, until recently there was no way to develop Java applications Bluetooth, until Java Specification Request 82 (JSR 82) appeared, which standardized ways to develop Bluetooth applications using Java. The goal of this specification is to define the architecture and the associated APIs required to enable an open, third party Bluetooth application development environment.
[edit] API Overview
This API is designed to operate on top of the Connected, Limited Device Configuration (CLDC), which is described in Connected, Limited Device Configuration (JSR 30) or Connected, Limited Device Configuration 1.1 (JSR 139).
[edit] Requeriments
Thi API for Bluetooth devices that are designed to meet the following characteristics:
- At least 512K of free memory (ROM and RAM) (applications require additional memory).
- Connectivity to the wireless Bluetooth.
- Have an implementation of J2ME CLDC.
[edit] Capabilities of JSR 82
The API is intended to provide the following capabilities:
- Register services
- Discover devices and services
- Establish RFCOMM, L2CAP, and OBEX connections between devices
- Using those connections, send and receive data (voice communication not supported)
- Manage and control the communication connections
- Provide security for these activities
[edit] API Architecture
JSR 82 requires that the Bluetooth stack underlying a JSR 82 implementation be qualified for the Generic Access Profile (GAP[1]), the Service Discovery Application Profile (SDAP[2]), and the Serial Port Profile (SPP[3]). The stack must also provide access to its Service Discovery Protocol (SDP[4]), and to the RFCOMM[5] and L2CAP[6] layers.
The APIs are designed in such a way that developers can use the Java programming language to build new Bluetooth profiles on top of this API as long as the core layer specification does not change. To promote this flexibility and extensibility, the specification is not restricted to APIs that implement Bluetooth profiles. JSR 82 includes APIs for OBEX and L2CAP so that future Bluetooth profiles can be implemented in Java, and these are already being used for that purpose. Figure 1 shows where the APIs defined in this specification fit in a CLDC/MIDP architecture.
[edit] Device discovery
An application may obtain a list of devices using either startInquiry() (non-blocking) or retrieveDevices() (blocking). The startInquiry() method requires the application to specify a listener; this listener is notified when new devices are found from a real inquiry. If an application does not wish to wait for an inquiry to begin, the API provides the retrieveDevices() method that returns the list of devices that were already found via a previous inquiry or devices that are classified as pre-known. This method does not perform an inquiry, but provides a quick way to get a list of devices that may be in the area.
[edit] Device Discovery Classes
[edit] interface javax.bluetooth.DiscoveryListener
This interface allows an application to specify an event listener that will respond to inquiry-related events. This interface is also used for service searching. The method deviceDiscovered() is called each time a device is found during an inquiry. When the inquiry is completed or canceled, the inquiryCompleted() method will be called. This method receives as an argument either the INQUIRY_COMPLETED, INQUIRY_ERROR or INQUIRY_TERMINATED constant to differentiate between completed, error or canceled inquiries.
[edit] interface javax.bluetooth.DiscoveryAgent
This class provides methods for service and device discovery. For device discovery, this class provides the startInquiry () method to place the local device in inquiry mode and the retrieveDevices() method to return information about devices that were found via previous inquiries performed by the local device. It also provides a way to cancel an inquiry via the cancelInquiry() method.
[edit] Example Code
Bluetooth.java
import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.bluetooth.*;
import java.util.*;
public class Bluetooth {
private static Display mDisplay;
/*** Bluetooth class instance ***/
public static Bluetooth mBluetooth;
public LocalDevice mLocalDevice;
public DiscoveryAgent da;
/*** Vector with Devices found ***/
public static Vector ListFoundDevices = new Vector();
/*** To check if devices search is completed ***/
public boolean bDevicesSearchCompleted = false;
/*** Constructor ***/
public Bluetooth(){
mBluetooth = this;
}
/**
* Shows an alert when an exception has ocurred
* @param e Exception
* @param s Screen
* @param iType Exception type
*/
public void showAlert(Exception e, Screen s, int iType){
Alert alert;
if(iType == 0){
alert = new Alert("Exception","The exception has ocurred: "+e.getClass().getName(), null, AlertType.ERROR);
}else{
alert = new Alert("Error","Device not selected ", null, AlertType.ERROR);
}
alert.setTimeout(Alert.FOREVER);
mDisplay.setCurrent(alert,s);
}
/**
* Search remote bluetooth devices
* @return Vector List of devices found
*/
public Vector searchBluetoothDevices(){
try{
ListFoundDevices.removeAllElements();
mLocalDevice = LocalDevice.getLocalDevice();
// Set device in General Discoverable Mode
// General/Unlimited Inquiry Access Code (GIAC)
mLocalDevice.setDiscoverable(DiscoveryAgent.GIAC);
da = mLocalDevice.getDiscoveryAgent();
da.startInquiry(DiscoveryAgent.GIAC,new Listener());
while(!bDevicesSearchCompleted)
{
}
bDevicesSearchCompleted = false;
return ListFoundDevices;
}catch(BluetoothStateException e){
//showAlert(e, mDevice,0);
return ListFoundDevices;
}
}
/**
* Discovery listener handler
*/
public class Listener implements DiscoveryListener{
/**
* Called when device is found during inquiry
* @param remoteDevice RemoteDevice
* @param clase class
*/
public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass clase){
System.out.println("A new Bluetooth device found");
ListFoundDevices.addElement(remoteDevice);
}
/**
* Called when Inquiry is completed
* @param completed int
*/
public void inquiryCompleted(int completed){
System.out.println("Devices search completed");
bDevicesSearchCompleted = true;
if(ListFoundDevices.size()==0){
Alert alert = new Alert("Attention","Devices not found",null, AlertType.INFO);
alert.setTimeout(3000);
}
}
}
}
[edit] References
- JSR 82: Java APIs for Bluetooth
- JSR 30: J2METM Connected, Limited Device Configuration
- JSR 139: Connected Limited Device Configuration 1.1
[edit] Notes
- ↑ Generic Access Profile (GAP) provides the basis for all other profiles.
- ↑ Service Discovery Application Profile (SDAP) describes how an application should use SDP to discover services on a remote device. SDAP requires that any application be able to find out what services are available on any Bluetooth enabled device it connects to. More info here.
- ↑ Serial Port Profile (SPP) defines how to set up virtual serial ports and connect two Bluetooth enabled devices.
- ↑ Service Discovery Protocol (SDP) enables network devices, applications, and services to seek out and find other complementary network devices, applications, and services needed to properly complete specified tasks. More info here.
- ↑ The RFCOMM protocol emulates the serial cable line settings and status of an RS-232 serial port and is used for providing serial data transfer. RFCOMM connects to the lower layers of the Bluetooth protocol stack through the L2CAP layer. More info here.
- ↑ The Bluetooth logical link control and adaptation protocol (L2CAP) supports higher level protocol multiplexing, packet segmentation and reassembly, and the conveying of quality of service information. More info here.


