Connecting to Bluetooth devices with Java

In this post I will show you how to use java to connect to Bluetooth devices.

To do that, I will use bluecove.
Bluecove is a JSR-82 implementation.
JSR-82 is a java specification for defining APIs for communicating with Bluetooth devices.

To use bluecove you will have to download bluecove jar.
You can download it from here.

Of course, you will also need a bluetooth device connected to your computer and enabled.


Discovering Bluetooth devices


To discover devices we need to follow these steps:
1. Get the our local BT device using blucove code.
2. Get the discovery agent from our device.
3. Start a query to search remote Bluetooth devices.


private static Object lock=new Object();

 try{
            // 1
            LocalDevice localDevice = LocalDevice.getLocalDevice();

            // 2
            DiscoveryAgent agent = localDevice.getDiscoveryAgent();
            
            // 3
            agent.startInquiry(DiscoveryAgent.GIAC, new MyDiscoveryListener());

            try {
                synchronized(lock){
                    lock.wait();
                }
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Device Inquiry Completed. ");
            
        }
        catch (Exception e) {
            e.printStackTrace();
        }



Notice that the inquiry is an asynchronous function. This is why we use the lock.wait().

Notice also that we give an object named MyDiscoveryListener as a parameter to the inquiry.

This listener will be executed when a device is found and when the inquiry is finished.

public class MyDiscoveryListener implements DiscoveryListener{
    
    @Override
    public void deviceDiscovered(RemoteDevice btDevice, DeviceClass arg1) {
        String name;
        try {
            name = btDevice.getFriendlyName(false);
        } catch (Exception e) {
            name = btDevice.getBluetoothAddress();
        }
        
        System.out.println("device found: " + name);
        
    }

    @Override
    public void inquiryCompleted(int arg0) {
        synchronized(lock){
            lock.notify();
        }
    }

    @Override
    public void serviceSearchCompleted(int arg0, int arg1) {
    }

    @Override
    public void servicesDiscovered(int arg0, ServiceRecord[] arg1) {
    }

}

The functions deviceDiscovered() and inquiryCompleted() are the ones exeuted when a device is found and when the inquiry is finished.

The other 2 functions servicesDiscovered and serviceSearchCompleted will be used in the next section.



Inquiring a device for a service


Now that we have remote devices we want to check if they support certain services, like receiving objects from other devices.

For that we need to use the discovery agent once again and also a remote device, which we found in the previous section.

             UUID[] uuidSet = new UUID[1];
             uuidSet[0]=new UUID(0x1105); //OBEX Object Push service
            
            int[] attrIDs =  new int[] {
                    0x0100 // Service name
            };

            LocalDevice localDevice = LocalDevice.getLocalDevice();
            DiscoveryAgent agent = localDevice.getDiscoveryAgent();
             agent.searchServices(null,uuidSet,device, new MyDiscoveryListener());
                
                
                try {
                    synchronized(lock){
                        lock.wait();
                    }
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                    return;
                }
                

Again here, the function searchServices() is asynchronous, and it is also takes the same listener as a parameter.
There are 3 other parameters:

  • RemoteDevice, which we discovered in the previous section.
  • An array of UUIDs. This array contains the services we wish to search. In this case we search for OBEX Object Push service, which will let us send messages to the device.
  • An array of integers which are attributes we whish to be returned, in this case we whish to get the service name as an attribute.


  • All that we have to do now is to implement the 2 listener functions we haven’t implemented yet: servicesDiscovered() and serviceSearchCompleted() .

     @Override
        public void serviceSearchCompleted(int arg0, int arg1) {
            synchronized (lock) {
                lock.notify();
            }
        }
    
        @Override
       public void servicesDiscovered(int arg0, ServiceRecord[] services) {
            for (int i = 0; i < services.length; i++) {
                String url = services[i].getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
                if (url == null) {
                    continue;
                }
                
                DataElement serviceName = services[i].getAttributeValue(0x0100);
                if (serviceName != null) {
                    System.out.println("service " + serviceName.getValue() + " found " + url);
                } else {
                    System.out.println("service found " + url);
                }
    
                   if(serviceName.getValue().equals("OBEX Object Push")){
                            sendMessageToDevice(url);                
                        }
            }
            
        }
    

    Notice that if we have a ServiceRecord we can extract a URL from it. This will be used in the next section to send a message to the device.



    Send a message to a bluetooth device


    Now that we have the URL of the service OBEX Object Push in the remote device, we can use it to send messages.

    private static void sendMessageToDevice(String serverURL){
            try{
                System.out.println("Connecting to " + serverURL);
        
                ClientSession clientSession = (ClientSession) Connector.open(serverURL);
                HeaderSet hsConnectReply = clientSession.connect(null);
                if (hsConnectReply.getResponseCode() != ResponseCodes.OBEX_HTTP_OK) {
                    System.out.println("Failed to connect");
                    return;
                }
        
                HeaderSet hsOperation = clientSession.createHeaderSet();
                hsOperation.setHeader(HeaderSet.NAME, "Hello.txt");
                hsOperation.setHeader(HeaderSet.TYPE, "text");
        
                //Create PUT Operation
                Operation putOperation = clientSession.put(hsOperation);
        
                // Sending the message
                byte data[] = "Hello World !!!".getBytes("iso-8859-1");
                OutputStream os = putOperation.openOutputStream();
                os.write(data);
                os.close();
        
                putOperation.close();
                clientSession.disconnect(null);
                clientSession.close();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    




    downloaddownload source

    21 thoughts on “Connecting to Bluetooth devices with Java

    1. Pingback: Weekend project: Bluetooth multisender

    2. Hi,

      When I run your code it gives me the discovered device list but not the service list.

      Any Idea?

    3. just i like to send me sources code how to connect Bluetooth with the data base and user can accesses from the database.
      just i need a sample code.

      • i’m also gerrin the same exception..
        java.lang.NullPointerException at LocalDevice.getLocalDevice()

    4. where do I have to copy bluecove.jar? I use eclipse and I copied it in the plugins folder but the program won’t recognize javax.bluetooth.

    5. I am trying to figure out how to write code so that I can stream data simultaneously from two Bluetooth devices (a 2.0 and a 2.1) to my laptop (a 64-bit Windows 7 machine). I’ve already paired the devices to my laptop. Am I correct in thinking that your code will help me with the next step of getting my devices talking to my laptop, or is this code intended for use in the pairing process?

    6. Pingback: Bluecove Java Bluetooth Library on Windows 7 64Bit – Solved | Turkey Tunnel

    7. Thanks for above code…

      I’m able to send the JSON data but not able to receive as response. can you give the code for receiving againt sent request.

    8. how to solve Null Pointer Exception in LocalDevice.getLocalDevice() ?
      Is it the problem with my bluetooth device?

    9. I am really stupid.
      But I have Bluecove-2.1.0.jar.
      What do I do with it?
      I am using NetBeans

    10. Hi,
      Thanks for the tuto but when I run, I get this message “The import bt.BTListener cannot be resolved”.

      From where do I import your bt ?
      And how do I do this if the answer is this line ” 1. Get the our local BT device using blucove code. ”

      Thanks

    Leave a Reply

    Your email address will not be published.

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>