miércoles, 31 de octubre de 2007

JSendMe

Bueno, como ya he empezado a desarrollar la aplicación en sí, lo que es el interfaz, creación de diagramas de flujos, me he permitido el lujo de bautizarla.

En un principio pensé llamarla JSend, (J de Java y de Jose) pero ya hay una aplicación así por internet, que te permite enviar formularios a través de Javascript (Tendré que mirar como va eso).

La segunda versión es JSendMe, y me gusta mucho más, el "Me" tiene el doble sentido de "A mi" y de "MicroEdition"...muahaha

En la imagen está la primera pantalla de la aplicación en la versión 0.1, todavía no hay mucho más, pero poco a poco voy a haciendo el esqueleto del proyecto.

Divide y vencerás.

FileSystem

Una de las cosas que me abrumaba enormemente era:

Si tengo que obtener un fichero del móvil, desde el MIDlet, para enviarlo...¿Como lo saco? ¿Habrá alguna API que me permita manejar ficheros?

La respuesta es ¡¡si!!

La API se llama FileConnnection (JSR 75) y mediante ella, podremos ver las carpetas del móvil, los ficheros e interactuar con ellos...ya tengo lo necesario para crearme mi propio "explorador" en el móvil y empotrarlo en la aplicación...

En cuanto tenga más información, escribiré algo más por aquí. También he de deciros que hay una API para obtener los números de la agenda de contactos...yeah!!

lunes, 29 de octubre de 2007

Enlaces de interés

El "Nokia forum" es el lugar perfecto para encontrar maravillas como las siguientes:

Manual para usar conexiones bluetooth mediantes RFCOMM y OBEX

Manual para usar Sockets y Datagramas con J2ME

Son simplemente geniales. El primer documento es el que tengo ahora entre manos. Sublime, no se me ocurre otra palabra.

jueves, 25 de octubre de 2007

OBEX

Una vez asentadas las bases de una comunicación bluetooth y habiendo visto y jugado con RFCOMM y L2CAP, ya va siendo hora de meterse en algo más serio:

OBEX (OBjet EXChange)

Obex es un protocolo de comunicaciones que permite que datos/objetos sean transferidos entre dos dispositivos. Estos dispositivos ya pueden estar conectados físicamente o no.

Dominando este protocolo, podremos hacer intercambio de archivos por bluetooth e infrarrojos.

sábado, 20 de octubre de 2007

viernes, 19 de octubre de 2007

Comunicaciones I

Una de las grandes ventajas que tiene J2ME (ya que parece que todo son inconvenientes, siempre optimizando, y mirando por los recursos) es la capacidad que tiene para conectarse con "el mundo exterior".

Hay muchas formas de conectarse mediante un MIDlet, pero todas ellas derivan de la clase "Connector".

Mediante la clase Connector, podemos realizar cualquier tipo de conexión sin preocuparnos de como está implementado el protocolo necesario.

La conexión es tan simple como:

Connector.open("protocolo:direccion;parametros");

De esta forma podemos conectarnos vía http, por sockets, datagramas, SPP (Serial Port Profile), ya hablaré de ellos más adelante.

En mis ejemplos y pruebas de envío de mensajes de móvil a móvil y de móvil a PC, he usado los interfaces:

InputConnection,OutputConnection y StreamConnectionNotifier.


StingBuffer url = new StringBuffer("bspp://localhost:")
StreamConnection con = (StreamConnection) Connector.open(url);
OutputStream out = con.openOutputStream();
InputStream in = con.openInputStream();


La dirección "btspp://" ya que uso el mecanismo de conexión SPP, en el cual obtendremos un InputStream y un OutputStream. Mediante este método de conexión enviamos y recibimos streams.


Java a tope: J2ME

Siempre que leo este manual no puedo evitar acordarme del Videojuego de Vicentín: Siempre a tope 5.0 (de ahí, viene el "5.0" del nombre del blog).

Pero bueno, no iba a hablar de los Chanantes.

Los profesores Sergio Gálvez Rojas y Lucas Ortega Díaz de la universidad de Málaga han confeccionado este hermoso manual de J2ME para aquellos que quieran empezar a programar para móviles:

Java a tope: J2ME

Está muy interesante, aunque se queda algo corto para mí.

Todos aquellos que quieran más información sobre el tema, que contacten conmigo, tengo manuales y libros en pdf para dar y tomar.

sábado, 13 de octubre de 2007

Estructura de aplicación Cliente.

Una vez que haces un par de aplicaciones cliente, ya son casi todas iguales, pero en definitiva la estructura básica se resumen en:

->startApp()

Método indispensable del MIDlet, en el que se inicializan las variables, ponemos la pantalla que se van a mostrar a lo largo de la aplicación, creamos los comandos que vamos a usar en nuestra aplicación y (una cosa muy importante) inicializar el bluetooth local.

->pauseApp()

Bueno, en este método meteremos todo aquello que debe ocurrir en caso que el MIDlet pase a estado de "pausa" (si recibimos una llamada, el programa se pasará a estado "pausa")

->destroyApp()

Aquí, irán todas aquellas "rutinas" que deben ocurrir cuando el MIDlet se "destruye", en otras cuentas, cuando cerramos el programa.

Ahora viene el método que recoge los "Comandos".

Los comandos son eventos que ocurren cuando el usuario interacciona con el móvil. Supongamos que tenemos un menú, con 2 opciones, una de ellas es "buscar dispositivos bluetooth" la otra es "Salir", pues cuando pulsemos sobre "Buscar dispositivos bluetooth" se lanzará un evento que irá al método:

