Вы находитесь на странице: 1из 29

UT3

PROGRAMACIN DE APLICACIONES PARA


DISPOSITIVOS MVILES (II).
1.Paquetes opcionales para Java ME.
Aqu tienes algunos de los paquetes opcionales para Java ME ms conocidos:
Wireless Messaging API (WMA). JSR-120, JSR-205. API de mensajera inalmbrica.
Para el envo de mensajes SMS y MMS.
Bluetooth API. JSR-82. API para la comunicacin por Bluetooth.
Personal Information Management and File Connection API. JSR-75. Acceso a la
lista de contactos del dispositivo y al sistema de archivos.
Mobile Media API (MMAPI). JSR-135. Soporte de audio y vdeo. Reproduccin y
captura.
Location API. JSR-179. Localizacin geogrfica del dispositivo, mediante GPS u otros
mecanismos.
Mobile 3D Graphics. JSR-184. Soporte de grficos 3D.
J2ME Web Services API (WSA). JSR-172. Soporte de servicios web en dispositivos
mviles.
Security and Trust Services API. JSR-177. Tratamiento de informacin privada,
ejecucin segura, identificacin, autentificacin, etc.

1.2.- Sun Java Wireless Toolkit.


La plataforma Sun Java Wireless Toolkit contiene una gran cantidad de herramientas y
utilidades que, en la plataforma que incluye Netbeans inicialmente (Java Platform
Micro Edition SDK), no siempre estn disponibles. Entre esas herramientas se
encuentra la consola de mensajera inalmbrica (para trabajar con el envo y
recepcin de mensajes cortos y multimedia en el emulador), control del Bluetooth,
gestin de contenidos y del sistema de archivos, etc.

2.- Aplicaciones multihilo.


En ms de una ocasin necesitars que tu aplicacin realice varias tareas al mismo
tiempo. Esto puede conseguirse mediante el uso de distintos hilos (o threads o hebras) de
ejecucin en el programa.
Una aplicacin multihilo contendr al menos dos hilos (flujos de ejecucin diferentes)
que podrn ejecutarse de manera ms o menos independiente y simultnea. La plataforma
Java ME proporciona la posibilidad de construir y ejecutar aplicaciones multihilo al igual
que tambin lo haca Java SE, aunque con algunas limitaciones.
2.1.- El modelo de hilos en Java ME.
Las mquinas virtuales que proporciona la plataforma Java ME permiten la ejecucin de
aplicaciones multihilo utilizando los mismos mecanismos que la plataforma Java SE (clase
Thread, interfaz Runnable, objetos synchronized, mtodos wait y notify, etc.).
Tanto la clase Thread como la interfaz Runnable estn disponibles en el paquete java.lang.
No es necesario por tanto ningn paquete opcional para poder trabajar con el modelo de hilos
de Java ME.

2.2.- Creacin de midlets multihilo.


Una aplicacin multihilo (o multihebra o multithread) es una aplicacin que contiene
varios segmentos de cdigo (al menos dos) que pueden ser ejecutados concurrentemente.
Toda aplicacin multihilo tiene un hilo principal que es lanzado por la mquina
virtual en el momento en que la aplicacin empieza a ejecutarse. Desde ese hilo
principal se irn creando el resto de hilos del programa y ser el ltimo que termine

su ejecucin. Cuando finalice el hilo principal, finalizar el programa.


En Java existen dos formas de crear nuevos hilos de ejecucin:
1 Mediante la implementacin de la interfaz Runnable.
2 Mediante la extensin (herencia) de la clase Thread.
Si decides implementar la interfaz Runnable para dotar a tu aplicacin de varios hilos
de ejecucin puedes seguir los siguientes pasos:
Declarar una clase que implemente la interfaz Runnable.
Sobrescribir el mtodo run de la interfaz Runnable, que contendr el cdigo que se desea
ejecutar en el hilo de ejecucin independiente.
Crear un objeto de esa clase.
Crear un objeto de la clase Thread (hilo) utilizando el objeto recin creado como parmetro
para el constructor del Thread.
Llamar al mtodo start del hilo (thread) recin creado. A partir de ese momento se
ejecutar el mtodo run en un hilo de ejecucin diferente al hilo principal desde el
cual se ha creado.
Si haces la otra opcin (crear una clase que herede de Thread) podras hacerlo as:
Declarar una clase que herede de la clase Thread.
Sobrescribir el mtodo run, que contendr el cdigo que se desea ejecutar en el hilo.
Crear un objeto de esa clase (ser el nuevo hilo).
Llamar al mtodo start del hilo recin creado.

3.- Mecanismos de persistencia (I). Sistemas de gestin de registros.


La plataforma Java ME proporciona, al menos, dos mecanismos de almacenamiento y
recuperacin de informacin para el perfil MIDP:
Mediante el sistema RMS (Record Management System), donde el almacenamiento
tiene lugar en la memoria interna del dispositivo.
Mediante el sistema de gestin de archivos en memoria externa (paquete opcional
JSR-75, tambin conocido como "PDA Optional Packages for the Java ME Platform").
El sistema RMS o sistema de gestin de registros est basado en almacenes de
informacin implementados sobre bases de datos estructuradas en registros. Estos
almacenes de registros permiten a las aplicaciones almacenar informacin en una zona de la
memoria del dispositivo.
Si lo que se desea es acceder al sistema de archivos de una memoria externa inserta en el
dispositivo (tarjetas SD, MMC, etc.), ser necesario recurrir al paquete opcional JSR-75.
3.1.- El sistema de gestin de registros (RMS).
Un almacn de registros o Record Stores consiste en un conjunto de registros que
permanece en la memoria no voltil del dispositivo, sin ser borrada (persistente),
aun cuando el midlet que la ha creado haya finalizado su ejecucin. La mquina
virtual del dispositivo es la responsable de mantener la integridad de los Record
Store creados por un midlet, para que puedan volver a ser utilizados en el futuro
cuando ese midlet vuelva a ejecutarse.
Los almacenes son creados en ubicaciones dependientes de la plataforma a las
cuales no tienen acceso directo los midlets.
El sistema de gestin de registros (RMS) proporciona un mecanismo de
almacenamiento de datos persistente a travs de una base de datos de registros. Las
herramientas necesarias para poder trabajar con este sistema de almacenamiento (clases,
interfaces y excepciones) se encuentran en el paquete javax.microedition.rms y son las
siguientes:

Clases
RecordStore

Interfaces
RecordComparator
RecordEnumeration
RecordFilter
RecordListener

Excepciones
InvalidRecordIDException
RecordStoreException
RecordStoreFullException
RecordStoreNotFoundException
RecordStoreNotOpenException

Un almacn de registros o RecordStore est representado por un objeto de la clase


RecordStore, cuyas principales caractersticas son:
Cada almacn (RecordStore) contiene un conjunto de registros (record).
Los nombres de los almacenes deben ser nicos para una suite de midlets.
Los nombres de los RecordStore son "case sensitive" (sensibles a maysculas y
minsculas).
Si una suite de midlets (o conjunto de midlets) es eliminada del dispositivo en el que
est instalada, se eliminarn tambin todos los almacenes vinculados a ella.
Un midlet puede acceder a un RecordStore creado por otro midlet de su misma
suite (siempre que tenga permiso para ello).
Los RecordStore mantienen adems un nmero de versin que va siendo
incrementado cada vez que se produce alguna operacin que modifica los
contenidos del almacn. Del mismo modo, si un midlet utiliza varios hilos para
acceder a un almacn de registros, la responsabilidad de coordinar ese acceso
para garantizar la coherencia de la informacin almacenada en el RecordStore
ser del propio midlet.
3.2.- Estructura de un almacn de registros.
Un RecordStore est formado por un conjunto de registros. Cada registro est formado
por dos elementos:
Un identificador de registro (RecordID), que es un nmero entero que determina de
forma unvoca (clave primaria) al registro.
Los datos almacenados en el registro, que son un array de bytes.
Cuando un registro se borra, su identificador no se vuelve a utilizar, de manera
que los registros de un almacn pueden no tener identificadores consecutivos
dado que pueden ir siendo borrados.
Todo almacn de registros tiene los siguientes atributos:
Nombre, que debe ser nico para una suite. Puede obtenerse a travs del mtodo
getName de la clase RecordStore.
Nmero de versin. Nmero entero que se va actualizando segn se realizan
operaciones (insercin, borrado, actualizacin) sobre los registros del
almacn. Este nmero de versin le sirve a los midlets para saber si otro
proceso o hilo ha modificado un determinado RecordStore. Puede obtenerse a
travs del mtodo getVersion.
Marca temporal (timestamp). Nmero entero largo (long) que representa el
instante en el que se ha realizado la ltima operacin sobre el almacn.
Puede obtenerse a travs del mtodo getLastModified. Se utiliza el formato Unix de
timestamp (nmero de milisegundos transcurridos desde el 1 de enero de 1970).

