bluetooth music store

Upload: casonova20

Post on 30-May-2018

223 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/9/2019 Bluetooth Music Store

    1/12

  • 8/9/2019 Bluetooth Music Store

    2/12

    Bluetooth boogies, Part 2: Creating the Bluetooth Music Store http://www-128.ibm.com/developerworks/wireless/library/wi-boo

    of 12 11/7/05

    As you can see from Figure 1, the server application is ready and waiting for clients to connect, so let'sfind out how to build the OBEX client application.

    Creating an OBEX client application

    As you can see in Figure 2, FileClient.java looks a lot like FileServer.java , so I'll skip the

    details ofFileClient.java for now.

    Figure 2. FileClient.java at startup

  • 8/9/2019 Bluetooth Music Store

    3/12

    Bluetooth boogies, Part 2: Creating the Bluetooth Music Store http://www-128.ibm.com/developerworks/wireless/library/wi-boo

    of 12 11/7/05

    Now, as I stated in Part 1 of this series, Bluetooth clients have a lot more work to do in comparison withBluetooth servers -- and if you think about it for a second, you'll understand why. First of all, how doesthe client know where to find the server? (Don't worry, this problem exists for every Bluetoothclient/server application; it's not unique to your situation). In order for any Bluetooth client to find aBluetooth server, the client must first discover it.

    Bluetooth device discovery

    DeviceDiscoverer.java is a helper application used by FileClient.java to find any remote

    Bluetooth devices in the vicinity. Listing 1 provides the import statements, class declarations, and theconstructor ofDeviceDiscoverer.java.

    Listing 1. Import statement and constructor for DeviceDiscoverer.java

    import javax.bluetooth.*;import java.util.*;

    public class DeviceDiscoverer implements DiscoveryListener {

    FileClient client;Vector remoteDevices = new Vector();

    DiscoveryAgent discoveryAgent;

    public DeviceDiscoverer(FileClient client) {

    this.client = client;try {

  • 8/9/2019 Bluetooth Music Store

    4/12

    Bluetooth boogies, Part 2: Creating the Bluetooth Music Store http://www-128.ibm.com/developerworks/wireless/library/wi-boo

    of 12 11/7/05

    LocalDevice localDevice = LocalDevice.getLocalDevice();discoveryAgent = localDevice.getDiscoveryAgent();

    client.updateStatus("[client:] LocalDevice properties: " +localDevice.getFriendlyName() +" (" + localDevice.getBluetoothAddress() + ")");

    client.updateStatus("[client:]Searching for Bluetooth devices in the vicinity...");

    discoveryAgent.startInquiry(DiscoveryAgent.GIAC, this);} catch(Exception e) {

    e.printStackTrace();}

    }

    As you can see in Listing 1, DeviceDiscoverer.java implements

    javax.bluetooth.DiscoveryListener . This way, the helper class gets notified when a remote

    Bluetooth device is discovered. To start the device discovery process, you need to first get an instance ofjavax.bluetooth.LocalDevice , which allows you to get an instance of

    javax.bluetooth.DiscoveryAgent. After you have instantiated a DiscoveryAgent, you're

    free to call discoveryAgent.startInquiry(), which starts the device discovery process.

    You may also notice in Listing 1 that LocalDevice has some pertinent information about your own

    Bluetooth device, such as its friendly name (like "Bruce's laptop" or "Joe's PDA"). LocalDevice also

    knows your 6-byte Bluetooth address; for instance, 00:0A:3E:56:57:B5. For informational purposes,DeviceDiscoverer.java displays that information before it enters the discovery process.

    If you refer back to Figure 2, you'll see that FileClient.java has three buttons, of which one of

    them is aptly named Discover Devices. When you click on the Discover Devices button, you'll instantiatethe helper class, DeviceDiscoverer.java . If you're new to Bluetooth, you may assume that the

    device discovery process is instantaneous. Unfortunately, it isn't.

    However, the good news is that because the helper class, DeviceDiscoverer.java, is a

    DiscoveryListener , it is notified asynchronously when Bluetooth devices are found. For each

    remote Bluetooth device found in the vicinity, the Java Virtual Machine (JVM) calls thedeviceDiscovered() method. When the device discovery process has ended, the JVM also calls the

    inquiryCompleted() method. Listing 2 and Listing 3 demonstrate the code for

    deviceDiscovered() and inquiryCompleted().

    Listing 2. DeviceDiscoverer.deviceDiscovered()

    public void deviceDiscovered(RemoteDevice remoteDevice, DeviceClass cod) {

    try{ remoteDevices.addElement(remoteDevice);client.updateStatus("[client:] New device discovered : " +remoteDevice.getFriendlyName(true)+ " (" +remoteDevice.getBluetoothAddress() + ")" );

    } catch(Exception e){e.printStackTrace();

    }

    }

  • 8/9/2019 Bluetooth Music Store

    5/12

    Bluetooth boogies, Part 2: Creating the Bluetooth Music Store http://www-128.ibm.com/developerworks/wireless/library/wi-boo

    of 12 11/7/05

    Listing 3. DeviceDiscoverer.inquiryCompleted()

    public void inquiryCompleted(int discType) {String inqStatus = null;

    if (discType == DiscoveryListener.INQUIRY_COMPLETED) {

    inqStatus = "[client:] Inquiry completed";} else if (discType == DiscoveryListener.INQUIRY_TERMINATED) {

    inqStatus = "[client:] Inquiry terminated";} else if (discType == DiscoveryListener.INQUIRY_ERROR) {

    inqStatus = "[client:] Inquiry error";}

    client.updateStatus(inqStatus);client.serviceButton.setEnabled(true);client.deviceButton.setEnabled(false);

    }

    As you can see in Listing 2, whenever a new Bluetooth device is discovered, I just add it to a Vector anddisplay the friendly name and Bluetooth address of the remote device. When the device discovery processhas ended, I update the client with status of the discovery process, whether it succeeded or failed. Figure3 shows FileClient.java after it has instantiated DeviceDiscoverer.java and has

    discovered all the Bluetooth devices in the vicinity.

    Look at FileClient.java after the discovery process.

    Figure 3. FileClient.java after the discovery process

  • 8/9/2019 Bluetooth Music Store

    6/12

    Bluetooth boogies, Part 2: Creating the Bluetooth Music Store http://www-128.ibm.com/developerworks/wireless/library/wi-boo

    of 12 11/7/05

    OK, it looks like there's a slight problem. According to Figure 3, there are four remote Bluetooth devicesin the area, but how do we know which one of them is running FileServer.java? Good question.

    That's where service discovery comes in very handy. And don't worry, I have another helper class that I'llintroduce to you that will aid in the search for the specific service that I want.

    Bluetooth service discovery

    Listing 4 contains the import statements, class declaration, and constructor forServiceDiscoverer.java.

    Listing 4. Import statement and constructor for ServiceDiscoverer.java

    import javax.bluetooth.*;import java.io.*;import java.util.Vector;

    public class ServiceDiscoverer extends Thread implements DiscoveryListener { UUID[] uuidSet = {new UUID("8841", true)};

    int[] attrSet = {0x0100, 0x0003, 0x0004};

    FileClient client;ServiceRecord serviceRecord;String connectionURL;Vector deviceList;

  • 8/9/2019 Bluetooth Music Store

    7/12

  • 8/9/2019 Bluetooth Music Store

    8/12

    Bluetooth boogies, Part 2: Creating the Bluetooth Music Store http://www-128.ibm.com/developerworks/wireless/library/wi-boo

    of 12 11/7/05

    that I iterated over the Vector of remote Bluetooth devices and searched for the services that exist on eachdevice.

    These examples were tested on real Bluetooth hardware, so you should see that as I iterated through theVector, I "backed off" for two seconds before I continued through the loop. The "backing off" perioddepends on your hardware; you may not need it at all. Without it though, your Bluetooth hardware mayonly search for services on the first remote Bluetooth devices that you pass in, and it may ignore theothers. For each service that matches the UUID, the JVM calls the servicesDiscovered() method,

    which is shown in Listing 6.

    Listing 6. ServiceDiscoverer.servicesDiscovered()

    public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {

    for(int i = 0; i < servRecord.length; i++) {

    DataElement serviceNameElement = servRecord[i].getAttributeValue(0x0100);String serviceName = (String)serviceNameElement.getValue();

    if(serviceName.equals("FTP")){client.updateStatus("[client:] A matching service has been found");

    try {

    connectionURL = servRecord[i].getConnectionURL(1,false);} catch (Exception e){

    client.updateStatus("[client:] oops");}

    client.updateStatus("[client:] The connection URL is: " + connectionURL );client.serviceButton.setEnabled(false);client.connButton.setEnabled(true);

    }}

    }

    You may recall from Part 1 that the UUID is mandatory and the service name is optional for all Bluetoothservers; however, we specified that the service name for our service would be "FTP." As you can see inListing 6, I'm checking to see if the service name is FTP, but just remember that every Bluetooth servicemay not specify a service name. After I've determined that a matching service has been found, I store theconnection URL in a String and display some information on the client. A screenshot ofFileClient.java after the service searching process is shown in Figure 4.

    Figure 4. FileClient.java after the service searching process

  • 8/9/2019 Bluetooth Music Store

    9/12

    Bluetooth boogies, Part 2: Creating the Bluetooth Music Store http://www-128.ibm.com/developerworks/wireless/library/wi-boo

    of 12 11/7/05

    Aha! So according to Figure 4, I've found a matching service and it exists on the ibook. You may noticethat although I found a matching service on the ibook, I continued to iterate through the Vector andsearch for services. As you can see, the two helper classes came in very handy in order to get theconnection URL to the server. Now that I have the URL to the server, let's connect and send a file to theserver!

    Connecting to the server and sending a file

    To keep the code FileClient.java as clean as possible, I isolated all the OBEX client code into a

    file named ObjectPusher.java. Of course, ObjectPusher.java is multithreaded so that it

    won't hang the GUI application during the file-transfer process. Listing 7 shows the code forObjectPusher.run().

    Listing 7. ObjectPusher.run()

    public void run(){

    try{connection = Connector.open(connectionURL);client.updateStatus("Connection obtained");

    ClientSession cs = (ClientSession)connection;HeaderSet hs = cs.createHeaderSet();

    cs.connect(hs);

    client.updateStatus("OBEX session created");

    InputStream is = new FileInputStream(file);byte filebytes[] = new byte[is.available()];is.read(filebytes);is.close();

    hs = cs.createHeaderSet();hs.setHeader(HeaderSet.NAME, file.getName());hs.setHeader(HeaderSet.TYPE, "text/plain");hs.setHeader(HeaderSet.LENGTH, new Long(filebytes.length));

  • 8/9/2019 Bluetooth Music Store

    10/12

    Bluetooth boogies, Part 2: Creating the Bluetooth Music Store http://www-128.ibm.com/developerworks/wireless/library/wi-boo

    0 of 12 11/7/05

    Operation putOperation = cs.put(hs);client.updateStatus("Pushing file: " + file.getName());client.updateStatus("Total file size: " + filebytes.length + " bytes");

    OutputStream outputStream = putOperation.openOutputStream();outputStream.write(filebytes);client.updateStatus("File push complete");

    outputStream.close();

    putOperation.close();

    cs.disconnect(null);

    connection.close();} catch (Exception e){}

    }

    Obviously, the main purpose ofObjectPusher.java is to push a file from a client to the server. I

    start off by taking the connection URL and creating a connection object. With the connection in place,I'm able to create the OBEX session.

    The next step is to convert the file that I want to send into a byte array. Afterwards, the OBEX headers areset and the OBEX PUT operation is initiated by the call to cs.put(). This returns a

    javax.obex.Operation object, which I named putOperation. An OutputStreamwas then

    created in order to send the file data, and the PUT operation was completed when the byte array waswritten to the OutputStream. Figure 5 shows FileClient.java after the file transfer process.

    Figure 5. FileClient.java after the file transfer process

  • 8/9/2019 Bluetooth Music Store

    11/12

    Bluetooth boogies, Part 2: Creating the Bluetooth Music Store http://www-128.ibm.com/developerworks/wireless/library/wi-boo

    1 of 12 11/7/05

    In conclusion: Creating the Bluetooth Music Store

    In Part 1, you learned how to create an OBEX server application. In this article, you learned how tocreate a very versatile OBEX client application. You've seen that OBEX clients are more difficult tocreate, but this article presented a few helper classes to aid you in the device discovery and servicediscovery processes. Figure 6 shows a simple application that I call the Bluetooth Music Store.

    Figure 6. The Bluetooth Music Store

    It's a modified version ofFileClient.java that uses the helper classes

    DeviceDiscoverer.java, ServiceDiscoverer.java, and ObjectPusher.java. With

    the Bluetooth Music Store, you can select a song or ringtone in MP3 format and push it to any phone,PDA, or computer that supports OBEX. Cool, huh?

    So why do I call it a "Music Store?" Well, of course, if you own the rights to any music file, ringtone, orpodcast, then you can easily use this application as a foundation to make a kiosk application and sell youraudio files. Enjoy!

    Resources

    Learn

    Part 1 of this series "Bluetooth boogies, Part 1: File transfer with JSR-82 and OBEX"(developerWorks, September 2005) shows how JSR-82 and OBEX can be used to transfer filesfrom client to server.

    IBM is a member of the Bluetooth SIG (Special Interest Group). The Bluetooth specifications canbe obtained at the Bluetooth SIG Web site.

    "SIM Access Profile" (developerWorks, April 2003) is an excellent article on the Bluetooth SIMAccess profile that covers the basics of the profile and also included some example scenarios.

    In "Securing the air: The PDA of tomorrow" (developerWorks, May 2002) Kim Getgen from RSAwrote an article about advanced security using Bluetooth.

    "Syncing data" (developerWorks, October 2001) provides an overview of the open industryspecification for data synchronization that delivers a uniform synchronization protocol for

  • 8/9/2019 Bluetooth Music Store

    12/12

    Bluetooth boogies, Part 2: Creating the Bluetooth Music Store http://www-128.ibm.com/developerworks/wireless/library/wi-boo

    2 of 12 11/7/05

    connecting multiple devices over any network to any data store.

    "SyncML intensive" (developerWorks, April 2002) walks you through the steps of a two-wayclient/server SyncML procedure.

    "The PalmOS data collection series" (developerWorks, November 2001) explores the keyingredients in developing data-collection applications for wireless devices.

    "SyncML device management" (developerWorks, April 2003) shows you how to managedata-exchange on wireless devices without having to commit to a proprietary protocol.

    Get more ideas and expertise on wireless technology in the developerWorks Wireless technologyzone.

    Get products and technologies

    Download the FileClient, FileServer, and Bluetooth Music Store Application, all three used in thisarticle, in a ZIP file.

    The Open OBEX Project is crafting an open source implementation of the Object Exchange

    protocol, a session protocol that can best be described as a binary HTTP protocol.

    The examples in this article were created using the JB-22 Java Bluetooth Development kit. TheJB-22 is a complete Java Bluetooth development kit featuring both Bluetooth hardware andsoftware, starting at $199.

    Discuss

    Get involved in the developerWorks community by participating in developerWorks blogs.

    About the author

    Bruce Hopkins is the author of the book, Bluetooth for Java (Apress) and is the creator of theJB-22 developer kit. He graduated from Wayne State University in Detroit with a B.S. degreein Electrical and Computer Engineering. He currently works as a Technical Architect forGestalt LLC and focuses on distributed computing, Web services, and wireless technologies. Hecan be contacted at [email protected].