Descubriendo dispositivos Bluetooth con Java y BlueCove

Introducción.

Después de la fallida búsqueda de una librería para acceder al protocolo Bluetooth desde Mono vuelvo entonces a Java buscando la opción mas portable posible.  Esta vez voy a probar BlueCove que soporta Mac OSX, WIDCOMM, BlueSolei, Windows nativo y Linux con BlueZ.

Instalación.

Descargar las últimas versiones disponibles desde la siguiente ubicación: http://sourceforge.net/project/showfiles.php?group_id=114020

  1. bluecove-*.jar: módulo principal, incluye el soporte para las pilas de Mac OS X, WIDCOMM, BlueSoleil and Microsoft Bluetooth.
  2. bluecove-gpl-*.jar: adiciona el soporte para la pila en Linux.

Descargar estos archivos JAR en una ubicación conocida.

Descubriendo dispositivos Bluetooth.

Para esto se parte de un objeto que implementa DiscoveryListener, él define que se debe hacer cuando cuando se encuentra un nuevo dispostivo y cuando se termina la búsqueda.

        /**
         * The DiscoveryListener interface allows an application to
         * receive device discovery and service discovery events.
         */

        DiscoveryListener listener = new DiscoveryListener()
        {
            /**
             * Called when a device is found during an inquiry.
             */

            public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
            {
                System.out.println("Device " + btDevice.getBluetoothAddress() + " found");

                devicesDiscovered.addElement(btDevice);

                try
                {
                    System.out.println("     name " + btDevice.getFriendlyName(false));
                }
                catch (IOException cantGetDeviceName) {}
            }

            /**
             * Called when an inquiry is completed.
             */

            public void inquiryCompleted(int discType)
            {
                System.out.println("Device Inquiry completed!");

                synchronized(inquiryCompletedEvent)
                {
                    inquiryCompletedEvent.notifyAll();
                }
            }
            // Not used in this example.

            public void serviceSearchCompleted(int transID, int respCode) {}
            public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {}
        };

En este ejemplo, cuando se identifica a un nuevo dispositivo Bluetooth (ver deviceDiscovered) se obtiene su dirección, de ser posible su nombre y se agrega en la lista de dispositivos encontrados.

public static final Vector<RemoteDevice> devicesDiscovered = new Vector<RemoteDevice>();

Para ejecutar finalmente la búsqueda de dispositivos de acuerdo con el comportamiento definido anteriormente, se crea un objeto sobre el cual se sincronizarán las próximas acciones.

final Object inquiryCompletedEvent = new Object();

synchronized(inquiryCompletedEvent)
{
         // The search code ...
}

Con él se inicia la búsqueda de dispositivos accediendo al Agente Descubridor del Dispositivo Local.

boolean started = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, listener);

Finalmente se verifica que la búsqueda haya comenzado exitosamente y se espera para garantizar su ejecución.

     if (started)
     {
          System.out.println("Starting Device Discovery process ...");

          /**
           * Wait for Discovery Process end
           */

          inquiryCompletedEvent.wait();

          System.out.println("There was " + devicesDiscovered.size() +  " device(s) found");
     }

Compilación & ejecución.

Para compilar y posteriormente ejecutar el programa de demostración es necesario garantizar que el JAR de bluecove, descargado inicialmente, se encuentre en el CLASSPATH.  También es necesario recordar que si la plataforma objetivo es Linux, es necesario incluír además el JAR de bluecove-gpl.

Para compilar se utiliza un comando preparado de la siguiente manera.

javac -cp ../lib/current/bluecove-2.1.0.jar:../lib/current/bluecove-gpl-2.1.0.jar RemoteDeviceDiscovery.java

Debe tenerse en cuenta que para la compilación se está suponiendo que los archivos JAR se encuentran en el directorio ../lib/current y que corresponden con la versión 2.1.0.   Además se está realizando en Linux, motivo por el cual el separador de directorios es : en lugar del ; utilizado por Windows.  Es necesario que adapte el comando según sus características específicas.

Para interpretar se utiliza un comando similar, preparado de la siguiente manera.

java -cp ../lib/current/bluecove-2.1.0.jar:../lib/current/bluecove-gpl-2.1.0.jar RemoteDeviceDiscovery

La salida de la aplicación.

La aplicación de demostración deberá imprimir por salida estándar la información de los dispositivos Bluetooth que se encuentren cerca durante el tiempo que dure la búsqueda.  Algo similar a lo siguiente.

BlueCove version 2.1.0 on bluez
Starting Device Discovery process …
Device 001ADE8BF510 found
name Jimezam Phone
Device 0017AE39DCB0 found
name Nintendo RVL-CNT-01

Device Inquiry completed!
There was 2 device(s) found
BlueCove stack shutdown completed

En la respuesta anterior se puede apreciar que la aplicación detectó exitosamente a mi teléfono celular y a un Wiimote que pasaba por allí.