3.3.- Gestin de un almacn de registros.


Las operaciones generales (abrir, cerrar, eliminar, etc.) ms importantes que se pueden
realizar con un almacn de registros (RecordStore) son:
Crear un RecordStore. Puedes usar el mtodo esttico openRecordStore. No se
dispone de constructores.
Eliminar un RecordStore. Para ello dispones del mtodo (tambin esttico)
deleteRecordStore.
Abrir la comunicacin con un RecordStore: mtodo openRecordStore. Este
mtodo abre un Record Store con el nombre que se le haya pasado como
parmetro (String) o bien lo crea si no existe. Existen varias versiones de este mtodo

(mtodo sobrecargado).
Cerrar la comunicacin con un RecordStore. Mtodo closeRecordStore.
Para la manipulacin de los registros de un RecordStore dispones, entre otras, de las
siguientes operaciones:
Aadir un nuevo registro (mtodo addRecord).
Obtener el contenido de un registro (mtodo getRecord).
Eliminar un registro (mtodo deleteRecord).
Modificar un registro (mtodo setRecord)
Obtener el nmero de registros (mtodo getNumRecords).
3.4.- Operaciones avanzadas en un almacn de registros.
Interfaz RecordEnumeration, para facilitar la navegacin a travs de los registros.
Interfaz RecordFilter, que puede ayudarte a realizar bsquedas ms eficientes mediante
el uso de un patrn de bsqueda.
Interfaz RecordComparator, que proporciona los mtodos necesarios para la
ordenacin de registros.
Interfaz RecordListener, cuyos mtodos te permitirn capturar los eventos que se
produzcan cuando se realice una determinada accin.

3.5.- Un oyente para la monitorizacin de almacenes de registros. La


interfaz RecordListener.
La interfaz RecordListener permite capturar eventos que se producen a la hora de
realizar cambios un RecordStore. Cuando ocurre algn evento, un mtodo es llamado para
notificar que se ha producido un cambio. Existen tres posibles eventos: registro
aadido, registro modificado y registro borrado. En funcin del evento que se haya
producido se realizar una llamada a uno de los siguientes mtodos de la interfaz:
recordAdded (RecordStore almacen, int id).
recordChanged (RecordStore almacen, int id).
recordDeleted (RecordStore almacen, int id).
Si quieres gestionar estos eventos, tendrs que implementar esta interfaz en alguna de las clases
de tu aplicacin y, por tanto, tendrs que escribir el cdigo que quieres que se ejecute cuando se
reciba la notificacin de alguno de esos tres eventos.

3.6.- Un ejemplo completo.


Para finalizar con el sistema de gestin de registros, te proponemos que analices un
ejemplo completo. Se trata de una biblioteca de clases con la funcionalidad bsica para
gestionar el acceso y manipulacin de registros almacenados en los dispositivos
mviles (visualizacin, creacin, bsqueda, modificacin y borrado de registros).
En esta biblioteca se ha intentado simplificar la reutilizacin del mecanismo de gestin de
registros, con independencia de la naturaleza de los mismos, a travs de una clase DBMgr que
contiene un RecordStore.
Tienes una descripcin completa de la biblioteca y cmo usarla, as como el cdigo fuente de las
clases y recursos necesarios para compilar y probar la aplicacin y la documentacin de todas
las clases en formato javadoc en el anexo I. INCLUIDO EN LA PARTE DE RECURSOS

4.- Conectividad.
Una de las mayores ventajas de los dispositivos mviles es la posibilidad de estar siempre (o
casi siempre) vinculados a algn tipo de conexin, con la plataforma Java SE, se utilizan las
clases (InputStream, OutputStream, InputStreamReader, BinaryArrayInputStream,
DataInputStream, Reader, Writer, etc.) se encuentran en el paquete java.io.

Generic Connection Framework o GCF se trata de un conjunto de herramientas


(clases e interfaces) diseado para facilitar el acceso a sistemas de
almacenamiento y conexin, sin necesidad de especificar ningn requisito
software o hardware. Estas clases e interfaces (la mayora son interfaces) se
encontraban en el paquete javax.microedition.io.
El marco CLDC Generic Connection Framework define una serie de interfaces para dar
soporte a la gran variedad de tipos de conexiones que nos podemos encontrar en dispositivos
mviles, pero no implementa ninguna de ellas, (simplemente sirve de soporte).

4.1.- La estructura genrica de conexiones (GCF).


El marco GCF consiste en una jerarqua de interfaces y clases que permiten crear
conexiones y realizar operaciones de E/S. Proporciona un mecanismo genrico de
conectividad poniendo a disposicin de las aplicaciones una API comn para todos los tipos
de conexiones bsicas.
Todas las conexiones se crean utilizando el mtodo esttico open de la clase
Connector. Si no se produce ningn error, este mtodo devuelve un objeto que
implementa una de las interfaces definidas en el marco GCF e implementadas por
MIDP.
La raz de la jerarqua es la interfaz Connection, que representa la conexin ms genrica y
abstracta que se puede tener. Todas esas interfaces estn disponibles en el paquete
javax.microedition.io.
Adems de la jerarqua de conexiones tambin dispones de:
La clase Connector, que es la factora de conexiones (mtodo open).
La excepcin ConnectionNotFoundException.
La interfaz Datagram, que se utiliza para las conexiones basadas en paquetes.
La clase Connector permite abrir cualquier tipo de conexin mediante el mtodo esttico
open. Por ejemplo:
conexion= Connector.open ("http://www.mec.es");

4.2.- Jerarqua de conexiones GCF.


En la siguiente figura puedes observar un esquema de la jerarqua interfaces de la GCF:

Aqu tienes la descripcin de algunas de ellas:


La interfaz Connection es el tipo bsico de conexin. Esta conexin slo puede abrirse y
cerrarse.
La interfaz InputConnection representa un dispositivo desde el que se pueden leer datos.
Proporciona el mtodo openInputStream que devuelve un stream de entrada para la
conexin.

La interfaz OuputConnection representa un dispositivo en el que se pueden escribir


datos. Proporciona el mtodo openOutputStream que devuelve un stream de salida
para la conexin.
La interfaz StreamConnection combina las conexiones de entrada y de salida anteriores
(conexin bidireccional).
La interfaz ContentConnection es una subinterfaz de StreamConnection. Proporciona
acceso a informacin especfica del contenido (longitud de los datos, tipo de contenido,
codificacin, etc.).
La interfaz StreamConnectionNotified permite a una aplicacin esperar conexiones
de flujo entrantes de manera asncrona. Devuelve un StreamConnection a travs
del cual puede establecerse un enlace de comunicacin bidireccional.
La interfaz DatagramConnection es utilizada para operaciones de E/S basadas en
paquetes (datagramas).
La interfaz HttpConnection representa una conexin HTTP (web).
La interfaz HttpsConnection representa una conexin HTTP segura.
La interfaz CommConnection, se usa para conexiones por el puerto serie.


4.3.- Conexiones soportadas.
El marco de conexiones genrico GCF soporta una gran cantidad diferente de conexiones. Los
tipos de conexiones pueden identificarse a travs de la URL (localizador de recursos
uniforme) que se utilice.
Principales esquemas de URL para la GCF
Esquema
Tipo de conectividad
blt2cap
Bluetooth.
datagram
Datagramas.
file
http
https
sms
mms
cbs
apdu
jcrmi
socket
serversocket
datagram

Tipo de conexin GCF (interfaz)


L2CAPConnection
DatagramConnection
FileConnection
InputConnection

Acceso al sistema de archivos.


Protocolo HTTP.

HttpConnection

Protocolo HTTP seguro.


SMS (mesajes de texto).
MMS (mensajes multimedia).
CBS (difusin de celda).
Comunicacin con tarjetas inteligentes
(smart cards).
Sockets.
Datagramas UDP.

HttpsConnection
MessageConnection
APDUConnection
JavaCardRMIConnection
SocketConnection
ServerSocketConnection
UDPDatagramConnection

5.- Mecanismos de persistencia (II). Acceso al sistema de archivos.