->commandAction()

"Acciones de los comandos", como comentaba arriba, en este método se recogen los eventos, y aquí ya hacemos lo que queramos con ellos. Continuando con el ejemplo anterior, si nos llega el evento que hemos creado para la opccion de "buscar dispositivos...", pues haremos una cosa, en caso que nos llegue el evento de "Salir" haremos otra.

Este método anterior es como...un "Switch", por lo menos yo lo veo así. Nos llegan eventos y dependiendo del evento que sea ya lo "enviamos" a otro lugar, a otra función para que haga cosas especificas.

Por aquí en medio crearía un método que se dedique a realizar la búsqueda de dispositivos, con un startInquiry(...) (Comienzo de búsqueda).

Cada vez que un dispositivo sea descubierto, este método se ejecutará automáticamente:

->deviceDiscovered(RemoteDevice remoteDevice, DeviceClass clase)

Aquí nos encargamos de hacer lo necesario con el dispositivo encontrado: guardarlo en un array, buscar sus servicios asociados, mostrar sus datos...todo lo que queramos.

->inquiryCompleted()

Cuando la búsqueda se ha realizado por completo, se ha parado por algún error o se ha cancelado, se llama a este método, aquí ya mostramos los mensajes correspondientes y realizamos las acciones que creamos convenientes.

->servicesDiscovered(int transID, ServiceRecord[] servRecord)

Método que se llama automáticamente cuando un servicio ha sido descubierto, los servicios se guardan y encapsulan en DataElements (sistema de encapsulamiento que todavía me cuesta majenar.

->serviceSearchCompleted

Una vez que se ha acabado la búsqueda de servicios, ya sea por cancelación del usuario, por fallo o simplemente que ha terminado, este método será llamado automáticamente.



Pues eso, esto es más o menos la estructura de una aplicación cliente, con sus variantes, claro...

martes, 9 de octubre de 2007

Cliente -> Servidor

Poco a poco voy cogiéndole la estructura a esto. Los últimos programas que estoy implementando (o intentándolo por lo menos) son del tipo.

Un "servidor" móvil, que ofrece unos servicios, un "cliente" que busca esos servicios para obtener "algo".

Servidor.

El programa "servidor" debe encargarse de ofrecer unos servicios "al mercado", los programas servidores suelen ser simples, especificas los atributos y los servicios encapsulandolos en un ServiceRecord (que todavía me cuesta visualizar), ejecutas un hilo y en un método "run", pones tu servidor en marcha.

El programa cliente es más complicado, debe realizar la búsqueda de dispositivos, contemplar todos los casos, y a continuación, buscar los servicios de dichos dispositivos.

Un ejemplo simple pero bastante intuitivo.

Tenemos un "servidor" que tiene funciones de impresión, está conectado a una red de impresoras y ofrece esos servicios.
Cada impresora tiene sus características, pueden ser b/n, a color... pues en la especificación de los servicios del servidor, creamos atributos específicos para cada impresora. Ofrecemos un servicio por cada impresora, y estos servicios están caracterizados por sus atributos (blanco y negro, color, calidad de impresión).

Nosotros, como clientes, hacemos una búsqueda de servicios en este servidor, y nos quedamos con lo que nos interesa. Si vamos a imprimir un documento, pues nos da igual que la impresora es b/n o color, pero si vamos a imprimir una imagen nos interesaría más seleccionar la impresora de color.


En definitiva, esto es lo que estoy haciendo últimamente, creando "servidores" que ofrezcan servicios. Me está costando trabajo, solo por el echo de no llegar a comprender del todo el encapsulamiento y el tratado de los "serviceRecord"...aunque poco a poco lo vaya entendiendo mejor.

martes, 2 de octubre de 2007

Descubrimiento de dispositivos bluetooth

Para descubrir un dispositivo Bluetooth en una aplicación java, se ha de usar la función, startInquiry() , este método requiere la especificación de un “Listener”, este Listener será notificado cuando se hayan encontrado dispositivos reales.

Si por el contrario ya tenemos conocimiento de la existencia de dispositivos en el entorno, y además tenemos dichos dispositivos almacenados como dispositivos “pre-known”, para no realizar un Inquiry o búsqueda usamos la función retrieveDevices(). Esta función devuelve la lista de dispositivos encontrados en una búsqueda anterior, o dispositivos almacenados como “conocidos”.


El método deviceDiscovered() debe ser implementado en un “Listener”, ya que cada vez que se encuentra un dispositivo en una búsqueda, se hace la llamada a este método, por eso, en la función startInquiry() es necesario la especificación de un Listener.

Cuando una búsqueda se ha completado o cancelado, el sistema hace una llamada a la función, InquiryCompleted().

Propiedades del dispositivo bluetooth

Cada dispositivo, dependiendo de la marca y del vendedor, necesita ser configurado de forma diferente. Para ellos usamos los parámetros del dispositivo.

La API JSR82 define que las propiedades del dispositivo pueden ser llamadas usando la función


LocalDevice.getProperty().


Estas propiedades dan información sobre el sistema Bluetooth, además de las posibles restricciones que tenga el dispositivo por su implementación.


Algunas propiedades:


bluetooth.api.version->Versión de la API del dispositivo.

bluetooth.connected.devices.max->Número máximo de dispositivos que pueden ser conectados

bluetooth.master.switch->¿Es posible la conmutación master/slave?