One of the first steps in implementing Bluetooth applications on Java ME devices is the discovery process. In a nutshell, the discovery process is the process by which Bluetooth-enabled devices find each other, and then handshake to find out the services that they can each support. The next step, invariably, is learning how to send data between these paired devices.
In this tech tip, I will show you how to create a MIDlet that will search for devices and services, and then will allow the user to send a simple note to one of the found devices. I have tested and verified that the MIDlet works on a Nokia N95 device, and that it connects to a computer running Windows Vista, with Bluetooth support enabled.
I have broken down the whole process into the following steps:
- Start the discovery process.
- Query the devices found in the discovery process for supported services.
- Initiate and process an OBEX data exchange using the supported service URL.
Step 1: Start the discovery process
The discovery process is used to tell the local Bluetooth stack that it should look within the nearby vicinity for any Bluetooth devices that are available for pairing. In the case of the MIDlet, this stack will be the implementation provided by your device provider for JSR 82.
This process of discovery is initiated by the discovery agent present in the local device, as shown in the following code.
// get the local discovery agent
agent = LocalDevice.getLocalDevice().getDiscoveryAgent();
// start the inquiry for general unlimited inquiry
agent.startInquiry(DiscoveryAgent.GIAC, this);
Once the discovery agent has started the discovery process, it will call various callback methods on a class that implements the DiscoveryListener interface. In our case, this is our MIDlet class.
Specifically, four methods of this interface must be implemented, two of which are interest to us in the discovery phase: deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) and inquiryCompleted(int discType). These two methods handle the discovery of a device and completion of the discovery process, respectively. As shown in the following code from the MIDlet, we
use these methods to append our UI with devices as they are discovered and when the process is completed.
public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
try {
// add the devices using the friendly names
listofDevices.append(btDevice.getFriendlyName(false), null);
// add to the devices hashtable
devices.put(new Long(listofDevices.size()), btDevice);
} catch(Exception ex) { handleError(ex); }
}
public void inquiryCompleted(int discType) {
// once the inquiry is completed, show the list of devices to the user
if(listofDevices.size() == 0) {
display.setCurrent(nothing, noteBox);
} else {
display.setCurrent(listofDevices);
}
}
Step 2: Start the service discovery on discovered devices
Since our aim in this tip is to allow data transfer from our MIDlet to a compatible device, we need to find services on the discovered devices that enable this goal. To do so, we need to specify the correct attributes and UUIDs in our service discovery process. The following code shows how to do so:
agent.searchServices(
null,
new UUID[] {new UUID(0x1105L)}, // we want the OBEX PUSH Profile
device,
this);
As you may guess, the code uses the local agent that we had used earlier to search for devices. We are not after a particular set of attributes, so we pass null as the first parameter, but the UUID must be OBEX PUSH profile, as this is the most open way of transferring data.
We talked about the DiscoveryListener interface which has two other methods that can be used to employ discovered services. These two methods are servicesDiscovered(int transID, ServiceRecord[] servRecord) and serviceSearchCompleted(int transID, int respCode). As the names
suggest, the first method is called each time a service is discovered, while the second method is called when the service process has completed.
Each time a service is discovered, we need to find out the connection URL for that particular service on the respective device. This connection URL will be used to make the OBEX connection for putting our data across, and consists of the Bluetooth hardware address of the device, among other things. In the code below, this connection URL is retrieved in the servicesDiscovered method:
String connURL = servRecord[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
With this connection URL, we can now move to the process of transferring our data across to the discovered device.
Step 3: Send data using OBEX PUT
In this MIDlet, we are going to allow the user to type some text as a note, and then send that across using the discovered device/service. To do so, we will need the connection URL we got in the previous step (and of course, the note data as a String).
// open a client session
ClientSession clientSession =
(ClientSession) Connector.open(connURL);
// connect using no headers
clientSession.connect(null);
if(rHeaders.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
// the connection could not be established
handleError(
new Exception("Remote client returned invalid response code: " +
rHeaders.getResponseCode()));
return;
}
// if we are here, then response code was ok
// create a new set of headers
HeaderSet headers = clientSession.createHeaderSet();
headers.setHeader(
HeaderSet.LENGTH,
new Long(noteBox.getString().length()));
headers.setHeader(HeaderSet.NAME, "myNote.txt");
headers.setHeader(HeaderSet.TYPE, "text/plain");
// create an operation using the headers we have just created
Operation op = clientSession.put(headers);
// on this operation, create the output stream
OutputStream out = op.openOutputStream();
// and send the note
out.write(noteBox.getString().getBytes());
To send the data, a client session is opened and a connection established with empty headers. At this point, your target device will ask for confirmation of receipt of data from a new device. It may also ask you for a passkey if you have never paired the devices before.
Once the connection is established, some headers that explain the purpose of the data are created, and a new Operation created with these headers. The Operation is then used to send the data via the available OutputStream.
The received note will be available in the default Bluetooth exchange folder on the target device.
Resources
- Source code as a Netbeans project
- Bluetooth JSR 82 API
I can not download Java by Sun. I need it to be able to play mt pogo games. HELP!!HELP!!
Posted by Belinda on March 27, 2009 at 08:21 PM PDT #
Download Java here <http://java.sun.com/javase/downloads/> or here <http://java.com/>. Thanks.
Posted by Christine Dorffi on March 27, 2009 at 08:27 PM PDT #
How can I send files via Bluetooth. Is it possible to send jar files via BT.
And this was a nice post
thanks a lot..
Posted by iftee on March 31, 2009 at 01:06 PM PDT #
Bluetooth APIs are here: http://java.sun.com/javame/reference/apis/jsr082/
Some introductory articles on Bluetooth:
- http://developers.sun.com/mobility/midp/articles/bluetooth1/
- http://developers.sun.com/mobility/apis/articles/bluetoothintro/
- http://developers.sun.com/mobility/apis/articles/bluetoothobex/
- http://developers.sun.com/mobility/apis/articles/bluetooth_gps/part1/
Posted by Christine Dorffi on March 31, 2009 at 07:40 PM PDT #
I get an error on Nokia Series 40 when running this midlet - says javax/obex/Operation cannot be loaded?
Posted by wotcha on April 03, 2009 at 01:24 PM PDT #
wotcha:
It probably means that the Series 40 phone that you are trying to use it on doesn't have the Bluetooth API. Check with Nokia for the phone specifications for your phone.
Regards,
Vikram
Posted by Vikram on April 03, 2009 at 05:16 PM PDT #
Thanks.
Posted by Omar on April 14, 2009 at 11:02 AM PDT #
Nice and clear.
Posted by Alfas on April 21, 2009 at 06:08 PM PDT #
Asi de esta manera, Java ayuda de forma completa para transferencias de archivos de forma que no exista un rose. De forma inalambrica, sin tener que usar un Infrarrojo
Posted by 166.210.19.104 on April 22, 2009 at 10:18 AM PDT #
6
Posted by 홍기택 on April 22, 2009 at 07:08 PM PDT #
Thanks very simple and clear
Posted by Kiran Raja on April 22, 2009 at 07:50 PM PDT #
<script>
alert("Hello");
</script>
Posted by 118.169.64.191 on April 23, 2009 at 12:26 PM PDT #
great
Posted by 122.160.174.149 on April 29, 2009 at 09:52 AM PDT #
hi friends
Posted by ravi kumar on May 21, 2009 at 12:36 AM PDT #
I am using motorola mobile and its java enabled..
but I am not able to program it...
I am beginner.. in mobile programming..
how I can start this ...
Can some one guide..
If yes pls mail me on marmik.csi@gmail.com
I am positively curious to implement all my ideas om mobile applications...
:)
Posted by marmik bhavsar on May 28, 2009 at 11:23 PM PDT #
I recommend that you check the Java Mobility Forums at http://forums.sun.com/category.jspa?categoryID=22
Posted by Christine Dorffi on May 29, 2009 at 12:11 AM PDT #
when i open BluetoothTechTip it comes up with a reference error...
I go to fix and it says:
Problem: The project uses the Java Platform called "Sun Java(TM) Wireless Toolkit 2.5.2 for CLDC", but this platform was not found.
Solution: Click Resolve and create new platform called "Sun Java(TM) Wireless Toolkit 2.5.2 for CLDC".
but i have WTK2.5.2_01
how do i fix this problem?
Posted by Ian Burns on June 05, 2009 at 09:03 AM PDT #
Hi Ian,
Are you trying to run it in Netbeans? Have you got the WTK installed within Netbeans?
That could be the reason why it is telling you that error.
Regards,
Vikram
Posted by Vikram Goyal on June 05, 2009 at 09:51 PM PDT #
Hey Ian,
The problem is that the NetBeans project included with this Tech Tip is looking specifically for WTK2.5.2, and unfortuntely you have WTK2.5.2_01. Since you have a different version, the easy solution is to create a new NetBeans project and copy the BluetoothTechTip.java file in your new project. This solution should also work for Sun Java ME SDK 3.0 users who don't want to install the WTK.
Thanks,
Bruce
Posted by Bruce Hopkins on June 07, 2009 at 09:16 PM PDT #
Can we send jar files?
Posted by praveen baid on July 28, 2009 at 07:04 AM PDT #
Yes,
And that makes this capability extremely powerful since you can provision an app to another device. Now, please be forewarned that not every mobile device will allow users to install apps over Bluetooth.
Posted by Bruce Hopkins on July 28, 2009 at 07:33 AM PDT #