Para acceder al sistema de archivos de una memoria externa introducida en el dispositivo no
puede usarse el sistema de gestin de registros RMS, sino que habra que recurrir al
paquete (JSR-75 Personal Information Management and File Connection API o
tambin conocido como "PDA Optional Packages for the J2ME Platform"). Esa biblioteca se
encuentra en el paquete javax.microedition.io.file, el cual contiene las siguientes
herramientas:
Clases
FileSystemRegistry

Interfaces
FileConnection
FileStystcodeListener

Excepciones
ConnectionClosedException
IllegalMode Exception

5.1.- API de acceso al sistema de archivos.


Para acceder al sistema de archivos se utilizarn principalmente los mtodos proporcionados
por la interfaz FileConnection, que proporcionan la funcionalidad habitual para el
trabajo con archivos. Entre esas funcionalidades puedes encontrar mtodos para:
Crear un archivo (mtodo create).
Eliminar un archivo (mtodo delete).
Obtener informacin sobre un archivo (mtodos getName, getPath, fileSize,
canRead, canWrite, isHidden, isDirectory, lastModify, etc.).
Crear un directorio (mtodo mkdir).
Abrir flujos para realizar operaciones de E/S (mtodos openDataInputStream,
openDataOutputStream, openInputStream, openOutputStream).
Obtener listas de archivos de un directorio (mtodo list).
Renombrar un archivo (mtodo rename).

5.2.- Lectura de un archivo.


Para leer el contenido de un archivo puedes seguir los siguientes pasos:
Abrir una conexin con el archivo (mtodo esttico open de la clase Connector).
Leer el contenido del archivo seleccionado de una manera similar a como se hara en
una aplicacin de escritorio con Java SE. Por ejemplo:
Crear un flujo de salida ByteArrayOutputStream donde ir volcando lo que se vaya
obteniendo del archivo.
Abrir un flujo de entrada InputStream a partir de la conexin abierta con el archivo.
Ir leyendo bytes del InputStream y depositndolos en el ByteArrayOutputStream
hasta que se recorra el archivo completamente.
Cerrar la conexin con el archivo (mtodo close de Connector).


Recuerda que este tipo de tareas en las que se realizan operaciones de E/S
deberas realizarlas dentro de un hilo de ejecucin diferente al hilo principal de la
aplicacin. De ese modo, si por alguna razn la operacin tarda ms tiempo del
esperado (o se produce algn tipo de bloqueo), la aplicacin no quedara
bloqueada.

5.3.- Escritura en un archivo.


Para escribir en un archivo puedes seguir estos pasos:
Preparar la informacin que deseas almacenar en el archivo (un String, el
contenido de un array, etc.).
Abrir una conexin con el archivo (mtodo esttico open de la clase Connector).
Comprobar si existe el fichero para crearlo o bien truncarlo.
Almacenar el contenido que se tenga preparado en el archivo seleccionado de
manera similar como se hara en una aplicacin de escritorio con Java SE. Por ejemplo:
Abrir un flujo de salida OutputStream a partir de la conexin abierta con el archivo.
Volcar la informacin que se tenga preparada en el OutputStream (por ejemplo
mediante el mtodo write y sin olvidarnos de purgar el buffer con un flush).
Cerrar la conexin con el archivo (mtodo close de Connector).

5.4.- Otras operaciones con archivos.


Adems de las tpicas operaciones de lectura, escritura y obtencin de informacin sobre
los archivos, el paquete javax.microedition.io.file tambin te va a permitir:
Enumerar las races de los sistemas de archivos disponibles en el dispositivo. Puedes
hacerlo mediante el mtodo listRoots de la clase FileSystemRegistry.
Registrar y borrar oyentes que sern invocados cuando las races de los sistemas
de archivos cambien (por ejemplo al extraer una tarjeta de memoria). Para ello puedes
utilizar los mtodos: addFileSystemListener y removeFileSystemListener, tambin de la clase
FileSystemRegistry e implementar la interfaz FileSystemListener (con su mtodo
rootChanged).ejemplo

6.- Gestin de comunicaciones inalmbricas.


Entre las diversas posibilidades de comunicacin inalmbrica que pueden ofrecer los
dispositivos mviles se encuentran:
Sistemas de comunicacin de voz propios de la telefona mvil (GPS, UMTS, etc.).
Sistemas de mensajera de telefona mvil (SMS, MMS).
Conectividad Wi-Fi con redes inalmbricas basadas en el estndar 802.11.
Emisin y recepcin en FM.
Bluetooth.
Infrarrojos.
Como ejemplo de gestin de comunicaciones inalmbricas vamos a utilizar el protocolo
Bluetooth que posibilita la transmisin entre diferentes dispositivos, mediante un enlace por
radiofrecuencia a poca distancia.

6.1.- Gestin de las comunicaciones Bluetooth con Java ME.


En Java ME, la API encargada de gestionar las comunicaciones Bluetooth es la JSR-82
("Java APIs for Bluetooth"). Consta de dos paquetes:
javax.bluetooth, que incluye las herramientas (clases e interfaces) necesarias para el
descubrimiento de dispositivos, conexin y comunicacin.
javax.obex, que contiene las herramientas para el manejo del protocolo OBEX, parecido al
protocolo HTTP, utilizado para el intercambio de archivos.
El protocolo OBEX se emplea para el intercambio de mensajes entre un cliente y un
servidor. Estos mensajes estarn compuestos por una serie de cabeceras ms un
contenido o cuerpo del mensaje. El cliente enva rdenes al servidor junto con
algunas cabeceras y, en algunos casos, un contenido. Las cabeceras se encapsulan en
un objeto de tipo HeaderSet y el contenido o cuerpo del mensaje se lee o escribe
mediante objetos del tipo InputStream y OutputStream.
El funcionamiento de una comunicacin Bluetooth est basado
cliente/servidor. El cliente deber realizar las siguientes actividades:
Bsqueda de dispositivos.
Bsqueda de servicios.
Establecimiento de la conexin.
Comunicacin propiamente dicha.
Mientras que en el caso del servidor, se encargar de:
Crear una conexin servidora.
Especificar los atributos del servicio.
Abrir las conexiones con los clientes.

en

el

modelo

6.2.- Identificacin de los dispositivos.

Para obtener informacin relacionada con un dispositivo Bluetooth la API proporciona las
siguientes herramientas:
La clase LocalDevice, que representa el dispositivo local. Ser el punto de partida de

cualquier comunicacin Bluetooth.


La clase DeviceClass, para describir el tipo de dispositivo que tienes.
La clase UUID, que representa los identificadores nicos universales para
protocolos y servicios. Son nmeros enteros de 128 bits.
Para obtener una referencia al objeto de la clase LocalDevice, que representa a
nuestro dispositivo, puedes hacer uso del mtodo esttico getLocalDevice:
LocalDevice dispositivoLocal= LocalDevice.getLocalDevice ();
Con la clase DeviceClass puedes obtener una descripcin del dispositivo: si es un
ordenador, un telfono mvil, una PDA, etc. Para ello puedes utilizar sus mtodos
getMajorDeviceClass, getMinorDeviceClass o getServiceClasses. Puedes obtener una
referencia al objeto DeviceClass mediante el mtodo getDeviceClass del objeto de la clase
LocalDevice anterior.
DeviceClass tipoDispositivo= LocalDevice.getLocalDevice().getDeviceClass ();
String infoDispositivo= 0x + Integer.toHexString (deviceClass.getMajorDeviceClass()) + ...
En el siguiente fragmento de cdigo tienes un ejemplo cmo usar las clases LocalDevice y
DeviceClass:

6.3.- Bsqueda de dispositivos.


Un cliente debe intentar descubrir cules son los dispositivos Bluetooth que se
encuentran dentro de su mbito de cobertura. Para llevar a cabo esta tarea, la API
proporciona las siguientes herramientas:
Las clases LocalDevice, DeviceClass y UUID, que ya has visto.
La clase DiscoveryAgent, para realizar las bsquedas de dispositivos.
La interfaz DiscoveryListener, para poder recibir eventos de descubrimiento de
dispositivos y servicios.
La clase RemoteDevice, para representar los dispositivos Bluetooth.
La bsqueda (o "descubrimiento") de dispositivos la realizars mediante un objeto de la
clase DiscoveryAgent que puedes obtener a travs del mtodo getDiscoveryAgent del
dispositivo local:
DiscoveryAgent agente= dispositivoLocal.getDiscoveryAgent ();

A continuacin utilizaremos el mtodo retrieveDevices del objeto DiscoveryAgent para


recuperar los dispositivos establecidos como conocidos o los descubiertos en
bsquedas anteriores. Los dispositivos Bluetooth encontrados estarn representados por
objetos de la clase RemoteDevice establecidos como conocidos o los descubiertos en
bsquedas anteriores. Para comenzar la bsqueda de nuevos dispositivos tendrs que utilizar el
mtodo startInquiry. Para descubrir los nuevos dispositivos de la interfaz DiscoveryListener.

