//----el midlet del servidor.
package SPPBluetooth;
import javax.microedition.midlet.*;
/**
* @author josorio
*/
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
public class SPPServidorMIDlet extends MIDlet implements CommandListener {
//Creamos las variables necesarias
public static SPPServidorMIDlet SPPs = null;
public static Display display;
private SPPServidor s = null;
//Constructor
public SPPServidorMIDlet() {
SPPs = this;
}
//Implementamos el ciclo de vida del MIDlet
public void startApp() {
display = Display.getDisplay(this);
s = new SPPServidor();
s.inicializar();
display.setCurrent(s);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
//Este metodo se encarga de las tareas necesarias para salir del MIDlet
public void salir() {
SPPs.destroyApp(true);
SPPs.notifyDestroyed();
SPPs = null;
}
//Manejamos la accion del usuario
public void commandAction(Command c, Displayable d) {
if (d == s && c.getLabel().equals("Salir")) {
//Salimos de la aplicacion
try {
s.fin = true;
s.servidor.close();
} catch (Exception e) {
}
salir();
}
}
}
-El servicio
package SPPBluetooth;
/**
*
* @author josorio
*/
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import javax.bluetooth.*;
import java.io.*;
public class SPPServidor extends List implements Runnable {
//Objetos Bluetooth necesarios
public LocalDevice dispositivoLocal;
public DiscoveryAgent da;
public boolean fin = false;
public StreamConnectionNotifier servidor;
//Constructor
public SPPServidor() {
super("Servidor SPP", List.EXCLUSIVE);
addCommand(new Command("Salir", Command.EXIT, 1));
setCommandListener(SPPServidorMIDlet.SPPs);
}
//Este metodo se encarga de dar un aviso de alarma cuando se produce una excepcion
public void mostrarAlarma(Exception e, Screen s, int tipo) {
Alert alerta;
if (tipo == 0) {
alerta = new Alert("Excepcion:", "Se ha producido la excepcion " + e.getClass().getName(), null,
AlertType.ERROR);
} else {
alerta = new Alert("Error:", "No ha seleccionado un dispositivo ", null, AlertType.ERROR);
}
alerta.setTimeout(Alert.FOREVER);
SPPServidorMIDlet.display.setCurrent(alerta, s);
}
//Este metodo se va a encargar de inicializar el servidor
public void inicializar() {
try {
dispositivoLocal = LocalDevice.getLocalDevice();
dispositivoLocal.setDiscoverable(DiscoveryAgent.GIAC);
//Lanzamos un hilo servidor (solo aceptara un cliente)
Thread hilo = new Thread(this);
hilo.start();
} catch (BluetoothStateException be) {
System.out.println("Se ha producido un error al inicializar el hilo servidor");
}
}
public void run() {
//Le damos un nombre a nuestra aplicacion
String nombre = "Ejemplo SPP";
//Definimos un UUID unico para este servicio. Elegimos uno a nuestro gusto.
UUID uuid = new UUID(0xABCD);
servidor = null;//Similar a un socket servidor
StreamConnection sc = null;//Similar a un socket cliente
RemoteDevice rd = null;
//Intentamos crear una conexion, usando SPP
try {
servidor = (StreamConnectionNotifier) Connector.open("btspp://localhost:" + uuid.toString()
+ ";name=" + nombre);
//Obtenemos el service record
ServiceRecord rec = dispositivoLocal.getRecord(servidor);
//Rellenamos el BluetoothProfileDescriptionList usando el SerialPort version 1
DataElement e1 = new DataElement(DataElement.DATSEQ);
DataElement e2 = new DataElement(DataElement.DATSEQ);
e2.addElement(new DataElement(DataElement.UUID, new UUID(0x1101)));//agregamos el puertoserie
e2.addElement(new DataElement(DataElement.INT_8, 1));//version 1
e1.addElement(e2);
//agregamos al service record el BluetoothProfileDescriptionList
rec.setAttributeValue(0x0009, e1);
} catch (Exception e) {
System.out.println("Se ha producido un error al lanzar el hilo servidor");
mostrarAlarma(e, this, 0);
return;
}
while (!fin) {
try {
append("Esperando mensaje:", null);
//Aceptamos conexiones del cliente y obtenemos el objeto remoto
sc = servidor.acceptAndOpen();
rd = rd.getRemoteDevice(sc);
//Obtenemos el input stream del objeto remoto
DataInputStream in = sc.openDataInputStream();
//Leemos el mensaje y lo mostramos por pantalla
append(in.readUTF(), null);
//Cerramos la conexion
sc.close();
} catch (Exception e) {
mostrarAlarma(e, this, 0);
return;
}
}
}
}
-El midlet del cliente.
package SPPBluetooth;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;
import javax.bluetooth.*;
import java.io.*;
import java.util.*;
/**
* @author josorio
*/
public class SPPClienteMIDlet extends MIDlet implements CommandListener {
//Creamos las variables necesarias
public static SPPClienteMIDlet SPPc = null;
public static Display display;
private SPPCliente c = null;
private Mensaje msg = null;
//Objetos Bluetooth necesarios
public LocalDevice dispositivoLocal;
public DiscoveryAgent da;
//Lista de dispositivos y servicios encontrados
public static Vector dispositivos_encontrados = new Vector();
public static Vector servicios_encontrados = new Vector();
public static int dispositivo_seleccionado = -1;
//Constructor
public SPPClienteMIDlet() {
SPPc = this;
}
//Implementamos el ciclo de vida del MIDlet
public void startApp() {
display = Display.getDisplay(this);
c = new SPPCliente();
msg = new Mensaje();
//Mostramos la lista de dispositivos(vacia al principio)
c.mostrarDispositivos();
display.setCurrent(c);
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
//Este metodo se encarga de las tareas necesarias para salir del MIDlet
public static void salir() {
SPPc.destroyApp(true);
SPPc.notifyDestroyed();
SPPc = null;
}
//Este metodo se encarga de dar un aviso de alarma cuando se produce una excepcion
public void mostrarAlarma(Exception e, Screen s, int tipo, String extra) {
Alert alerta = null;
if (tipo == 0) {
alerta = new Alert("Excepcion", "Se ha producido la excepcion " + e.getClass().getName() + " - "
+ "" +e.getMessage() + " T:"+extra, null,
AlertType.ERROR);
} else if (tipo == 1) {
alerta = new Alert("Error", "No ha seleccionado un dispositivo ", null, AlertType.ERROR);
} else if (tipo == 2) {
alerta = new Alert("Informacion", "El mensaje ha sido enviado ", null, AlertType.INFO);
}
alerta.setTimeout(Alert.FOREVER);
display.setCurrent(alerta, s);
}
//Manejamos la accion del usuario
public void commandAction(Command co, Displayable d) {
if (d == c && co.getLabel().equals("Busqueda")) {
//Limpiamos la lista
dispositivos_encontrados.removeAllElements();
servicios_encontrados.removeAllElements();
try {
dispositivoLocal = LocalDevice.getLocalDevice();
dispositivoLocal.setDiscoverable(DiscoveryAgent.GIAC);
da = dispositivoLocal.getDiscoveryAgent();
da.startInquiry(DiscoveryAgent.GIAC, new Listener());
c.escribirMensaje("Por favor espere...");
} catch (BluetoothStateException be) {
mostrarAlarma(be, c, 0, "busqueda");
}
} else if (d == c && co.getLabel().equals("Enviar")) {
dispositivo_seleccionado = c.getSelectedIndex();
//Nos aseguramos de que el usuario selecciono un dispositivo
if (dispositivo_seleccionado == -1 || dispositivo_seleccionado >= dispositivos_encontrados.size()) {
mostrarAlarma(null, c, 1, "");
return;
}
display.setCurrent(msg);
} else if (d == c && co.getLabel().equals("Salir")) {
salir();
} else if (d == msg && co.getLabel().equals("OK")) {
servicios_encontrados.removeAllElements();
//Buscamos el servicio de puerto serie en el dispositivo seleccionado
RemoteDevice dispositivo_remoto = (RemoteDevice) dispositivos_encontrados.elementAt(dispositivo_seleccionado);
try {
//Buscamos en el puerto serie 0x1101
da.searchServices(null, new UUID[]{new UUID(0x1101)}, dispositivo_remoto, new Listener());
} catch (BluetoothStateException be) {
mostrarAlarma(be, c, 0 , " searchservices");
}
}
}
//Este metodo se va a encargar de enviar un mensaje al primer ServiceRecord usando el
//Serial Port Profile
public void enviarMensaje(String msg) {
System.out.println(servicios_encontrados.firstElement().toString() +" LLL "+servicios_encontrados.size() );
try {
ServiceRecord sr = (ServiceRecord) servicios_encontrados.firstElement();
//Obtenemos la URL asociada a este servicio en el dispositivo remoto
String URL = sr.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
try {
//Obtenemos la conexio y el stream de este servicio
StreamConnection con = (StreamConnection) Connector.open(URL);
DataOutputStream out = con.openDataOutputStream();
//Escribimos datos en el stream
out.writeUTF(msg);
out.flush();
//Cerramos la conexion
out.close();
con.close();
mostrarAlarma(null, c, 2, "");
} catch (IOException e){
mostrarAlarma(e , c, 0, "open "+ URL);
} catch (Exception e) {
mostrarAlarma(e, c, 0, "openconection "+URL);
}
} catch (Exception e) {
mostrarAlarma(e, c, 0, "get conection");
}
}
//Implementamos el DiscoveryListener
public class Listener implements DiscoveryListener {
//Implementamos los metodos del interfaz DiscoveryListener
public void deviceDiscovered(RemoteDevice dispositivoRemoto, DeviceClass clase) {
System.out.println("Se ha encontrado un dspositivo Bluetooth");
dispositivos_encontrados.addElement(dispositivoRemoto);
}
public void inquiryCompleted(int completado) {
System.out.println("Se ha completado la busqueda de dispositivos");
if (dispositivos_encontrados.size() == 0) {
Alert alerta = new Alert("Problema", "No se ha encontrado dispositivos", null, AlertType.INFO);
alerta.setTimeout(3000);
c.escribirMensaje("Presione descubrir dispositivos");
display.setCurrent(alerta, c);
} else {
c.mostrarDispositivos();
display.setCurrent(c);
}
}
public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {
System.out.println("Se ha encontrado un servicio remoto a");
for (int i = 0; i < servRecord.length; i++) {
// ServiceRecord record = servRecord[i];
servicios_encontrados.addElement(servRecord[i]);
}
}
public void serviceSearchCompleted(int transID, int respCode) {
System.out.println("Terminada la busqueda de servicios");
//Si encontramos un servicio, lo usamos para mandar el mensaje(todos los
//servicios que hemos buscado son de puerto serie)
if (servicios_encontrados.size() > 0) {
enviarMensaje(msg.getString());
} else {
//Si no encontramos ningun servicio de puerto serie
c.mostrarDispositivos();
display.setCurrent(c);
}
}
}
}
-Implementacion cliente
package SPPBluetooth;
/**
*
* @author josorio
*/
import javax.microedition.lcdui.*;
import javax.bluetooth.*;
public class SPPCliente extends List {
public SPPCliente() {
super("Cliente SPP", List.EXCLUSIVE);
addCommand(new Command("Busqueda", Command.SCREEN, 1));
addCommand(new Command("Enviar", Command.SCREEN, 1));
addCommand(new Command("Salir", Command.EXIT, 1));
this.setCommandListener(SPPClienteMIDlet.SPPc);
}
//Este metodo se encarga de limpiar la pantalla y de mostrar un mensaje
public void escribirMensaje(String str) {
for (int i = 0; i < this.size(); i++) {
delete(i);
}
append(str, null);
}
//Este metodo muestra los "friendly names" de los dispositivos remotos
public void mostrarDispositivos() {
for (int i = 0; i < this.size(); i++) {
delete(i);
}
if (SPPClienteMIDlet.dispositivos_encontrados.size() > 0) {
for (int i = 0; i < SPPClienteMIDlet.dispositivos_encontrados.size(); i++) {
try {
RemoteDevice dispositivoRemoto = (RemoteDevice) SPPClienteMIDlet.dispositivos_encontrados.elementAt(i);
append(dispositivoRemoto.getFriendlyName(false), null);
} catch (Exception e) {
System.out.println("Se ha producido una excepcion");
}
}
} else {
append("Pulse Busqueda", null);
}
}
}
La clase mensaje
import javax.microedition.lcdui.*;
public class Mensaje extends TextBox {
public Mensaje() {
super("Introducir mensaje", "Hola Mundo", 50, TextField.ANY);
addCommand(new Command("OK", Command.SCREEN, 1));
this.setCommandListener(SPPClienteMIDlet.SPPc);
}
}