Enlaces.

16 thoughts on “Descubriendo dispositivos Bluetooth con Java y BlueCove”

  1. Discula al ejecutar el programa tengo el siguiente problema:

    Exception in thread “main” java.lang.NoClassDefFoundError: RemoteDeviceDiscovery
    Caused by: java.lang.ClassNotFoundException: RemoteDeviceDiscovery
    at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
    Could not find the main class: RemoteDeviceDiscovery. Program will exit.

  2. Hola!

    Yo también tengo ese problema :s, y bueno aparte también lo trate de hacer con neatbeans y me sale que no puede cargar la clase nativa.
    Native Library bluecove not available.

    1. Saludos @Adrián, yo creo que el problema es que no tienes instalado el paquete de desarrollo. Dependiendo de la plataforma que utilices se debe llamar algo así como bluez-libs-devel, libbluetooth-dev, bluetooth-dev o bluez-dev.

  3. Disculpa pero me salio la siguiente exepcion
    run:
    Exception in thread “main” java.lang.UnsatisfiedLinkError: com.intel.bluetooth.BluetoothStackMicrosoft.getLibraryVersion()I
    at com.intel.bluetooth.BluetoothStackMicrosoft.getLibraryVersion(Native Method)
    at com.intel.bluetooth.BlueCoveImpl.detectStack(BlueCoveImpl.java:450)
    at com.intel.bluetooth.BlueCoveImpl.access$500(BlueCoveImpl.java:65)
    at com.intel.bluetooth.BlueCoveImpl$1.run(BlueCoveImpl.java:1020)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.intel.bluetooth.BlueCoveImpl.detectStackPrivileged(BlueCoveImpl.java:1018)
    at com.intel.bluetooth.BlueCoveImpl.getBluetoothStack(BlueCoveImpl.java:1011)
    at javax.bluetooth.LocalDevice.getLocalDeviceInstance(LocalDevice.java:75)
    at javax.bluetooth.LocalDevice.getLocalDevice(LocalDevice.java:95)
    at busca.Main.main(Main.java:100)
    Java Result: 1

    1. Saludos @andres. El código me funcionó sin problemas en Linux y no lo he probado en Windows así que no sabría que decirte. A primera vista parecen ser problemas con el stack de BT que utilizas (BluetoothStackMicrosoft), parecería que no incluye los métodos necesarios (getLibraryVersion por ejemplo).

  4. hola, me funciono perfecto en windows, y queria preguntar si tenian algun ejemplo de envio de archivos mediante bluetooth

  5. Hola amigo muchas gracias por este tutorial, tengo el mismo problema de alguien por aqui.

    Exception in thread “main” java.lang.NoClassDefFoundError: RemoteDeviceDiscovery
    Caused by: java.lang.ClassNotFoundException: RemoteDeviceDiscovery
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    Could not find the main class: RemoteDeviceDiscovery. Program will exit.

    Ya verifique que mi archivo se llame RemoteDeviceDiscovery.java, compila chevre, pero cuando voy a ejecuatr me da ese problema. Espero me pueda ayudar.

  6. Eduardo, probablemente te esté faltando incluír al directorio actual (o donde se encuentre la clase) en el CLASSPATH. Puedes hacer esto en el parámetro -cp de la invocación a “java”.

  7. Jorge:solo quiero implementar java from Bluetooth
    x z
    its poosible but Acer Windows 2003 adaptad 2005
    tanks ,.del javax.bluetooth tutorial… atte Vienna

  8. hola pedon se me presento este problema :

    Native Library intelbth not avalable on platform linux
    Exception in thread “main” java.lang.UnsatisfiedLinkError: com.intel.bluetooth.BluetoothPeer.initializationStatus()I
    at com.intel.bluetooth.BluetoothPeer.initializationStatus(Native Method)
    at com.intel.bluetooth.BluetoothPeer.(BluetoothPeer.java:102)
    at com.intel.bluetooth.BlueCoveImpl.(BlueCoveImpl.java:55)
    at com.intel.bluetooth.BlueCoveImpl.(BlueCoveImpl.java:38)
    at com.intel.bluetooth.BlueCoveImpl$SingletonHolder.(BlueCoveImpl.java:50)
    at com.intel.bluetooth.BlueCoveImpl.instance(BlueCoveImpl.java:60)
    at javax.bluetooth.LocalDevice.(LocalDevice.java:45)
    at javax.bluetooth.LocalDevice.getLocalDevice(LocalDevice.java:78)
    at RemoteDeviceDiscovery.main(RemoteDeviceDiscovery.java:88)

    esto es en el momenot de ejecutarlo en linux por liena de comandos en el terminal, adicional ya instale esos paquetes anteriores de los otros ocmentariso pero me sigue dando el mismo error

Leave a Reply

Your email address will not be published. Required fields are marked *