6.4.Descubrimiento
DiscoveryListener.

de

nuevos

dispositivos.

La

interfaz

Para descubrir los nuevos dispositivos en el rea de cobertura puedes


implementar los mtodos deviceDiscovered e inquiryCompleted de la interfaz
DiscoveryListener. En el siguiente fragmento de cdigo tienes un ejemplo de cmo
implementar ambos mtodos:

10

6.5.- Bsqueda de servicios (I).


Una vez que se haya obtenido informacin sobre los dispositivos Bluetooth disponibles en la
zona de cobertura del cliente ser necesario tambin realizar el descubrimiento o
bsqueda de los servicios proporcionados por esos dispositivos. Para ello, podrs usar las
siguientes herramientas:
Clase DiscoveryAgent e interfaz DiscoveryListener, que ya has visto en apartados
anteriores.
Interfaz ServiceRecord, que describe las caractersticas de un servicio Bluetooth.
Clase DataElement, que encapsula los posibles tipos de datos mediante los cuales se
pueden describir los servicios Bluetooth.
Utilizars los mtodos servicesDiscovered y serviceSearchCompleted de la interfaz
DiscoveryListener para descubrir los servicios disponibles en los dispositivos
encontrados, mientras que con los objetos de la clase ServiceRecord dispondrs de una
descripcin de cada servicio. Esta descripcin se realiza mediante atributos que se
identifican numricamente. Cada servicio tendr una lista de pares (identificador, valor) y
esta lista ser almacenada por un objeto de tipo ServiceRecord. Cada uno de los servicios
disponibles en un dispositivo se registra en una estructura conocida como SDDB (Service
Directory DataBase).
Cada uno de los identificadores de los atributos de un servicio Bluetooth es un
nmero entero, mientras que los valores sern objetos de la clase DataElement. Estos objetos
encapsulan los posibles tipos de datos mediante los que se pueden describir los servicios. Entre
los tipos disponibles puedes encontrar: valor nulo, nmeros enteros de diferente tamao,
arrays de bytes, URL, UUID, valores lgicos (boolean), String o enumeraciones de
alguno de estos tipos. La clase DataElement proporciona una constante para cada uno de
estos tipos (NULL, INT_1, INT_2, BOOL, STRING, etc.).
Para acceder a cada atributo de un ServiceRecord puedes utilizar el mtodo
getAttributeValue, que devolver un objeto de tipo DataElement. Tambin puedes
recuperar todos los identificadores de atributo de un servicio en un array por medio del mtodo
getAttributeIDs:
nt[] identificadores= serviceRecord.getAttributeIDs ();
for (int i=0; i< identificadores.length(); i++) {
DataElement elemento= serviceRecord.getAttributeValue (identificadores[i]);
System.out.println (ID: + Integer.toHextString(identificadores[i]);
}
Para saber el tipo de dato almacenado en un objeto DataElement puedes usar el mtodo
getDataType:
int tipoElemento= elemento.getDataType ();
switch (tipoElemento) {
case DataElement.NULL:
...
case DataElement.STRING:

...
6.5.1.- Bsqueda de servicios (II).
Finalmente, para llevar a cabo el descubrimiento de servicios Bluetooth disponibles en el
entorno, tendras que implementar los mtodos deviceDiscovered, servicesDiscovered y
serviceSerarhCompleted de la interfaz DiscoveryListener.
En el siguiente fragmento de cdigo tienes un ejemplo de cmo implementar estos mtodos
suponiendo que se est buscando un servicio con UUID 0x0008 (OBEX) y contenido en un
atributo con identificador 0x7777:

11

6.6.- Establecimiento de la conexin en el cliente.


Una vez realizada la bsqueda de dispositivos y de servicios, ha llegado el momento de
establecer una conexin entre cliente y servidor. La API de Bluetooth JSR-82 proporciona
dos mecanismos diferentes para realizar esa conexin:
SPP, que trabajarn con un InputStream y un OutputStream.
L2CAP, que trabajarn con arrays de bytes encapsulados en objetos de la clase
L2CAPConnnection.
Para abrir una conexin se utilizar la clase Connector de la GCF. A travs del mtodo
esttico open le pasars como parmetro un String que contendr la URL necesaria para
establecer la conexin. Esa URL tendr un esquema diferente en funcin de que se realice una
conexin de tipo SPP o L2CAP:
Si se trata de una URL para una conexin de tipo SPP tendr la siguiente estructura:
btspp://hostname:[ PSM | UUID ];parametros.
Si se trata de una URL para una conexin de tipo L2CAP la estructura ser de la siguiente
forma:
btl2cap://hostname:[ PSM | UUID ];parametros.
Un cliente Bluetooth puede obtener la URL necesaria para realizar una conexin mediante el
mtodo getConnectionURL de la clase ServiceRecord. Habr que pasar dos parmetros
que indican:
1 Si se desea autenticar o cifrar (o ambos) la conexin. Los posibles valores seran:
a) ServiceRecord.NOAUTHENTICATE_NOENCRYPT.
b) ServiceRecord.AUTHENTICATE_NOENCRYPT.
c) ServiceRecord.AUTHENTICATE_ENCRYPT.
2 Valor lgico (boolean) que indica si el dispositivo local debe actuar como maestro (true) o

12

bien si es indiferente ser maestro o esclavo (false).


Para abrir una conexin de tipo cliente utilizando el protocolo SPP podras hacer lo
siguiente:
// Obtenemos la URL
String url= registro.getConnectionURL (ServiceRecord.NOAUTHENTICATE_NOENCRYPT,
false);
// Abrimos la conexin (uso de la GCF)
StreamConnection conexion= (StreamConnection) Connector.open ();
// Abrimos los flujos de entrada y salida para la comunicacin
OutputStream salida= conexion.openOutputStream ();
InputStream entrada= conexion.openInputStream ();
Para hacer lo mismo utilizando el protocolo L2CAP tendrs que crear una conexin con una
URL estilo L2CAP:
// Obtenemos la URL
String url= registro.getConnectionURL (ServiceRecord.NOAUTHENTICATE_NOENCRYPT,
false);
// Abrimos la conexin (uso de la GCF)
L2CAPConnnection conexion= (L2CAPConnnection) Connector.open ();

6.7.- Establecimiento de la conexin en el servidor.


Para que un dispositivo Bluetooth pueda actuar como servidor hay que establecer su estado
como "descubrible" o susceptible de ser descubierto (activo). Para ello puedes utilizar el
mtodo setDiscoverable del objeto que representa al dispositivo local:
LocalDevice dispositivoLocal= LocalDevice.getLocalDevice ();
boolean ok= dispositivoLocal.setDiscoverable(DiscoveryAgent.GIAC); // GIAC = Conectividad
ilimitada
Una vez que se ha establecido que el dispositivo puede ser descubierto, hay que crear una
conexin servidora con una URL. Esta URL se construye de manera similar a como se haca
para las conexiones cliente, teniendo en cuenta que debe contener:
El valor localhost como hostname.
UUID, que identifica el servicio que se desea ofrecer.
Nombre del servicio.
Otros parmetros adicionales.
Por ejemplo:
// Para SPP
String url= btspp://localhost: + (new UUID(0x7777)).toString() +
;name=ejemplo;authorize=true";
// Para L2CAP
String url= brl2cap://localhost:
+ (new UUID(0x7777)).toString() + ;name=ejemplo;ReceiveMTU=512;TrnasmitMTU=512";
Para abrir la conexin con alguna de esas URL tendrs que utilizar el mtodo open de la clase
Connector. Dependiendo del tipo de protocolo que se vaya a usar (SPP o L2CAP) se obtendr
un
tipo
de
notificador
diferente
(StreamConnectionNotifier
o
L2CAPConnectionNotifier). En ambos casos dispondrs de un mtodo acceptAndOpen
que devolver un objeto de tipo conexin especfico (StreamConnection o
L2CAPConnection).
Por ejemplo:
// Abrimos conexin para SPP
StreamConnectionNotifier notificador= (StreamConnectionNotifier) Connector.open (url);
StreamConnection conexion= notificador.acceptAndOpen ();
// Abrimos conexin para L2CAP
L2CAPConnectionNotifier notificador= (L2CAPConnectionNotifier) Connector.open (url);

13

StreamConnection conexion= notificador.acceptAndOpen ();


