A continuación, y como muestra de frikismo, os presento el código asociado a la comunicación bluetooth entre un terminal móvil y un GPS.
Funciona, os lo aseguro. Si no me creéis, probadlo. Mola.
Funciona, os lo aseguro. Si no me creéis, probadlo. Mola.
/* TITULO DE LA APLICACIÓN: practicaGPS
AUTOR: FoN
DESCRIPCIÓN: Generación de una clase que va a crear una conexión bluetooth con un GPS bluetooth y éste le va a responder
con la posición geográfica en que nos encontramos (latitud, elevación, longitud y orientación)
VERSIÓN: 1.0 */
/* Librerías necesarias */
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.bluetooth.*;
import java.io.*;
import javax.microedition.io.*;
/* Creación de la clase que extiende de MIDlet e implementará las interfacez CommandListener y DiscoveryAgent
Estas interfaces sirven para la comunicación de órdenes al terminal (CommandListener tiene asociado un método abstracto commandAction implementado más abajo) y para el descubrimiento y tratamiento de terminales bluetooth (DiscoveryAgent) */
public class AplicacionGPS extends MIDlet implements CommandListener, DiscoveryListener
{
private Display pantalla;
private Command salir, buscar;
private Form formulario;
private List lista;
private LocalDevice local;
private DiscoveryAgent agente;
private TextBox infoPos;
private StreamConnection conn;
private InputStream in;
/* CONSTRUCTOR: creamos todos los elementos necesarios al iniciar la aplicación */
public AplicacionGPS()
{
/* Inicializamos el objeto Displayable a null */
pantalla = null;
/* Creamos la orden SALIR */
salir = new Command("Salir", Command.EXIT, 0);
/* Ponemos el formulario como pantalla activa */
formulario = new Form("Informacion del dispositivo local");
formulario.addCommand(salir);
/* Se crea un lista de dispositivos */
lista = new List("Lista de dispositivos", Choice.IMPLICIT);
lista.addCommand(salir);
lista.setCommandListener(this);
/* Si no se encuentran dispositivos conocidos, se buscan y se añaden a la lista */
buscar = new Command("Buscar", Command.OK, 1);
formulario.addCommand(buscar);
formulario.setCommandListener(this);
/* Objeto TextBox */
infoPos = new TextBox("Posicion geografica", "Buscando...", 50, TextField.ANY);
infoPos.addCommand(salir);
infoPos.setCommandListener(this);
}
/* Método para pausar la aplicación en curso (se necesita declarar, pues implementamos una interfaz y este método es abstracto) */
public void pauseApp() {}
/* Cuando salimos de la aplicación, cerramos la conexión con el GPS */
public void destroyApp(boolean t)
{
try
{
if (conn!=null) conn.close();
if (in!=null) in.close();
}
catch(IOException ioex) {}
}
/* Método implementado para comenzar la aplicación */
public void startApp()
{
if (pantalla == null)
{
/* Obtenemos las características de la pantalla del terminal */
pantalla = Display.getDisplay(this);
/* Y le ponemos como pantalla activa un objeto de la clase Form */
pantalla.setCurrent(formulario);
try
{
/* Obtenermos las características del terminal local */
local = LocalDevice.getLocalDevice();
agente = local.getDiscoveryAgent();
/* Y la mostramos por la pantalla activa */
getInfo();
}
/* Capturamos la excepción BluetoothStateException */
catch (BluetoothStateException bse) {}
}
}
/* Implementación del método abstracto asociado a la interfaz CommandListener */
public void commandAction(Command c, Displayable d)
{
if (c == salir)
{
destroyApp(true);
notifyDestroyed();
}
/* Vemos si buscamos dispositivos */
else if (c == buscar)
{
/* Borramos los elementos de la lista para iniciar el Inquiry */
lista.deleteAll();
try
{
/* Iniciamos el Inquiry (busqueda de dispositivos bluetooth mediante APIs) */
agente.startInquiry(DiscoveryAgent.GIAC, this);
}
catch(BluetoothStateException bse)
{
formulario.append("Error de dispositivo BT");
}
}
/* O si seleccionamos un elemento de la lista de entre los dispositivos encontrados o ya conocidos */
else if (c == List.SELECT_COMMAND)
{
try
{
/* Obtenemos su dirección bluetooth */
String dir = lista.getString(lista.getSelectedIndex());
/* Y abrimos la conexión bluetooth para la comunicación de datos */
/* El GPS siempre será un esclavo, por lo que únicamente obtendremos datos de él */
conn = (StreamConnection)Connector.open("btspp://"+dir+":1", Connector.READ);
in = conn.openInputStream();
/* Si la apertura fue satisfactoria, pasamos a obtener los parámetros para mostrar */
if ((conn != null)&&(in != null)) escucharGPS();
}
catch (IOException ioex) {}
/* Y ponemos como pantalla activa el TextBox donde veremos los datos a mostrar */
pantalla.setCurrent(infoPos);
}
}
/* Este método obtiene la información de los terminales remotos y se pone él en modo Discoverable, para poder
ser descubierto por otros dispositivos */
void getInfo()
{
formulario.append(local.getBluetoothAddress() + "\n");
int modoI = local.getDiscoverable();
String modoS = "";
switch(modoI)
{
case DiscoveryAgent.GIAC: modoS = "GIAC";
break;
case DiscoveryAgent.LIAC: modoS = "LIAC";
break;
case DiscoveryAgent.NOT_DISCOVERABLE: modoS = "No descubierto";
break;
}
formulario.append(modoS + "\n");
formulario.append(local.getFriendlyName() + "\n");
formulario.append(local.getProperty("bluetooth.master.switch") + "\n");
formulario.append(local.getProperty("bluetooth.api.version"));
try
{
local.setDiscoverable(DiscoveryAgent.GIAC);
}
catch(BluetoothStateException bse){}
}
/* Método que pone al terminal en modo escucha
No es más que la invocación a un Thread que nos va a capturar información del GPS para tratarla */
private void escucharGPS()
{
Thread thr = new Thread()
{
public void run()
{
try
{
StringBuffer informacion = new StringBuffer();
int dato;
while(in.read() != (int)'$');
while((dato = in.read()) != 13) informacion.append((char)dato);
String temp = informacion.toString();
String infoGPS = temp.substring(0, temp.length() - 1);
/* De entre las muchas tramas que puedo recibir, sólo trato 2 en concreto que
me mostrarán el posicionamiento de mi terminal, el resto las descarto */
if ((infoGPS.indexOf("GPRMC") == 0) || (infoGPS.indexOf("GPGGA") == 0) presentarInfo(infoGPS);
else escucharGPS();
}
catch(IOException ioex) {}
}
};
thr.start();
}
/* Método que me va a presentar por pantalla los detalles del posicionamiento que he descrito en el inicio.
Evidentemente, cada trama tiene un formato que debe ser conocido de antemano para poder tratarlas de manera
adecuada y seleccionar la información que cada uno quiera mostrar */
void presentarInfo(String cadena)
{
String latitud, longitud, a, b;
int i = cadena.indexOf(',');
System.out.println ("i = " + i + " " + cadena.substring(0, i));
if (cadena.substring(0, i).compareTo("GPRMC") == 0)
{
i = cadena.indexOf(',');
i = cadena.indexOf(',' , i + 1);
i = cadena.indexOf(',', i + 1);
/* Latitud*/
latitud = cadena.substring(i+1, cadena.indexOf(',', i+1));
/* Elevación */
i = cadena.indexOf(',', i + 1);
a = cadena.substring(i+1, cadena.indexOf(',', i+1));
if (a.compareTo("N") == 0) a = "Norte";
else a = "Sur";
/* Longitud */
i = cadena.indexOf(',', i + 1);
longitud = cadena.substring(i+1, cadena.indexOf(',', i+1));
/* Orientación */
i = cadena.indexOf(',', i + 1);
b = cadena.substring(i+1, cadena.indexOf(',', i+1));
if (b.compareTo("E") == 0) b = "Este";
else b = "Oeste";
}
else
{
i = cadena.indexOf(',');
/* Latitud*/
i = cadena.indexOf(',' , i + 1);
latitud = cadena.substring(i+1, cadena.indexOf(',', i+1));
/* Elevación */
i = cadena.indexOf(',', i + 1);
a = cadena.substring(i+1, cadena.indexOf(',', i+1));
if (a.compareTo("N") == 0) a = "Norte";
else a = "Sur";
/* Longitud */
i = cadena.indexOf(',', i + 1);
longitud = cadena.substring(i+1, cadena.indexOf(',', i+1));
/* Orientación */
i = cadena.indexOf(',', i + 1);
b = cadena.substring(i+1, cadena.indexOf(',', i+1));
if (b.compareTo("E") == 0) b = "Este";
else b = "Oeste";
}
/* Mostramos la información relevante con respecto a las 2 tramas validadas */
infoPos.setString("Latitud: " + latitud + ", " + a + "\n" + "Longitud: " + longitud + ", " + b);
}
/* Conjunto de métodos asociados a la interfaz DiscoveryAgent, que hay que declarar al usar Inquiry para
buscar dispositivos */
/* Estos 2 métodos hay que declararlos (ya que son métodos abstractos de la interfaz DiscoveryAgent), pero en
este caso, no es necesaria su implementación */
public void servicesDiscovered(int transID, ServiceRecord[] rd) {}
public void serviceSearchCompleted(int transID, int tipo) {}
/* Método que me inserta por el frente de una lista las direcciones bluetooth de los dispositivos encontrados
en el Inquiry */
public void deviceDiscovered(RemoteDevice rd, DeviceClass dc)
{
lista.insert(0, rd.getBluetoothAddress(), null);
}
/* Método asociado al Inquiry que me mostrará por la pantalla activa la dirección bluetooth de los dispositivos
encontrados, en caso de existir alguno */
public void inquiryCompleted(int tipo)
{
if (lista.size() == 0)
{
lista.insert(0, "No hay dispositivos al alcance", null);
lista.addCommand(buscar);
}
pantalla.setCurrent(lista);
}
}
Ahí es nada.
FoN