En cualquier caso, antes de abrir la conexin, tambin hay que especificar los atributos del
servicio que se va a ofrecer (objetos de la clase DataElement). Esos atributos podrs
obtenerlos a partir del ServiceRecord, que a su vez puedes recuperar a travs del mtodo
getRecord de la clase LocalDevice. Una vez obtenido el ServiceRecord puedes establecer
sus atributos mediante el mtodo setAttibuteValue.
Por ejemplo:
ServiceRecord registro= dispositivoLocal.getRecord (notificador);
DataElement elemento= new DataElement (DataElement.URL, http://www.mec.es/);
registro.setAttributeValue (0x1111, elemento);
Una vez que tengas un objeto de la clase StreamConnection, el envo y recepcin de datos
tanto en cliente como en servidor se realizar de la misma manera: mediante el uso de flujos
de entrada y de salida.
Por ejemplo:
StreamConnection conexin= <establecimiento_conexin> // Estilo SPP o L2CAP

DataInputStream entrada= conexin.openDataInputStream ();


DataOutputStream salida= conexion.openDataOutputStream ();
...
salida.writeUTF (Bienvenido);
salida.flush ();

7.- Mensajes de texto.


El servicio de mensajes cortos, mensajes de texto o SMS (Short Message Service)
permite a los dispositivos de telecomunicaciones el envo y recepcin de pequeos
mensajes de texto.
Estos mensajes son enviados a un centro de mensajes cortos SMSC (Short Message
Service Center) que conecta con el resto de elementos de la red de comunicaciones y que se
encargar de guardarlos, procesarlos y encaminarlos por la ruta adecuada para que puedan
llegar correctamente a su destino.
Los mensajes van encapsulados en un paquete que incluye, adems del propio texto del
mensaje:
Fecha de envo del mensaje.
Perodo de validez del mensaje.
Nmeros de telfono del origen y del destino del mensaje.
Nmero del centro de mensajes cortos (SMSC) de donde proviene el mensaje.

7.1.- La API de mensajera inalmbrica (WMA).


La API de mensajera inalmbrica WMA (Wireless Messaging API) es una API
opcional que proporciona a las aplicaciones del perfil MIDP la posibilidad de trabajar con
mensajes de texto SMS, as como el procesamiento del servicio de difusin de celdas
CBS (Cell Broadcast Service). Las ltimas versiones de esta API tambin incorporan el
soporte de mensajera multimedia.
Mediante el uso de estas herramientas resulta relativamente sencillo utilizar el servicio de
mensajes cortos SMS desde aplicaciones de tipo midlet.
La API WMA funciona conjuntamente con el marco genrico de conexin o GCF
(Generic Connection Framework) que se encuentra incluido en el paquete
javax.microedition.io. Las herramientas necesarias para trabajar con mensajes de texto
SMS se encuentran en el paquete javax.wireless.messaging.
Del mismo modo que el paquete javax.microedition.io inclua las interfaces
SocketConnection y DatagramConnection, el paquete javax.wireless.messaging
contiene la interfaz MessageConnection. A travs del mtodo esttico open de la clase

14

Conector puedes obtener una nueva conexin para poder enviar o recibir tus mensajes
de texto.
Por tanto, para crear esa conexin bastara con hacer algo as:
MessageConnector msgCon= (MessageConnector) Conector.open (<direccion>);
Donde <direccion> sera una URL que indicara en este caso un nmero de telfono. El
formato de la cadena de conexin es de la forma sms://<nmero_telfono>. Por ejemplo:
"sms://+34666777444".
De esa forma habras creado una conexin en modo cliente, que podra ser utilizada para
enviar mensajes.
De una manera similar tambin podras crear una conexin en modo servidor indicando un
nmero de puerto:
MessageConnector msgCon= (MessageConnector) Conector.open (sms://:1234);
Una vez que dispongas de una conexin abierta, sta puede ser usada para:
Crear mensajes.
Enviar mensajes.
Recibir mensajes (modo servidor).
Obtener informacin de segmentacin sobre un mensaje.

7.2.- Creacin de mensajes.


Para poder enviar mensajes, es necesario primero crear un mensaje y a continuacin
rellenarlo con un contenido. Como ya has visto en el apartado anterior, la interfaz
MessageConnection proporciona los mtodos necesarios para crear nuevos mensajes y
tambin para poder enviar y recibir mensajes. Para crear un mensaje vaco debes utilizar el
mtodo newMessage de la interfaz MessageConnection.
Dispones de dos versiones de este mtodo:
Message newMessage(String tipoMensaje).
Message newMessage(String tipoMensaje, String direccion).
Existen varios tipos de mensajes, representados por interfaces que heredan de Message:
TextMessage.
BinaryMessage.
MultipartMessage.
Para indicar qu tipo de mensaje deseas crear con el mtodo newMessage puedes utilizar las
siguientes constantes predefinidas:
MessageConnection.TEXT_MESSAGE.
MessageConnection.BINARY_MESSAGE.
MessageConnection.MULTIPART_MESSAGE.
Para crear un mensaje de texto bastara con hacer algo as:
TextMessage mensaje= (TextMessage) msgCon.newMessage
(MessageConnection.TEXT_MESSAGE);
Para rellenar ese mensaje con algn contenido (payload) puedes utilizar el mtodo
setPayLoadText, que establece el contenido del mensaje de texto:
mensaje.setPayLoadText ("Ejemplo de mensaje SMS.");
Message.

7.3.- Envo de mensajes.


Para enviar un SMS una vez creado un objeto de tipo TextMessage y relleno con el contenido
que se desea mandar tan solo queda utilizar el mtodo send de la interfaz
MessageConnection:
msgCon.send (mensaje);
Aqu tienes un ejemplo de de cdigo que realiza todas las tareas necesarias para enviar un
mensaje:

15

Crear la conexin.
Crear el mensaje.
Establecer el contenido del mensaje.
Enviar el mensaje.
Cerrar la conexin.

7.4.- Recepcin de mensajes.


La interfaz MessageConnection tambin dispone de un mtodo para recibir mensajes
(mtodo receive). Este mtodo hace que el hilo de ejecucin se quede detenido en espera
de la llegada de un mensaje.
La forma ms sencilla de recibir un mensaje sera simplemente esperar a que llegue un
mensaje y actuar cuando eso suceda. El nico inconveniente es que la aplicacin no podra hacer
ninguna otra cosa mientras tanto. Para hacer esto basta con utilizar el mtodo receive de la
interfaz MessageConnection:
public Message receive() throw IOException, InterruptedIOException
Se lanzar una IOException si se produce algn error durante el proceso de recepcin, si la
conexin est cerrada o si el mtodo ha sido send ha sido llamado desde una conexin abierta
en modo cliente y no servidor (una conexin cliente solamente puede mandar, pero no
recibir).

16

Dado que una llamada al mtodo send se queda esperando la llegada de un mensaje (no se
siguen ejecutando otras instrucciones), sta debera realizarse siempre desde su propio hilo de
ejecucin (thread) para no detener la ejecucin de toda la aplicacin (dara la impresin de
que se ha quedado bloqueada, pues no se harn ms cosas hasta que la llamada a send reciba
un mensaje, cosa que no se sabe cunto puede tardar en suceder). Lo ms habitual es crear un
hilo especfico de recepcin dentro de la aplicacin, como sucede en la programacin de
cualquier de aplicacin que implementa algn tipo de servicio.
Ese hilo de ejecucin para recepcin podra ser liberado posteriormente mediante el cierre
de la conexin MessageConnection. En tal caso se lanzar la excepcin
InterruptedIOException si la conexin es cerrada mientras la ejecucin estaba bloqueada
por una llamada a send (estaba a la espera de un mensaje y an no lo haba recibido).

7.4.1.- Un oyente
MessageListener.

para

la

recepcin

de

mensajes.

La

interfaz

Existe una alternativa para recibir mensajes sin tener que estar comprobndolo continuamente
(y por tanto bloqueando el hilo de ejecucin en espera de un mensaje). Para eso, el paquete
javax.wireless.messaing incorpora la interfaz MessageListener, que incluye el mtodo
notifyIncomingMessage. Este mtodo ser llamado cada vez que el dispositivo reciba un
mensaje.
Podras tener un midlet que implementara la interfaz MessageListener y que en el mtodo
notifyIncommingMessage actuar en consecuencia cada vez que se reciba una
notificacin de mensaje entrante. En realidad la comprobacin de llegada de mensajes se
estar realizando desde algn otro hilo lanzado por la mquina virtual y cada vez que se
produzca una recepcin se notificar al oyente que se haya establecido (por ejemplo el midlet) a
travs de la llamada al mtodo notifyIncommingMessage. De este modo se nos facilita la
tarea evitndonos tener que definir nosotros un nuevo hilo de ejecucin.
Nuestro midlet (o el componente de la aplicacin que vaya a ser oyente y gestor de ese evento)
tendr implementar la interfaz MessageListener.

17

Por ejemplo:
public class midletOyenteSMS extends midlet implements MessageListener {
Cuando el midlet se inicie, lo registramos como oyente de una conexin para recibir mensajes:
public void startApp () {
conexion= (MessageConnection) Connector.open ("sms://:5000"); // Abrimos la conexin
conexion.setMessageListener(this); // Establecemos como oyente de esta conexin al propio
midlet
...
Y finalmente se define el mtodo notifyIncomingMessage:
public void notifyIncomingMessage (MessageConnection conexion) {
if (conexion == this.conexion) {
Message mensaje= conexion.receive ();// Recibimos el mensaje
// Analizamos el mensaje recibido
...
Aqu tienes un ejemplo de cmo podra quedar la implementacin de un ese mtodo en un
midlet simple sin interfaz grfica:


7.4.2.- Activacin automtica por recepcin mensaje. Push Registry.
En ocasiones es posible que la aplicacin que recoge los mensajes recibidos por el dispositivo no
est en ejecucin. En esos casos existe la posibilidad de registrar para que cuando se produzca
un determinado evento de conexin se active automticamente el midlet. Se trata del
mecanismo conocido como Push Registry.
La API WMA permite lanzar una determinada aplicacin cuando se reciba un nuevo mensaje.
El registro puede realizarse bien a travs del archivo JAD del midlet o bien dinmicamente en
tiempo de ejecucin mediante la clase PushRegistry.
Una entrada en el registro debe incluir:
Una cadena de conexin (URL) que identifique las conexiones entrantes.

18

El nombre del midlet que debe ser lanzado cuando llegue una nueva conexin entrante.
Un filtro que especifica los emisores que tendrn permiso para hacer que se lance el midlet
al mandar un mensaje.
Un ejemplo de entradas midlet-Push en el archivo JAD podra ser:


Si lo que deseas es registrar dinmicamente el midlet desde el cdigo podras entonces que
utilizar la clase PushRegistry:
PushRegistry.registerConnection (sms://:5000, midletRecepcionSMS, *);

19

7.5.- Seguridad y permisos.

En el caso de MIDP dispones de un mecanismo para dar permisos a las aplicaciones para que
tengan acceso a funciones privilegiadas del dispositivo. En el caso del envo de
mensajes tendras los siguientes permisos relacionados:
Permiso para acceder a la implementacin de la clase MessageConnection. Si no
se tiene ese permiso, el mtodo Connector.open lanzara una excepcin de tipo
SecurityException.
Permiso para enviar mensajes. Si no se tiene se lanzara tambin una SecurityException.
Permiso para recibir mensajes. Si no se tiene se lanzara nuevamente una
SecurityException.
Permiso para utilizar el mecanismo Push Registry.
Si no se tiene alguno de esos permisos y se intentan realizar operaciones como
Connector.open, send, receive, etc. se lanzar una excepcin de tipo
SecurityException.
Los permisos necesarios para poder realizar estas operaciones sin dar lugar a una excepcin
son:
javax.microedition.io.Connector.sms.
javax.wireless.messaging.sms.send.
javax.wireless.messaging.sms.receive.
javax.wireless.messaging.io.PushRegistry.
La forma ms sencilla de conceder esos permisos a un midlet es a travs del panel de
propiedades del proyecto, dentro de la opcin "Application Descriptor" en la pestaa "API
Permissions".
Aunque tambin podras hacerlo mediante la entrada midlet-Permissions del archivo JAD
del midlet:
midlet-Permissions: javax.microedition.io.Connector.sms, javax.wireless.messaging.mms.send,
javax.wireless.messaging.sms.receive, javax.microedition.io.PushRegistry

20

7.6.- Difusin de celda.


El servicio de difusin de celda o CBS (Cell Broadcast Service) permite a los operadores
de telefona mvil el envo simultneo de mensajes a todos los usuarios que se encuentren
en un rea especfica (una celda o un conjunto de celdas). Entre sus principales utilidades
se encuentran el envo de alertas de emergencia o de trfico, la prestacin servicios basados en
la ubicacin, y el envo de informacin comercial o cultural por parte del operador.
Una aplicacin que haga uso de la API WMA con Java ME puede recibir mensajes CBS,
aunque no enviarlos. No se necesita para ello ninguna clase o interfaz adicional a las que ya has
visto. Se puede emplear el mismo mecanismo utilizado para la recepcin de SMS. Ahora bien, la
conexin de tipo MessageConnection slo podr ser abierta en modo servidor, dado que no
est permitido enviar mensajes de tipo CBS (tan solo recibirlos).
Bastara entonces con abrir una conexin MessageConnection indicando una URL de tipo
CBS y un identificador de canal CBS.
conexion = (MessageConnection) Connector.open ("cbs://:12345");
mensaje = conexion.receive();
En este caso el nmero "12345" no representa un puerto sino un identificador CBS.

8.- Mensajera multimedia.


El sistema de mensajera multimedia o MMS (Multimedia Messaging System) es un
estndar de mensajera que permite a los dispositivos mviles enviar y recibir contenidos no
solo de texto como suceda con los mensajes SMS, sino todo un conjunto de elementos
multimedia (imgenes, texto, sonido, vdeo, etc.). El lmite en el tamao de los mensajes
puede depender tanto del terminal como del operador.
Con este sistema ser necesario tambin un nuevo centro de mensajes: el centro de
gestin de mensajes multimedia o MMSC (Multimedia Message Service Center),
anlogo al SMSC de los mensajes de texto SMS).
Los mensajes multimedia pueden incluir los siguientes tipos de formatos de contenido:
Para imgenes: formatos GIF y JPEG.
Para texto: texto normal y texto con formato basado en EMS.
Para sonido: formatos de compresin AMR, WAV y MP3 para audio digitalizado y
formatos MIDI e IMY para melodas.
Para vdeo: formatos 3GP y MPEG4.

8.1.- Estructura de un mensaje MMS.


Un mensaje MMS consiste en un mensaje de tamao variable (normalmente bastante mayor
que los mensajes de texto) formado por distintas partes. Cada una de esas partes puede
contener un texto, una imagen, un fragmento de vdeo o de audio, o en general cualquier
contenido multimedia soportado.
La estructura general de un mensaje MMS consiste en:
Una cabecera.
Un cuerpo multiparte.
Cada parte del cuerpo est formado a su vez por:
Una cabecera de la parte.
El contenido o cuerpo de la parte.
La cabecera de una parte estar formada por un conjunto de campos como por ejemplo:
MIME-Type, que indica el tipo de contenido (texto, imagen, vdeo, etc.). Por ejemplo:
text/plain, audio/mp3, image/jpeg.
Content-Location, para hacer referencia al nombre del archivo.
Content-Identifier, que identifica el contenido.

21

El cuerpo de la parte ser finalmente el contenido en s mismo (un conjunto de bytes que
representan un texto, un sonido, una imagen, etc.).

8.2.- Creacin de un mensaje.


Como ya has estudiado en apartados anteriores, el paquete javax.wirelesss.messaing
proporciona tambin las herramientas necesarias para gestionar, enviar y recibir mensajes
multimedia MMS. En concreto, la API WMA 2.0 incorpora dos elementos para trabajar con
mensajes multimedia:
La clase MessagePart, utilizada para representar cada una de las partes de un mensaje.
La interfaz MultipartMessage, que nuevamente hereda de Message y que representa al
mensaje completo (de manera similar a como suceda con TextMessage para el caso de los
SMS).

8.2.1.- Las partes de un mensaje.


Cada objeto MessagePart ser un elemento de contenido que se podr incluir en un mensaje y
estar formado por los siguientes componentes:
El tipo MIME del elemento.
El identificador de contenido.
El contenido propiamente dicho (texto, audio, imagen, etc.).
Alguna otra informacin opcional (ubicacin del contenido, esquema de codificacin
utilizado, etc.).
Para crear un nuevo objeto MessagePart puedes utilizar alguno de sus constructores y pasarle
las cabeceras a travs de sus parmetros. Por ejemplo, para objeto de tipo texto tendras los
siguientes parmetros:
Tipo MIME (por ejemplo "text/plain").
Identificador de contenido (por ejemplo "id-0").
Ubicacin (por ejemplo: "prueba.txt").
Codificacin (por ejemplo: "UTF-8").
El cdigo de creacin podra quedar as:

Aqu tienes otro ejemplo, en este caso para una imagen JPEG:

22

8.2.2.- El mensaje completo.


Para representar el mensaje MMS completo se utiliza una nueva interfaz que hereda de
Message. En este caso se trata de MultipartMessage.
Para crear objetos que implementen la interfaz habr que hacer algo similar a como se haca con
los mensajes de texto: utilizar el mtodo factora newMessage de la interfaz
MessageConnection.
Por ejemplo:
String direccion= mms://+34666123456;
MessageConnector conexion= (MessageConnector) Conector.open (direccion);
MultipartMessage mensaje=
(MultipartMessage) conexion.newMessage (MessageConnection.MULTIPART_MESAGE);
En este caso utilizaremos la constante MessageConnection.MULTIPART_MESSAGE para
indicar que se trata de un MMS. Para ir incluyendo partes en el mensaje puedes utilizar el
mtodo addMessagePart:

MessagePart textoMsgPart= new MessagePart ();


MessagePart imagenMsgPart= new MessagePart ();
MessagePart audioMsgPart= new MessagePart ();
...
MultipartMessage mensaje=
(MultipartMessage) conexion.newMessage (MessageConnection.MULTIPART_MESAGE);
...
mensaje.addMessagePart (textoMsgPart);
mensaje.addMessagePart (imagenMsgPart);
...
La interfaz MultipartMessage dispone de una larga lista de mtodos que te permitirn, entre
otras cosas:
Gestionar las cabeceras del mensaje: getHeader, setHeader.
Gestionar la direccin: getAddress, setAddress, removeAddress.
Gestionar cada una de las partes que contiene el mensaje: addMessagePart,
getMessagePart, removeMessagePart, removeMessagePartId, removeMessagePartLocation.

8.3.- Envo y recepcin de mensajes.


El mecanismo de envo y recepcin de mensajes (interfaz Message) es comn para los tres
tipos de mensajes que la API WMA es capaz de gestionar (interfaces TextMessage,
BinaryMessage y MultipartMessage). Recuerda que disponas de las siguientes
herramientas:
Mtodo send para enviar mensajes.
Mtodo receive para recibirlos, teniendo en cuenta que se quedar en espera de la llegada de
un mensaje (es fundamental hacerlo en un hilo de ejecucin independiente), o bien
utilizar la interfaz MessageListner.
Mecanismo de activacin Push Registry.
Nuevamente, al igual que suceda con los mensajes SMS, tendrs que conceder permisos para
poder trabajar con mensajes multimedia. En este caso se trata de:
javax.microedition.io.Connector.mms.
javax.wireless.messaging.mms.send.
javax.wireless.messaging.mms.receive.
javax.wireless.messaging.io.PushRegistry.

23

9.- Conexiones web.


El protocolo utilizado para las comunicaciones por la WWW (World Wide Web) es conocido
como HTTP. Este estndar se encarga de establecer las normas que utilizan los elementos de
software de la arquitectura web (esencialmente clientes y servidores, aunque tambin los
servidores proxy) para comunicarse. Se trata de un protocolo orientado a transacciones que
sigue el esquema peticin-respuesta entre un cliente y un servidor (el cliente realiza
una peticin al servidor y espera a que ste le enve una respuesta).
Al cliente que efecta la peticin (un navegador web) se lo conoce como "user agent"
(agente del usuario). A la informacin transmitida se la llama recurso y se la identifica
mediante un localizador uniforme de recursos (URL). Los recursos pueden ser archivos,
el resultado de la ejecucin de un programa, una consulta a una base de datos, la traduccin
automtica de un documento, etc.

9.1.- Conexiones HTTP.


Una conexin HTTP puede encontrarse en uno de estos tres estados:
Estado de establecimiento de la conexin (setup), donde se indican los parmetros
de comunicacin. El cliente prepara la peticin que se va a realizar al servidor, adems de
negociar algunos parmetros como el formato, el idioma, etc.
Estado de conexin (Connected), en el que se realiza el intercambio de informacin
entre el cliente y el servidor.
Estado de cierre de la conexin (closed), cuando finaliza la comunicacin entre
cliente y servidor.
La estructura de conexiones genrica GCF proporciona la interfaz HttpConnection para
trabajar con las conexiones HTTP. Dispone de todos los mtodos y constantes necesarias para
poder establecer una conexin HTTP, realizar una comunicacin a travs de ella y
finalmente cerrar la conexin.
Los principales mtodos de la interfaz HttpConnection los puedes consultar en la API del
GCF.
Los tipos de peticiones HTTP (comandos o mtodos HTTP) que se pueden enviar son:
GET, donde toda la informacin que se enva al servidor va en la URL.
POST, donde la informacin que se enva al servidor va aparte en un stream (adems de lo
que se enve por la URL).
HEAD, donde se pide metainformacin.
Una peticin HTTP estar formada por:
La peticin propiamente dicha (comando HTTP).
Cabeceras de peticin.
Cierta informacin adicional (en el caso de peticiones POST). Formara el cuerpo de la
peticin (no siempre existe, slo si se trata de una peticin de tipo POST).
Ejemplos de posibles cabeceras HTTP
Nombre cabecera
Descripcin
User-Agent
Identificacin del cliente (agente).
Date
Fecha y hora de envo del mensaje.
Content-Length
Longitud del cuerpo de la peticin.
Accept
Formatos que acepta el cliente.
Connection
Indica al servidor si se quiere dejar abierta la conexin tras la peticin o se quiere cerrar.

9.2.- Manejo de las conexiones HTTP con la GCF.


Para establecer una conexin HTTP con un servidor utilizaremos una vez ms el mecanismo
genrico que el marco GCF nos proporciona para abrir conexiones: el uso del mtodo
esttico open de la clase Connector indicando una URL de tipo HTTP.

24

Por ejemplo:
HttpConnection conexion= (HttpConnection) Connector.open ("http://www.mec.es/");
Una vez creada la conexin, falta indicar:
El tipo de peticin (GET, POST, HEAD). MtodosetRequestMethod.
Las cabeceras que se van a enviar (User-Agent, Connection, Accept, Content-Language,
etc.). Mtodo setRequestProperty.
Por ejemplo:
conexion.setRequestMethod (HttpConnection.GET);
conexion.setRequestProperty ("User-Agent", "Profile/MIDP-20.0 Configuration/CLDC-1.0");
conexion.setRequestProperty ("Content-Language", "es-ES");
En este momento an estamos en el estado de establecimiento de conexin. Pasaramos al
estado conectado en cuanto se comiencen a enviar o recibir datos.
Mientras la conexin permanezca abierta, podrs utilizar los siguientes mtodos: getURL,
getProtocol, getHost y getPort, que proporcionan informacin acerca de la conexin.

9.3.- Establecimiento de la conexin HTTP.


Para enviar o recibir informacin a travs de la conexin HTTP puedes utilizar los mtodos
openOutputStream y openInputStream, heredados de InputConnection y
OutputConnection. A partir de ese momento, si todo ha ido bien, la conexin pasara a estado
conectada. Por ejemplo:
OutputStream salida= conexion.openOutputStream (); // Flujo abierto: conexin realizada
InputStream entrada= conexion.openInputStream ();
En el siguiente fragmento de cdigo tienes un ejemplo de cmo establecer una conexin HTTP
con un servidor para descargar un archivo de tipo imagen GIF y almacenarlo en un objeto de
tipo Image:

25


9.4.- Conexiones HTTPS.
HTTPS es la versin segura del protocolo HTTP. Se basa en el establecimiento de
conexiones HTTP sobre SSL (Secure Sockets Layer). Para poder establecer este tipo de
conexiones dispones del interfaz HttpsConnection, que hereda de HttpConnection.
La forma de trabajar con esta interfaz es idntica a la que has utilizado para las conexiones
HTTP convencionales. La nica diferencia es que en este caso hars uso de un objeto
HttpsConnection.
Por ejemplo:
HttpsConnection conexionSeg (HttpsConnnection) Connector.open ("https://......");
conexionSeg.setRequestMethod (HttpConnection.GET);
conexionSeg.setRequestProperty ("User-Agent", "Profile/MIDP-2.1 Configuration/CLDC-1.1");
...
Los mtodos adicionales que aporta esta interfaz son:
getPort, que devuelve el puerto utilizado para la conexin HTTPS (funcin sobrescrita).
getSecurityInfo, que devuelve la informacin de seguridad asociada a la conexin (objeto
SecurityInfo).
Las conexiones HTTP seguras pueden lanzar la excepcin CertificateException (subclase de
IOException), relacionada especficamente con errores ocurridos en el establecimiento
de conexiones seguras.
La interfaz SecurityInfo proporciona mtodos que permiten acceder a la informacin
asociada a conexiones seguras. Cualquiera de los protocolos que implementa MIDP 2.0
para establecer estas conexiones seguras (HTTP o sockets seguros sobre SSL) pueden utilizar
estos mtodos para conocer los parmetros de seguridad de estas conexiones. En la
siguiente tabla tienes una breve descripcin de estos mtodos:
Mtodo
String getCipherSuite ()
getProtocolName()
getProtocolVersion
Certificate getServerCertificate()

Descripcin
Obtiene una cadena con el nombre del sistema de cifrado
(suite de cifrado) que se est utilizando.
Obtiene el nombre del protocolo seguro al que pertenece la conexin.
Obtiene la versin del protocolo seguro utilizado.
Obtiene el certificado (objeto Certificate) utilizado para establecer
la conexin segura con el servidor.

9.4.1.- Certificados digitales.


La interfaz Certificate, incluida en el paquete javax.microedition.pki, sirve para
representar y manejar certificados digitales en la plataforma Java ME. Proporciona los
mtodos necesarios para consultar las caractersticas de un certificado:
Nombre del emisor del certificado (mtodo getIssuer).
Fecha de caducidad del certificado (mtodo getNotAfter).
Fecha de inicio de validez del certificado (mtodo getNotBefore).
Nmero de serie del certificado (mtodo getSerialNumber).
Algoritmo utilizado para firmar el certificado (mtodo getSigAlgName).
Asunto del certificado (mtodo getSubject).
Tipo de certificado (mtodo getType).
Versin del certificado (mtodo getVersion).
Aqu tienes un ejemplo que obtiene la informacin de seguridad relacionada con una conexin
HTTPS:

26


Anexo II.- La plataforma Wireless Toolkit para CLDC. (leer interesante)
Plataforma Sun Java Wireless Toolkit.
La plataforma Sun Java Wireless Tookit consiste en un conjunto de herramientas que
permite la creacin de aplicaciones Java compatibles con tecnologas de dispositivos mviles
que implementan los estndares de Java ME. Est compuesta por herramientas de
generacin de cdigo, utilidades, emuladores de dispositivos y otras herramientas.
Este conjunto de herramientas implementan la mayora de las APIs definidas por la JCP (Java
Community Process.):
Mobile Service Architecture (JSR 248).
Java Technology for the Wireless Industry (JTWI) (JSR 185).
Connected Limited Device Configuration (CLDC) 1.1 (JSR 139).
Mobile Information Device Profile (MIDP) 2.0 (JSR 118).
PDA Optional Packages for the J2ME Platform (JSR 75).
Java APIs for Bluetooth (JSR 82).
Mobile Media API (MMAPI) (JSR 135).
J2ME Web Services Specification (JSR 172).
Security and Trust Services API for J2ME (JSR 177).
Location API for J2ME (JSR 179).
SIP API for J2ME (JSR 180).
Mobile 3D Graphics API for J2ME (JSR 184).
Wireless Messaging API (WMA) 2.0 (JSR 205).
Content Handler API (JSR 211).
Scalable 2D Vector Graphics API for J2ME (JSR 226).
Payment API (JSR 229).
Advanced Multimedia Supplements (JSR 234).
Mobile Internationalization API (JSR 238).
Java Binding for the OpenGL(R) ES API (JSR 239).
Si por alguna razn no tuvieras instalada esta plataforma puedes descargarla de:
Sun Java Wireless Toolkit 2.5.2_01 for CLDC Download (en ingls).
Entre las herramientas incluidas en este paquete tienes por ejemplo la consola WMA, que te
va a proporcionar muchas facilidades a la hora de probar tus midlets que utilizan las
funcionalidades de envo y recepcin de mensajes. Si lo deseas puedes seguir trabajando con la
plataforma incluida por Netbeans como es probable que hayas estado haciendo hasta ahora,
pero es posible que para este tipo de aplicaciones la consola WMA que incorpora esta otra
plataforma te sea de gran ayuda.
Si an no tienes integrada esta plataforma en el IDE de Netbeans puedes hacerlo de la
siguiente manera:
Si no tienes disponible en tu sistema esta plataforma, descrgala del enlace anterior e

27

instlala.
Abre la caja de dilogo "Administrador de Java Platform". Puedes llegar hasta ella a
travs de la opcin de men "Herramientas -> Plataformas Java".
Una vez abierta la caja de dilogo, comprueba si dentro de la categora J2ME tienes instalada
la plataforma "Sun Java(TM) Wireless Toolkit 2.5.2 for CLDC adems de "Java
Platform Micro Edition SDK 3.0", que es la que incorpora inicialmente Netbeans.
Si no est instalada esa plataforma, pulsa el botn "Aadir plataforma".
Se te abrir una nueva caja de dilogo "Aadir plataforma Java". Escoge como tipo de
plataforma "Java MIDP Platform Emulator".
En el segundo paso, "Platform Folders", debera aparecer la opcin de instalar Selecciona
esa opcin marcando su casilla de verificacin.
Si todo ha funcionado correctamente, debera indicar que se ha instalado la plataforma "Sun
Java(TM) Wireless Toolkit 2.5.2 for CLDC" as como algunos detalles como los
emuladores de dispositivo que incorpora o las APIs opcionales que incluye.
A partir de este momento, deberas de tener al menos dos plataformas (si no las tenas ya)
dentro de la categora J2ME:
Java Platform Micro Edition SDK 3.0.
Sun Java(TM) Wireless Toolkit 2.5.2 for CLDC.
Desde de ahora, para cada midlet que vayas a generar, podrs elegir la plataforma con la que
desees trabajar. Eso podrs hacerlo dentro de las propiedades del proyecto, en la seccin
"Platform", en la opcin "Emulator Platform".
Si dentro del administrador de plataformas eliges la opcin "Sun Java(TM) Wireless
Toolkit 2.5.2 for CLDC", y a continuacin, en la pestaa "Tools & Extensions", pulsas el
botn "Open Utilities", obtendrs una ventana con una serie herramientas que te podrn ser
de gran utilidad. Entre ellas se encuentra la "WMA Console" que te permitir, entre otras
cosas, enviar mensajes a los nmeros de telfono que quieras para poder probar la recepcin de
mensajes en los dispositivos que ests emulando en ese momento.

Anexo II.- Herramientas para el envo de mensajes de texto SMS.


El paquete javax.wireless.messaging proporciona las herramientas necesarias para el envo
de mensajes de texto:
Interfaz Message, que incluye los mtodos necesarios para manipular los mensajes.
Interfaz MessageConnection, con los mtodos necesarios para gestionar una conexin que
te va a permitir enviar y recibir mensajes.
Interfaz TextMessage, que representa a los mensajes de texto SMS.
Un mensaje genrico se representa mediante un objeto de una clase que implemente la
interfaz Message. Los mtodos proporcionados por esta interfaz los tienes en la siguiente
tabla:
Mtodo
String getAddress ().
Date getTimeStamp ().
void setAddress (String direccion).

Descripcin
Obtiene la direccin del mensaje.
Obtiene la fecha y hora de envo del mensaje (marca de tiempo "Unix").
Establece la direccin del mensaje.

Para mantener la compatibilidad con el estndar definido en la GCF, la funcionalidad de envo y


recepcin de mensajes es implementada mediante una interfaz que hereda de Connection: la
interfaz MessageConnection. Los mtodos proporcionados por esta interfaz los tienes en la
siguiente tabla:
Mtodo
Message newMessage (String tipo).
Message newMessage (String tipo, String direccion).
int numberOfSegments (Message msg).

28

Descripcin
Crea un nuevo mensaje del tipo indicado.
Crea un nuevo mensaje con el tipo y la direccin de destino
indicados.
Devuelve el nmero de segmentos necesarios para enviar
un determinado mensaje.

Message receive ().


void send (Message msg).
void setMessageListener (MessageListener oyente).

Recibe un mensaje (este mtodo detiene el hilo de


ejecucin mientras no se reciba un mensaje).
Enva un mensaje.
Registra el oyente que ser notificado cada vez que se
produzca la recepcin de un mensaje por esa conexin.

La interfaz que hereda de Message y que representa los mensajes de texto es


TextMessage. Sus mtodos los tienes en la siguiente tabla:
Mtodo
getPayLoadText ().
void setPayLoadText (String contenido).

Descripcin
Devuelve el contenido de un mensaje de texto.
Establece el contenido de un mensaje de texto.

29

Вам также может понравиться