You are on page 1of 41

VERSIÓN 1.

0
A medida que evoluciona la tecnología aumenta la posibilidad de añadir funcional
idad a nuestros dispositivos inalámbricos y así satisfacer las necesidades de lo
s usuarios. ¿Por qué conformarse con los paquetes que trae el móvil por defecto
cuando lo puedes personalizar?, para esto Java ha desarrollado un paquete llamad
o J2ME con el objetivo de desarrollar aplicaciones para PDAs, móviles, agendas e
lectrónicas y todo tipo de dispositivos que cumplan unas determinadas especifica
ciones. En este documento se pretende iniciar en el manejo de este paquete así c
omo familiarizarle con conceptos tales como MIDP, CLDC, MIDLET, RMS, Perfiles de
usuario y muchos otros.
Tutores: Mª Celeste Campo Vázquez y Carlos García Rubio Autores: Guillermo Diez-
Andino Sancho (gdandino@it.uc3m.es ) Rosa Mª García Rioja (rgrioja@it.uc3m.es) h
ttp://www.it.uc3m.es/pervasive
1
INDICE
OBJETIVOS ......................................................................
...........................................1 INTRODUCCIÓN.......................
................................................................................
..1 J2ME Y OTRAS TECNOLOGÍAS INALÁMBRICAS ......................................
...........2 WAP ...............................................................
..........................................................2 SMS ................
................................................................................
..........................2 I-MODE .............................................
.......................................................................2 J2SE vs
J2ME ..........................................................................
.....................................2 ARQUITECTURA DE J2ME.....................
...................................................................3 K VIRTUAL M
ACHINE .........................................................................
.................3 CONFIGURACIÓN ...............................................
...................................................4 PERFIL ....................
................................................................................
.................4 CONCEPTOS PREVIOS ...........................................
...................................................4 MANIFIESTO.................
................................................................................
..........4 DESCRIPTOR .........................................................
.................................................5 MIDLET ......................
................................................................................
.............5 INSTALACIÓN .....................................................
.......................................................6 UN PRIMER EJEMPLO .....
................................................................................
..........9 DESCARGA DE UN MIDLET ..............................................
.....................................13 PAQUETES Y CLASES PRINCIPALES...........
.........................................................14 JAVAX.MICROEDITON.MI
DLET ........................................................................14
JAVAX.MICROEDTION.LCDUI.........................................................
..................15 ALMACENAMIENTO DE DATOS ...................................
........................................21 COMUNICACIONES DE RED MEDIANTE J2ME M
IDP ........................................23 XML .............................
................................................................................
..............24 UNA APLICACIÓN DE DESCARGA ....................................
...................................26 Compilación ..............................
..............................................................................34
Preverificación ...............................................................
.........................................35 Creación del archivo jar ...........
................................................................................
35 Ejecución....................................................................
.............................................35 GLOSARIO .......................
................................................................................
.........37 BIBLIOGRAFÍA........................................................
.................................................38
i
OBJETIVOS
El objetivo de este documento es dar una visión general del lenguaje de programa
ción Java2 Micro Edition, desarrollado por Sun para cubrir las necesidades de di
spositivos con recursos muy limitados como teléfonos móviles y PDAs. En primer l
ugar se hará una introducción a la tecnología Java en general, para a continuaci
ón hacer una breve reseña de tecnologías paralelas existentes en el mercado. Tra
s ver las principales diferencias con Java2 SE se procederá a considerar los asp
ectos tanto de instalación como de ejecución de una primera aplicación. Por últi
mo se describirán las características principales de los paquetes más destacados
en J2ME con breves ejemplos que faciliten su entendimiento.
INTRODUCCIÓN
TECNOLOGÍA JAVA2 Si se ha trabajado con Java anteriormente, se conocerá la edici
ón estándar de Java, denominada J2SE (Java 2 Standard Edition). J2SE es un conju
nto de herramientas y APIs que permiten desarrollar applets y aplicaciones. En l
os orígenes de Java este kit cubría las necesidades del mercado ya que se podía
desarrollar todo lo demandado, pero a medida que pasa el tiempo y los ordenadore
s se adaptan más a los tiempos, aparecen nuevas exigencias a cubrir. Hoy en día
los productos software tienden a ser distribuidos, a compartir información en di
stintas ubicaciones físicas, esto es lo que se denomina “enterprice applications
”. Sun para cubrir las nuevas necesidades del mercado presenta J2EE (Java Enterp
rice Edition). La razón por la que no se integró el paquete J2EE en el J2SE que
ya era conocido es que las aplicaciones distribuidas suponen tratar tareas espec
íficas de red, operaciones de E/S y manejo de Base de datos con un enfoque total
mente distinto al que requiere una aplicación convencional. Además estas aplicac
iones requieren manejar una significante cantidad de almacenamiento, de memoria
y tienen una complejidad adicional en el diseño de APIs. Si J2EE surgió por los
nuevos requisitos que presentaban las aplicaciones ni que decir tiene que se pre
cisaba un paquete que diese soporte a las aplicaciones para móviles, PDAs, agend
as electrónicas... Estos dispositivos no cuentan con mucha memoria, tienen limit
aciones computacionales, los displays son pequeños...y es por esto que J2ME resu
me la funcionalidad de J2SE adaptándola a los requisitos mínimos necesarios que
son aplicables a los dispositivos móviles, inalámbricos.
J2EE
J2ME
J2SE
1
J2ME Y OTRAS TECNOLOGÍAS INALÁMBRICAS
En esta apartado se comentan algunas de las tecnologías y servicios inalámbricos
con el fin de esclarecer lo que no es J2ME, entre ellas se hablará de las más c
onocidas. WAP Acrónimo de Wireless Application Protocol, es una tecnología intro
ducida en el mercado en 1995 que permite a los dispositivos inalámbricos recibir
datos de Internet y mostrarlos en las pantalla de los mismos. Se piensa en Wap
como una tecnología que da soporte a buscadores Web en móviles pero en realidad
no es una aplicación sino un protocolo. SMS Short Messaging Service, es una tecn
ología que da soporte al envío y recepción de mensajes cortos de texto en dispos
itivos móviles. Otra característica interesante de SMS es que emplea una mensaje
ría unificada, lo que te permite acceder a mensajes de voz, al correo electrónic
o y faxes desde un dispositivo móvil. I-MODE Introducido al mercado por la compa
ñía Japonesa NTT DoCoMo, esta tecnología compite con WAP, ya que de igual modo o
frece un mecanismo de acceso a Internet a través de los dispositivos móviles. I-
Mode dispone de un lenguaje de etiquetas similar a HTML denominado compact HTML
(cHTML). La mayoría de sus usuarios se encuentran en Japón y otros países asiáti
cos.
J2SE vs J2ME
Java2 Micro Edition ha sido creado para adaptarse a las características de los n
uevos dispositivos inalámbricos tales como teléfonos móviles y PDAs. Consecuente
mente existirán diferencias con la versión estándar de Java destinada a PCs. Alg
unas de las principales diferencias son las siguientes: 1.- Tipos de datos J2ME
soporta un subconjunto de los tipos de datos de J2SE, los tipos float y double n
o son soportados por dos razones: la mayoría de dispositivos CLDC no tienen unid
ad de coma flotante y en segundo lugar es una operación muy costosa. 2.- Preveri
ficación (on-line y off-line) Al contrario que en J2SE dónde se realiza la verif
icación del código en tiempo de ejecución, en J2ME parte de la verificación se r
ealiza off-line, es decir, fuera del dispositivo. Esto tiene la finalidad de red
ucir la carga de la máquina, llevando a cabo el resto de la verificación on-line
. 3.- Descriptor y manifiesto
2
Al empaquetar archivos en J2ME es necesaria la inclusión de unos archivos especi
ales que contienen información de las aplicaciones que incluyen, estos archivos
de denominan manifiesto y descriptor 4.- Nueva librería gráfica Mediante el paqu
ete lcdui J2ME define un nuevo conjunto de clases para la creación de interfaces
gráficas. Estas clases están adaptadas a dispositivos con memorias muy limitada
s y pantallas de tamaño reducido. 5.- Desaparición del main Al contrario que las
aplicaciones de la edición estándar de Java, en J2ME no existe una función main
como punto de entrada para la ejecución del programa. El equivalente a este mai
n sería el método start app (será explicado posteriormente). 6.- Ausencia del re
colector de basura Con el objetivo de reducir la utilización de memoria, desapar
ece el recolector de basura en J2ME siendo necesario eliminar de forma explícita
todos aquellos elementos que no vayan a ser utilizados más.
ARQUITECTURA DE J2ME
En este apartado se describen brevemente los conceptos básicos relacionados con
J2ME. La arquitectura de alto nivel de J2ME se muestra en la siguiente figura:
K VIRTUAL MACHINE La K Virtual Machine es una máquina virtual java altamente por
table y compacta pensada y diseñada para funcionar en dispositivos con recursos
limitados y con conexión a red. El objetivo de la tecnología KVM es el de crear
la JVM más pequeña y completa que mantuviese los aspectos más importantes del le
nguaje de programación Java y que funcionase en dispositivos con procesadores de
16 o 32 bits y unas
3
capacidades de unos pocos cientos de KiloBytes (originalmente 128 Kbytes de memo
ria).
CONFIGURACIÓN Este nivel es menos visible a los usuarios, pero es muy importante
para los implementadores de perfiles. Define el conjunto mínimo de característi
cas de la KVM y las librerías de clases disponibles en una categoría de disposit
ivos. Representaría una franja horizontal de dispositivos con un mínimo denomina
dor común que los desarrolladores van a poder asumir que tienen todos los dispos
itivos con esta configuración. PERFIL Este nivel es el más visible a los usuario
s y desarrolladores de aplicaciones. Las aplicaciones se desarrollan sobre un de
terminado perfil que a su vez está implementado sobre una determinada configurac
ión. El perfil define un conjunto de APIs y características comunes para una fra
nja vertical de dispositivos. Las clases de un perfil permiten el acceso a funci
onalidades específicas de los dispositivos como el interfaz gráfico, funcionalid
ades de red, almacenamiento persistente, etc ... Las aplicaciones desarrolladas
sobre un determinado perfil van a ser portables a cualquier dispositivo que sopo
rte ese perfil. Cabe destacar que un dispositivo puede soportar varios perfiles
y que sobre una configuración pueden existir diversos perfiles. Actualmente el p
erfil más utilizado es MIDP (Mobile Information Device Profile).
CONCEPTOS PREVIOS
MANIFIESTO Cuando se empaquetan varias aplicaciones J2ME (MidLets) en un paquete
(MidLet Suite) es necesario incluir un fichero de texto denominado manifiesto.
La finalidad del manifiesto es describir el contenido del fichero .JAR con infor
mación tal como el nombre, versión, vendedor, etc .. también se incluye en este
fichero una entrada por cada MIDlet que lo compone. Un ejemplo de manifiesto pod
ría ser el siguiente:
MIDlet-1: Lista1, /icons/Lista1.png, Lista1 MIDlet-2: Texto1, /Icons/Texto1.png,
Texto1 MIDlet-Name: Ejemplos MIDlet-Vendor: Sun Microsystems MIDlet-Version: 1.
0
4
MicroEdition-Configuration: CLDC-1.0 MicroEdition-Profile: MIDP-1.0
DESCRIPTOR Aunque este fichero comparte el mismo formato que el del manifiesto,
su finalidad es totalmente diferente. El objetivo de este fichero es proporciona
r la información requerida por el Application Management Software (programa que
gestiona las descargas de aplicaciones entre otras cosas) para cerciorarse de qu
e el MIDlet suite es adecuado para el dispositivo en el que queremos instalarle.
Su extensión es .JAD y al contrario que el manifiesto, éste no se incluye en el
paquete. MIDLET Las aplicaciones que se desarrollan con J2ME e implementan la e
specificación MIDP para dispositivos móviles se denominan MIDLETs. Los MIDLETS s
e deben agrupar en un fichero .JAR para que sea posible su distribución (a otros
dispositivos, a través de Internet, por ejemplo). En un fichero .JAR se pueden
incluir varios MIDLETs y a este conjunto se le denomina MIDLETSuite. Por último
se presenta la información que se incluye en un MIDLET.JAR: • • • • • Clases MID
let Clases soporte Recursos(imágenes,sonido,...) Fichero Manifiesto ( fichero .m
f) Descriptor de aplicación (fichero .jad)
5
INSTALACIÓN
WINDOWS Antes de comenzar a implementar un MIDLET se precisa tener instalado un
software determinado que constituirá el entorno desarrollo J2ME. Los componentes
están disponibles en http://www.java.sun.com y son los que se presentan a conti
nuación: • • • Java 2 SDK Entorno de desarrollo visual (opcional) J2ME Wireless
Kit
Java 2 SDK, es el Kit de desarrollo estándar de Java que se emplea para diseñar
aplicaciones estándares. Este elemento debe ser el primero en instalarse ya que
los siguientes se apoyan en él. Se requiere la versión 1.3 o superior que encuen
tra disponible en el enlace http://java.sun.com/j2se/1.3/download-windows.html.
J2MEWT se puede ejecutar individualmente o como un componente integrado en uno d
e los siguientes entornos gráficos de desarrollo: KToolBar : Es el entorno visua
l de desarrollo que permite la creación de MIDLETS con J2ME. Se considera el más
simple de todos los aquí mencionados ya que ni siquiera cuenta con un editor. P
ara incluir los fuentes editados con otro programa se debe haber creado un proye
cto desde KToolBar, la herramienta crea la siguiente estructura de directorios d
entro del proyecto.
€
En el directorio src se deben incluir los fuentes para que KToolBar los pueda co
mpilar, pre-verificar y posteriormente emular.
6
Forte : Java: Se debe instalar antes que las J2MEWT, éste se puede descargar de
la página http://www.cun.com/forte/ffj/buy.html. Durante la instalación hay que
seleccionar la versión de JDK que se ha instalado.
€ € € €
Los requisitos hardware de Forte Java son un Pentium II a 300 MHz, 128 MB y 30 M
B de espacio en disco. Este entorno provee un entorno de desarrollo para J2SE Y
J2EE. El entorno incluye un editor de texto de GUI, un buscador de clases y un b
uscador de Web. El buscador de clases proporciona una vista gráfica de las clase
s que contiene el MIDLET que se está desarrollando. Utilizando este browser se p
uede navegar fácilmente por los métodos y atributos de las clases, así como anal
izar la clase compilada almacenada en el .JAR .
Code Warrior for Java: es un entorno visual que da soporte a J2ME , similar a Fo
rte Java, que cuenta con un editor de textos y un browser de clases. Este softwa
re se puede adquirir en http://www.codewarrior.com/ .
Jbuilder Handheld Express: presenta las mismas opciones que Forte Java y Code Wa
rrior, soporta el entorno de desarrollo J2ME pero sólo para Palms, aunque se esp
era que en breve se presente la versión que da soporte a móviles y agendas perso
nales. La página en la que se puede adquirir el software y obtener más informaci
ón es http://www.inprise.com/jbuilder/hhe/ .
J2ME Wireless Kit disponible para dos plataformas: Sun Solaris y Microsoft Windo
ws , se puede descargar en http://java.sun.com/ products/j2mewtoolkit/ download.
html . A continuación se va a comentar la instalación en Windows. 7
La versión Windows de la herramienta requiere un mínimo de 64MB y un espacio en
disco de 15MB. Se deben haber llevado a cabo los pasos anteriores, ya que si en
la instalación se detecta que no existe una versión de JDK no se permite continu
ar con la instalación. El entorno de desarrollo es opcional. Si se desea trabaja
r con un entorno de desarrollo no se debe seleccionar la opción de “Integrated”,
sino la de “Stand Alone”. Una vez completada la instalación se debe asegurar qu
e todo está correctamente instalado. Desde el promt de DOS vaya al directorio J2
MEWTK_DIR\apps\ example\bin\, luego verá que existe un fichero run.bat, ejecútel
o y si la instalación tuvo éxito verá la pantalla de inicio de la aplicación eje
mplo que incluye el paquete.
Ahora ya está todo listo para comenzar.
8
UN PRIMER EJEMPLO
Una vez superada la fase de instalación llegamos a la fase de creación de un pri
mer programa. Para ello basta disponer de un editor de texto cualquiera en el qu
e se irá escribiendo el código fuente que compilaremos bien desde el interfaz gr
áfico que el Wireless Toolkit ofrece o desde la propia línea de comandos. A cont
inuación se detallan los pasos para hacer funcionar nuestro “primer programa”. 1
.- Escribir el código fuente del programa, en este caso va a ser el HolaMundo.ja
va.
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public cl
ass Howdy extends MIDlet implements CommandListener{ private Command exitCommand
; private Display display; private Form screen; public Howdy() { display=Display
.getDisplay(this); exitCommand = new Command("Exit",Command.EXIT,2); screen = ne
w Form("Hola"); StringItem strItem = new StringItem(" ","Hola mundo"); screen.ap
pend(strItem); screen.addCommand(exitCommand); screen.setCommandListener(this);
} public void startApp() throws MIDletStateChangeException{ display.setCurrent(s
creen); } public void pauseApp(){ } public void destroyApp(boolean unconditional
){ } public void commandAction (Command c, Displayable s){ if(c==exitCommand){ d
estroyApp(false); notifyDestroyed(); } } }
9
Esta clase hereda de la clase MIDLET. En el constructor se capturan las caracter
ísticas del display, se crea una instancia de la clase Form , StringItem y del C
omando que me permite salir. Luego se añade la cadena y el comando de salida al
formulario y se incluye el capturador de eventos del comando, éste tiene una acc
ión asociada que se ejecutará al pulsar sobre esta opción.
2.- Compilar desde la línea de comandos:
C:\c:\jdk1.3\bin\javac -g:none -bootclasspath %SUNJ2MEHOME%\lib\midpapi.zip -cla
sspath %SUNJ2MEHOME%\lib\kvem.jar HolaMundo.java
Al utilizar el compilador de J2SE para compilar el ejemplo es necesario indicar
de alguna manera que las librerías CLDC y MIDP se encuentran en un lugar diferen
te. Esto se hace mediante la opción –bootclasspath. La opción –g:none se ha empl
eado para desactivar la posibilidad de incluir información en la depuración, hac
iendo de este modo los ficheros .class más pequeños. 3.- Preverificar Cuando se
trabaja con J2SE la máquina virtual Java (JVM) lleva a cabo un proceso de verifi
cación en tiempo de ejecución. Esto ocupa ciertos recursos que en dispositivos i
nalámbricos son relativamente escasos. Debido a las restricciones de estos dispo
sitivos se ha creado en J2ME un proceso denominado preverification consistente e
n llevar a cabo parte de la verificación de la KVM off-line, el resto será lleva
do a cabo como una verificación normal. El comando utilizado es el siguiente:
C:\>%SUNJ2MEHOME%\bin\preverify.exe -classpath %SUNJ2MEHOME%\lib\midpapi.zip -d
c:\Ejemplos c:\Ejemplos
4.- Crear el fichero .jar El siguiente paso consiste en empaquetar el Midlet en
un MidletSuite, que es un simple fichero .jar. Esto es un requerimiento por part
e de muchos dispositivos MIDP. Para realizar este proceso JDK1.3 dispone de la u
tilidad jar para archivar y comprimir ficheros .class en un paquete.
C:\>c:\JDK1.3\bin\jar cmf MANIFIESTO.MF HolaMundo.jar HolaMundo.class
5.- Ejecutar el Midlet Una vez dispuesto el Midlet dentro de un paquete llega la
fase de ejecución. Para simplificar la línea de comandos establecemos en primer
lugar las variables de entorno necesarias.
10
C:\>set CODEPATH=c:\Ejemplos
C:\>set CLASSPATH=%SUNJ2MEHOME%\lib\kvem.jar;%SUNJ2MEHOME%\lib\kenv.zip; %SUNJ2M
EHOME%\lib\lime.jar;%CODEPATH%
A continuación se lanza el emulador para ejecutar el programa:
C:\c:\jdk1.3\bin\java.exe -Dkvem.home=%SUNJ2MEHOME% -classpath %CLASSPATH% com.s
un.kvem.midp.Main DefaultGrayPhone -descriptor HolaMundo.jad
El resultado obtenido es el siguiente:
11
Finalmente se muestra un esquema de las fases anteriores
12
DESCARGA DE UN MIDLET
Una vez creado un MidLet llega la fase de distribución. Existen diversas maneras
como puede ser a través de un cable serie conectado al PC, pero la técnica más
empleada es a través de Internet. Esto conlleva una serie de pasos adicionales q
ue se describen a continuación. 1.- Seleccionar la aplicación Los dispositivos M
IDP proporcionan mecanismos que permiten a los usuarios descubrir o ser notifica
dos de los MIDlets suites que pueden ser descargados en sus dispositivos. Estos
MIDlets son identificados mediante su descriptor. 2.- Descargar y verificar el d
escriptor Una vez seleccionado el MidLet se procede a la descarga del descriptor
en el dispositivo. El AMS (Application Management Software) examinará el nombre
, versión, tamaño, versión de CLDC/MIDP para verificar que el entorno de ejecuci
ón será el correcto. 3.- Descargar y ejecutar el MIDlet suite Una vez verificado
el descriptor el AMS comenzará a descargar el archivo JAR de la dirección espec
ificada en el atributo MIDlet-Jar-URL. Una vez descargada la aplicación se contr
astará el descriptor con la información del manifiesto, para que en caso de que
los atributos correspondan el MIDlet suite se cargue y esté listo para su ejecuc
ión, en caso contrario será rechazado.
En la siguiente ilustración se muestra el proceso completo de descarga.
13
PAQUETES Y CLASES PRINCIPALES
A lo largo de este apartado se comentan los paquetes lcdui y midlet así como sus
clases más importantes, siendo el resto explicados en apartados independientes.
Los principales paquetes de J2ME son los siguientes: • • • • javax.microediton.
lcdui javax.microediton.midlet javax.microediton.rms javax.microediton.io
Se incluye una breve descripción de ciertos métodos en los casos que se consider
e relevante, ya que no hay que perder de vista que el objetivo de este documento
es iniciar, no ilustrar de forma detallada, con lo que si en algún momento dese
a información más concreta remítase a la ayuda online del perfil MIDP.
JAVAX.MICROEDITON.MIDLET Un MIDlet es una aplicación de MIDP. La aplicación debe
heredar de esta clase para que le permita gestionar el control del software. Un
MIDLET tiene 3 estados que son activo, pasivo y destruido, éstos se corresponde
n con los siguientes métodos: • • • startApp( )- La aplicación inicialmente se e
ncuentra en el estado “pausa”.A este método se le puede llamar varias veces si e
ntre medias se llama al método pauseApp() destroyApp( )- Mediante este método, l
a aplicación libera recursos. pauseApp( ) - Este método permite intercambiar el
MIDLET que se está ejecutando, pasándolo de activo a pasivo.
14
El administrador del entorno de ejecución de la aplicaciones es el que llama dir
ectamente a estos métodos, ya que un MIDLET no cuenta con el método “main”. El m
étodo de esta clase permite al gestor software de la aplicación crear, iniciar,
pasar al estado de pausa y destruir el MIDlet. Un MIDlet es el conjunto de clase
s diseñadas para ser ejecutadas y controladas por la aplicación vía la interfaz.
Se pueden tener varios MIDlets a la vez, y seleccionar cual está activo en un t
iempo concreto llamando al metodo startApp( ) y ponerlo en pausa con la llamada
a otro método, el pauseApp().
public void startApp() throws MIDletStateChangeException{ display.setCurrent(lis
t); } public void pauseApp(){ } public void destroyApp(boolean unconditional){ l
ist=null; exitCommand=null; display=null; } En este ejemplo se presentan únicame
nte los métodos anteriormente comentados. En el método startApp( ) se establece
la pantalla de esa clase. Hay que capturar la excepción dentro del mismo o lanza
rla. En destroyApp (boolean unconditional), se ponen a nulo los elementos instan
ciados en la clase, para liberar memoria ya que J2ME carece del recolector de ba
sura.
JAVAX.MICROEDTION.LCDUI En el paquete javax.microedtion.lcdui se encuentran las
clases que nos permiten desarrollar una interfaz de usuario. La clase pública Di
splay representa el gestor de las entradas y salidas del dispositivo del sistema
. Por cada MIDlet se crea una instancia de Display y la aplicación hace referenc
ia a esta instancia con la llamada al método getDisplay(). La aplicación llama a
este método desde startApp(). La clase Displayable es una superclase de todas l
as pantallas que se pueden poner en el Display.
Displayable
Screen
Canvas
Form
Alert
List
TextBox 15
La clase Displayable tiene dos descendientes directos , Screen y Canvas. La prin
cipal abstracción de la interfaz de usuario de MIDP es la pantalla, instancia de
la clase Screen. Una pantalla es un objeto que encapsula las especificaciones g
ráficas del dispositivo. Este objeto captura todos los eventos que tienen lugar
cuando el usuario está navegando por su pantalla. La aplicación puede cambiar de
pantalla invocando al método Display.setCurrent (Displayable). Esta clase prese
nta la posibilidad de incluir un título para la pantalla y un Ticker, para ello
cuenta con los métodos getTitle(), setTitle(String), getTicker(), setTicker(Tick
er). Para incluir elementos (deben ser del tipo Item) dentro de una pantalla hac
e falta un contenedor, que viene representado por la clase Form. Los métodos pri
ncipales de esta clase, que son los que permiten trabajar con Items, realizan fu
nciones tales como la inserción, borrado y obtención de un Item. Se presentan a
continuación: • • • • • int append(Item elemento) void insert(int index,Item ele
mento) get(Item) set(int index, Item elemento) delete(int index)
Otro elemento que se puede incluir en un objeto Screen es un mensaje informativo
para el usuario, teniendo la posibilidad de definir la duración del mismo en pa
ntalla, esto se consigue instanciando la clase Alert. Alert(String titulo,String
texto, Image imagen, AlertType a) El primer parámetro que se incluye en el cons
tructor de esta clase es el título que se asocia al mensaje a visualizar. En el
parámetro texto se incluye el contenido a mostrar por pantalla, el mensaje propi
amente dicho. El parámetro imagen es la imagen que se va a incluir en el mensaje
, aunque se puede obviar poniéndolo a nulo. Por último el parámetro AlertType in
dica el tipo al que corresponde este mensaje, éstos pueden ser: • • • • • Alarm
Confirmation Error Info Warning
El método más destacable de esta clase es el que permite determinar el tiempo qu
e permanecerá en pantalla el mensaje que es setTimeout(int time). A continuación
se muestra como crear un objeto Alert, su asignación de tiempo y la visualizaci
ón en pantalla.
16
Alert conversion= new Alert("Conversion AlertType.INFO); conversion.setTimeout(A
lert.FOREVER); pantalla.setCurrent(conversion);
También puede ser deseable incluir una lista con opciones que se puedan seleccio
nar dentro de la pantalla, esto se consigue utilizando la clase List. Hay tres t
ipos básicos de lista: exclusiva, implícita y múltiple. List(String titulo,int t
ipolista,String[] Elementos, Image[] imágenes) Los elementos que se van a inclui
r en la lista así como las imágenes que se relacionan con los mismos se pasan al
método como un array. A continuación se presenta una clase que crea una lista y
la inicializa con los valores "Opcion A","Opcion B","Opcion C". public class Li
sta1 extends MIDlet implements CommandListener{ private List list; private Comma
nd exitCommand = new Command("Salir",Command.EXIT,1); private String[] options={
"Opcion A","Opcion B","Opcion C"}; private Display display; public Lista1(){ lis
t=new List("Elija una opción",List.IMPLICIT,options,null); list.addCommand(exitC
ommand); list.setCommandListener(this); display=Display.getDisplay(this); } La c
lase TextBox implementa un componente de texto que rellena toda la pantalla. El
constructor nos permite incluir el título, un texto inicial, el tamaño máximo de
caracteres que se pueden incluir en ese TextBox, así como las restricciones del
tipo de datos que se pueden incluir. Las restricciones son las siguientes: • •
• • • • ANY - no impone restricciones en el tipo de texto a incluir EMAILATOR -
sólo se permite incluir direcciones de e-mail NUMERIC – los datos han de ser de
tipo numérico PASSWORD – este tipo enmascara los caracteres que se introducen PH
ONENUMBER – permite incluir exclusivamente números de teléfono URL – permite la
inserción de URLs
En el API de MIDP también están incluidos los componentes que derivan de la clas
e Item y ChoiceGroup.
£ $ ¨¨ 0) ¨© ¨¥ % & ¨¥ ¨# " !   §  ¡  ¨© ¨¦¤ ¡ £ ¢€ $¥ £  § (' % $   §¥ ¡
17
Item
StringItem
ImageItem
TextField
DateField
Gauge
La clase StringItem representa un elemento que contiene una cadena de texto, y c
uenta con dos de métodos para coger y devolver el valor de la cadena. Para repre
sentar imágenes se cuenta con la clase ImageItem. A continuación se presenta un
ejemplo en el que se trabaja con la clase StringItem e ImageItem. Primero se cre
an y se inicializan la pantalla, el formulario, los comandos y se crea un elemen
to StringItem a cuyo constructor se le pasa la cadena que contiene, en este caso
“Bienvenido”. A continuación se crea una imagen indicando dónde se encuentra y
posteriormente se le pasa al constructor de ImageItem, junto con la ubicación qu
e se quiere que ocupe en la pantalla. Ya para finalizar se añade el objeto frase
y dibujito, ambas instancias de las clases StringItem e ImageItem, al formulari
o mediante la invocación al método append(Item).
//constructor que inicializa los valores de los atributos public EjemploItem(){
Image dibu=null; pantalla=Display.getDisplay(this); salir= new Command ("Salida"
,Command.EXIT,2); formulario= new Form("Programa 1"); StringItem frase = new Str
ingItem(" ","Bienvenido "); try{ dibu= Image.createImage("/icons/Duke.png"); }ca
tch (IOException e){ System.out.println("error"+e); } ImageItem dibujito=new Ima
geItem("",dibu,ImageItem.LAYOUT_DEFAULT,""); formulario.append(frase); formulari
o.append(dibujito); formulario.addCommand(salir); formulario.setCommandListener(
this); }
18
TextField presenta una ventana de texto que se incluye en un formulario. A difer
encia de la clase TextBox, se puede añadir a un formulario junto con otros eleme
ntos y no ocupa toda la pantalla. Este ejemplo se va a comentar a la vez que se
muestra el código. Dentro de la clase que se ha creado se define un elemento de
tipo Form y otro de tipo TextField y se inicializan en el constructor.
private Form formulario; private TextField pesetas; En el caso del TextField, se
indica el titulo que queremos que aparezca en el TextField, el valor inicial qu
e en este caso es nulo, la restricciones de los tipos de datos que se admiten en
este elemento, son las mismas que las de TextBox y en este caso se indica que s
ólo se admiten datos de tipo numérico. public Euros(){ pantalla=Display.getDispl
ay(this); formulario=new Form("Conversor de euros"); pesetas = new TextField("Pt
s a convertir","",5,TextField.NUMERIC); Ahora ya solo queda añadírselo al formul
ario y para ello lo hacemos como se muestra a continuación
formulario.append(pesetas); } DateField es un componente editable que presenta i
nformación de tipo fecha y hora en un formulario. En el constructor se añade la
etiqueta que se le asigna y el modo que viene definido por unas constantes que s
on: • • • DATE – Tipos de datos de fecha TIME – para horas DATE_TIME – para hora
s y fechas
La Clase Gauge implementa un gráfico de barras para visualizar valores represent
ados en rangos de porcentajes. La clase ChoiceGroup es como la de JDK, represent
a una lista de elementos que el usuario puede seleccionar y que cada uno de ello
s tiene una acción asociada. Una vez comentada la clase Screen ,se dará una brev
e descripción de la clase Canvas y Graphics ya que no presentan ninguna diferenc
ia sobre las de JDK. La clases Canvas se emplea para las aplicaciones en las que
se necesita capturar eventos y realizar llamadas gráficas para dibujar en el di
splay. Esta clase es
19
intercambiable con la clase Screen, por ejemplo en un formulario se puede inclui
r un elemento List y que la opción seleccionada realice un dibujo, utilizando pa
ra ello la clase Canvas. Para dibujar cualquier elemento es imprescindible invoc
ar al método paint(Graphics dibujo) de la clase Canvas. El objeto Graphics defin
e una región que se considera inválida, con la llamada al método paint() se cons
igue que se pinten todos los pixels de esa región. La clase Graphics provee la c
apacidad de renderizar figuras geométricas 2D, permite dibujar textos , imágenes
, líneas, rectángulos y arcos, para ello cuenta con los métodos: • • • • • • dra
wString() drawImage (Image img, int x, int y, int anchor) drawLine(int x1, int y
1, int x2, int y2) drawRect(int x, int y, int width, int height) drawRoundRect(i
nt x, int y, int width, int height, int arcWidth, int arcHeight) drawArc(int x,
int y, int width, int height, int startAngle, int arcAngle)1
Los rectángulos y los arcos se pueden rellenar con la llamada al método fillRect
(int x, int y, int width, int height) y fillArc(int x, int y, int width, int hei
ght, int startAngle, int arcAngle).
1
A diferencia de Java Estándar no existe el método drawOval( ), con lo que para d
ibujar un óvalo se emplea el método drawArc( ) y se especifica que el ángulo es
de 360
20
ALMACENAMIENTO DE DATOS
El almacenamiento y recuperación de datos de forma persistente es una caracterís
tica propia de prácticamente todos los lenguajes de programación. J2ME MIDP defi
ne una simple base de datos de registros denominada record management system (RM
S) con el objetivo de poder almacenar información una vez que el MIDlet finalice
. La unidad de almacenamiento básica dentro de RMS es el record que es almacenad
o en una base de datos especial denominada record store. Un record (registro) co
mo su nombre indica es un simple array de bytes, mientras que un record store es
un fichero binario que contiene una colección de registros. El API empleado par
a la creación y manejo de estos registros es descrito en el paquete javax.microe
dition.rms; este paquete define dos clases, tres interfaces2 y cinco excepciones
. RecordStore, RecordEnumeration RecordComparator, RecordFilter, RecordListener
InvalidRecordIDException, RecordStoreException, RecordStoreFullException, Record
StoreNotFoundException, RecordStoreNotOpenException. A continuación se describen
las clases disponibles en el API así como sus funciones de manejo básicas. Reco
rdStore Algunas de las normas básicas a la hora de crear un RecordStore son las
siguientes: • • • Los nombres no deben superar los 32 caracteres, cabe mencionar
que se distingue entre mayúsculas y minúsculas. Dentro de un MIDlet suite no de
ben existir dos record store con el mismo nombre Los RecordStores creados dentro
de un MIDlet suite no son accesibles a otros.
Las funciones básicas de manejo de record store se muestran a continuación: . op
enRecordStore: abre un record store existente, en caso contrario crea uno nuevo.
Ej. RecordStore fichero = null; fichero = RecordStore.openRecordStore("fichero_
prueba",true); . closeRecordStore: cierra un record store Ej. fichero.closeRecor
dStore();
2
En la especificación MIDP, RecordEnumeration está definida como un interfaz, aun
que no es necesario implementarlo ya que lo hace MIDP. A efectos del programador
se trata como una clase más.
21
. deleteRecordStore: borra un record store . getName: obtiene el nombre de un re
cord store . getNumRecords: obtiene el número de registros dentro de un record s
tore Existen una serie de métodos adicionales para la obtención de la informació
n de cabecera sobre el record store, las más empleadas son: getLastModified, get
NextRecordID, getNumRecords, getVersion. Es posible asimismo obtener otros tipos
de información sobre el record store, esta información no está disponible en la
cabecera, pero se puede acceder a ella mediante implementación, para ello se di
spone de los métodos: getSizeAvailable, getSize, listRecordStores. Este último m
étodo merece mención especial ya que ofrece la posibilidad de obtener un array c
on los nombres de todos los record stores que pertenecen a un MIDlet suite. Con
respecto al manejo de registros se dispone de los siguientes métodos: . addRecor
d: añade un nuevo registro, éste debe encontrarse como un array de bytes, el val
or devuelto por esta función es un entero denominado record ID . getRecord: se o
btienen los datos almacenados en un determinado registro . setRecord: este métod
o se emplea para establecer los datos de un registro. . deleteRecord: eliminar u
n registro de un record store Cada vez que se crea un nuevo registro en un fiche
ro se le asigna un identificador único dentro del mismo, record ID, éste será ut
ilizado para localizarle dentro del fichero de manera única, una vez eliminado u
n registro, este permanece a NULL, su identificador con. Un pequeño ejemplo de e
scritura en un fichero se muestra a continuación:
public void Escribir(){ String nombre1="Pepe", nombre2="Juan"; byte[] dato1,dato
2; int id = 0; dato1=nombre1.getBytes(); dato2=nombre2.getBytes(); try{ id=fiche
ro.addRecord(dato1,0,dato1.length); System.out.println("Escribiendo ..."); }catc
h (RecordStoreException e){ e.printStackTrace(); } System.out.println("El id del
primer registro es: " + id); }
Por último comentar que una opción interesante a la hora de navegar entre los re
gistros, es la clase RecordEnumeration que ofrece las siguientes funciones: hasN
extElement,
22
hasPreviousElement, nextRecord, previousRecordId, rebuild y reset.
nextRecordId,
numRecords,
previousRecord,
COMUNICACIONES DE RED MEDIANTE J2ME MIDP
La capacidad de movilidad y conectividad de los dispositivos móviles quedaría me
rmada si no se dispusiese de un mecanismo para poder acceder a datos remotos y r
edes corporativas, en resumen, Internet. El funcionamiento de red en J2ME tiene
que ser muy flexible para soportar una gran variedad de dispositivos, para ello
se introduce un nuevo concepto, "marco de conexión general" consistente en abstr
aer el funcionamiento de red y los ficheros de entrada/salida. Todas las clases
e interfaces se encuentran en el paquete javax.microedition.io. J2ME soporta las
siguientes formas de comunicación: . HTTP . Sockets . Datagramas . Puerto serie
. Fichero
23
Todas estas formas de comunicación son creadas mediante el método Connector.open
(), al que se le especificará el tipo de comunicación. static Connection open(St
ring connectString, int mode, boolean timeouts) Ejemplo: Connection hc = Connect
or.open("http://www.uc3m.es") Connection dc = Connector.open("datagram://www.uc3
m.es:9000") Connection sc = Connector.open("comm:0;baudrate=9000") En los ejempl
os anteriores se está creando en primer lugar una comunicación http, a continuac
ión mediante datagramas para finalmente llevar a cabo una comunicación serie. En
estos ejemplos no se ha especificado ninguno de los dos parámetros posibles: mo
do y timeout. El parámetro mode permite seleccionar el tipo de acceso, existen t
res posiblidades: READ, READ_WRITE y WRITE. El valor tomado por defecto en caso
de que no se seleccione ningún modo es de lectura/escritura. Hay que tener en cu
enta que si el modo de acceso no es soportado por el protocolo, se lanza una Ill
egalArgumentException. En caso de que el parámetro timeouts esté a true genera u
na excepción de tipo InterruptedIOException, indicando que se ha superado el tie
mpo de espera en la apertura de la comunicación. Cabe destacar que de todas las
implementaciones MIDP existentes, MotoSDK es la única que soporta los tres proto
colos de red (http, udp, tcp/ip), aunque el J2ME Wireless Toolkit de Sun sólo so
porta comunicación http, existe una característica no documentada que permite ej
ecutar un socket o programa que utilice udp estableciendo para ello la variable
de entorno ENABLE_CLDC_PROTOCOLS = INTUITIVE_TOOLKIT.
XML
XML (Xtensible Markup Language) en los últimos años se ha convertido en un están
dar para el intercambio de datos. La finalidad de xml es hacer los datos portabl
es a través de diferentes aplicaciones. Muchas de las aplicaciones desarrolladas
hoy en día conllevan un intercambio de datos constante con fuentes variadas. Es
tos datos pueden encontrarse en diversos formatos por lo que se hace necesaria u
na conversión. El enfoque de xml es evitar este paso intermedio generando para e
llo los llamados “documentos xml”. Un documento xml es un fichero que contiene i
nformación categorizada mediante etiquetas; éstas definen las estructuras de los
datos así como los elementos que los componen. Existen una serie de parsers bas
ados en Java. Los más destacados son TinyXML, NanoXML y /Elfred. Estos fueron or
iginalmente escritos en J2SE, aunque ya se encuentran varias versiones existente
s para J2ME.
24
Los ficheros necesarios (así como sus tamaños) para poder utilizar alguno de est
os parsers son los siguientes: Tiny XML tinyxml_event.jar 10KB NanoXML nanoxml_t
ree.jar 9KB /Elfred SAX aelfred_event.jar 18KB Para el caso del parser de SAX se
deben soportar ocho métodos: endDocument(), startElement(), endElement(), chara
cters(), ignorableWhitespace(), processingInstruction() y setDocumentLocator().
Un pequeño ejemplo que utiliza el parser NanoXML’s SAX sería el siguiente: try{
Parser parser = ParserFactory.makeParser(“nanoxml.sax.SAXParser”); DemoHandler m
iHandler = new DemoHandler(); Parser.setDocumentHandler(miHandler); Parser.parse
(urlstring); ResultString = miHandler.getResultString(); }catch(Exception e){ Sy
stem.out.println(e); }
€ € €
25
UNA APLICACIÓN DE DESCARGA
Una vez vistas las principales características y funcionalidades de J2ME se va a
proceder a la realización desde cero de una aplicación que dada la URL de una p
ágina Web la descargue y almacene en un fichero para su posterior visualización.
El Midlet está estructurado en tres clases:
€
Conexión: clase encargada de establecer la conexión, descargar la página Web y d
evolverla como un array de bytes. Fichero: gestiona todos los aspectos relaciona
dos con el almacenamiento en fichero de las páginas Web. Comunicación: clase pri
ncipal con los interfaces que gestiona la descarga de las páginas.
€ €
A continuación se van a ir comentando cada una de ellas, así como sus correspond
ientes métodos. Primero se comenta la clase Conexión que como su propio nombre i
ndica en esta clase se establece la conexión con el servidor Web indicado en una
ventana de texto. Para trabajar con conexiones es J2ME se debe incluir el paque
te javax.microedition.io, el resto de los paquetes depende de la operativa inter
na, en nuestro caso se han incluido las siguientes: import javax.microedition.io
.*; import java.io.*; import java.util.*; La clase conexión cuenta con los sigui
entes atributos: • • • • _con conexión propiamente dicha _sal flujo de datos de
recepción. _datos representa la información en flujo de bytes que se ha descarga
do _dirección URL de la página a la que nos queremos conectar.
En el constructor de la clase se inicializa el atributo _dirección al valor del
parámetro que recibe el método. public class Conexion { private StreamConnection
_con = null; private InputStream _sal = null; private StringBuffer _datos; priv
ate String _direccion; public Conexion(String direc){ _direccion = new String(di
rec); }
26
Para poder establecer la comunicación se debe abrir la comunicación indicando la
URL a la que se quiere conectar, esto se hace mediante la llamada la método ope
n(URL) de la clase Conector, se debe hacer un cast para indicar que la comunicac
ión es de tipo http, ya que se dispone de distintos tipos de comunicación3. En c
aso de que la dirección introducida no siga el formato correcto un excepción del
tipo IllegalArgumentException será lanzada. Si por el contrario el formato es c
orrecto, pero el servidor no está operativo o la dirección introducida no existe
la excepción será ConnectionNotFoundException. Una vez establecida la conexión
sin problemas, lo siguiente es crear un flujo de datos de recepción para poder l
eer del destino.
public void abrir() throws ConnectionNotFoundException, IllegalArgumentException
, IOException{ _con = (HttpConnection)Connector.open(_direccion); _sal = _con.op
enInputStream(); }
El siguiente paso es la descarga de la pagina, en este caso se hace leyendo cará
cter a carácter mediante el flujo de datos creado para esta conexión concreta; l
os datos son almacenados en el atributo _datos. Si se produce algún error en la
lectura se lanza la excepción IOException. El tratamiento dado a las excepciones
dentro de las clases Fichero y Conexion es que en caso de que se produzca una d
entro de la propia clase será propagada hacia el exterior para que la clase prin
cipoal sea la encargada de gestionarlas de forma adecuada, es decir, que el trat
amiento de las excepciones sea independiente de las clases que las generan. publ
ic void descargar() throws IOException{ _datos= new StringBuffer(); int _ch; whi
le ((_ch = _sal.read())!=-1){ _datos.append((char)_ch); } }//fin de private read
pagina El método getpagina permite acceder a los datos descargados devolviendo u
na array de bytes con el contenido descargado.
3
Ver apartado Comunicaciones de red mediante J2ME
27
public StringBuffer getpagina(){ return _datos; } Cuando ya se han realizado tod
as las operaciones necesarias se debe cerrar la conexión para liberar recursos a
sociados con el flujo de datos y la conexión, la conexión finaliza. public void
cerrar() throws IOException{ _sal.close(); _con.close(); } }
A continuación se va a comentar la clase Fichero, que almacena en un Record Stro
re la página descargada. Para poder manejar el RecordStore se precisa el paquete
javax.microedition.rms. El record store es una colección de registros localizad
os por un identificador propio de cada registro. Por simplificar el ejemplo se h
a considerado como únicos atributos el nombre del fichero (inicializado en el co
nstructor) y el Record Store del fichero.. public class Fichero{ private RecordS
tore _fichero =null; private String _nombre= null; public Fichero(String nomfich
){ _nombre=new String(nomfich); } Lo primero es indicar qué fichero queremos abr
ir y si se desea que se cree en caso de que no exista, esto se logra mediante la
llamada al método openRecordStrore. Al tratar de abrir el fichero se pueden pro
ducir errores porque éste no se encuentre o bien debido a la falta de espacio en
el dispositivo.
public void abrir() throws RecordStoreException, RecordStoreFullException, Recor
dStoreNotFoundException{ _fichero = RecordStore.openRecordStore(_nombre,true); }
La operación de borrado de fichero también puede interesar implementarla, ya qu
e se ha como se ha visto, algunos errores pueden ser producidos por la falta de
espacio. public void borrar() throws RecordStoreNotFoundException, RecordStoreEx
ception{
28
_fichero.deleteRecordStore(_nombre); } El método que se presenta a continuación
es el encargado de añadir un registro al fichero, en nuestro caso tendríamos un
único registro que contiene la página descargada. Este método nos devuelve el at
ributo _id que contiene el identificador del registro insertado, éste será neces
ario para la posterior recuperación del fichero. public int insertar(byte[] dato
s) throws RecordStoreFullException, RecordStoreNotOpenException, RecordStoreExce
ption{ int _id = 0; _id=_fichero.addRecord(datos,0,datos.length); return _id; }
El siguiente mégodo recupera el archivo descargado accediendo al RecordSotre med
iante el identificador, _id, para finalmente devolver un array de bytes. Las exc
epciones que se lanzan en éste método se deben a que no se puede cargar el regis
tro o el identificador no tiene asociado ningún registro. public byte[] Visualiz
ar(int id) throws RecordStoreNotOpenException, InvalidRecordIDException, RecordS
toreException{ byte[] datos=null; datos=_fichero.getRecord(id); return datos; }
Una vez que ya no se van a realizar más operaciones sobre el Record Store se cie
rra mediante el método cerrar. public void cerrar() throws RecordStoreNotOpenExc
eption, RecordStoreException{ _fichero.closeRecordStore(); } }//Cierre de la cla
se Fichero Creadas ya las clases Comunicación y Fichero, será necesaria una clas
e que controle el flujo de programa e instancia a Fichero y Conexión, ésta es la
clase Comunicación.
29
Los paquetes a incluir son los que se indican a continuación. javax.microedition
.midlet.*; javax.microedition.lcdui.*; javax.microedition.io.*; javax.microediti
on.rms.*; java.io.*; java.util.*; Los atributos de esta clase son los elementos
que se añaden al objeto Displayable, como Form, TextBox, TextField, Command, etc
. public class Comunicacion extends MIDlet implements CommandListener{ private C
ommand salir, volver, ir; private Display pantalla; private Form formulario; pri
vate TextField direccion,guardar; private TextBox pagina=null; private TextBox e
ditor=null; private Conexion _conexion; private Fichero _fichero; public Comunic
acion(){ pantalla=Display.getDisplay(this); inicia_formulario(); } En el constru
ctor se indica cuál es la pantalla activa para a continuación llamar al método i
nicia_formulario. Como se ve a continuación hay tres métodos denominados inicia_
X, donde X es una instancia de algún hijo de la clase Screen. En estos métodos s
e inicializan los valores de los elementos de X (formulario,TexBoxt, List,..) y
se añaden a éste. En la pantalla se va a visualizar el formulario inicial, el Te
xtbox que muestra el contenido de la página descargada y el TextBox que muestra
el fichero. public void inicia_formulario(){ formulario=new Form("Conectarse a..
."); direccion = new TextField("Introduzca la URL","",256,TextField.URL); guarda
r=new TextField("nombre de l fichero a guardar","",256,TextField.URL); salir = n
ew Command("Salida", Command.EXIT,2); ir = new Command("Ir a ", Command.OK,2); f
ormulario.append(direccion); formulario.append(guardar); formulario.addCommand(s
alir); formulario.addCommand(ir);
30
formulario.setCommandListener(this); }
public void inicia_pagina(){ salir = new Command("Salida", Command.EXIT,2); volv
er = new Command("Ver Fichero", Command.OK,2); cargarpagina(); pagina.addCommand
(volver); pagina.addCommand(salir); pagina.setCommandListener(this); } public vo
id inicia_editor(){ volver = new Command("Volver", Command.EXIT,2); salir = new
Command("Menu", Command.EXIT,2); editor=new TextBox("Visualiza RMS",tratarficher
o(),tratarfichero().length(),0); editor.addCommand(volver); editor.addCommand(sa
lir); editor.setCommandListener(this); } A continuación se presentan los métodos
que permiten la ejecución del midlet y que modifican los estados del mismo a lo
largo de su ciclo de vida. La funcionalidad de ellos es la misma que la comenta
da en el ejemplo HolaMundo, cabe destacar que en el método destroyApp se igualan
todos los elementos de la pantalla a nulo, para liberar memoria ,ya que J2ME no
cuenta con el recolector de basura de J2SE.
public void startApp() throws MIDletStateChangeException{ pantalla.setCurrent(fo
rmulario); } public void pauseApp(){ } public void destroyApp(boolean unconditio
nal){ direccion = null; formulario=null; pantalla=null; editor = null; dirección
= null; guardar = null; salir = null; volver = null; 31
ir = null; } Hasta aquí ya se dispone de los interfaces y métodos necesarios par
a poder ejecutar el midlet, pero falta lo que aporta la funcionalidad a la aplic
ación. Como se indicó la principio de este apartado, mediante este ejemplo se pr
etende descargar una página Web y almacenarla en un fichero. Para ello se han im
plementado los métodos cargarpagina y tratarfichero. El cargar página se estable
ce la conexión y se descarga la página haciendo uso de la clase Conexión. El con
tenido de la página se obtiene mediante el método getpagina y se visualiza en el
TextBox página. Como en la clase Conexión no se han capturado las excepciones s
ino que sólo se han lanzado, ahora hay que capturarlaa y asociarlas funcionalida
d, en éste ejemplo simplemente se visualiza el error. public void cargarpagina()
{ Conexion _conecta=null; String _texto; try{ _conecta= new Conexion(direccion.g
etString()); _conecta.abrir(); _conecta.descargar(); _texto =_conecta.getpagina(
).toString(); pagina=new TextBox("Pagina cargada",_texto,_texto.length(),0); _co
necta.cerrar(); }catch(ConnectionNotFoundException co){ System.out.println("Erro
r: "+co.getMessage()); }catch(IllegalArgumentException ia){ System.out.println("
Error: "+ia.getMessage()); }catch (IOException e){ System.out.println("Se ha pro
ducido un error de I/O"); } }//fin de private readpagina
El método tratarfichero abre un fichero en el que almacena la información obteni
da en la descarga de la página de Internet para devolvérselo a la aplicación que
lo va a tratar, aquí se emplea una instancia de la clase Fichero y sus métodos.
32
Al igual que en el método anterior se capturan las excepciones y se les asocia l
a acción de visualizar un mensaje de error. public String tratarfichero(){ Strin
g texto= null; try{ _fichero=new Fichero(guardar.getString()); _fichero.abrir();
int identificador=_fichero.insertar(pagina.getString().getBytes()); _fichero.ce
rrar(); _fichero.abrir(); byte[] contenido= _fichero.Visualizar(identificador);
texto =new String(contenido); _fichero.cerrar(); }catch(RecordStoreNotFoundExcep
tion e1){ System.out.println("Error: "+e1.getMessage()); }catch(RecordStoreFullE
xception e2){ System.out.println("Error: "+e2.getMessage()); }catch(RecordStoreN
otOpenException e3){ System.out.println("Error: "+e3.getMessage()); }catch(Inval
idRecordIDException e4){ System.out.println("Error: "+e4.getMessage()); }catch(R
ecordStoreException e5){ System.out.println("Error: "+e5.getMessage()); } return
texto; } Para finalizar con este ejemplo, sólo queda capturar los eventos que s
e producen cuando se selecciona una “opción” (un command), para ello está e l mé
todo command Action. Dado que existen tres elementos que lanzan eventos, debido
a que el formulario, la pantalla y el editor tienen commands añadidos, lo primer
o que hay que hacer es ver de dónde provienen los eventos. Esto se comprueba med
iante instanceof que informa del tipo de objeto que contiene ese command. Una ve
z que ya se conoce se comprueba qué “opción ” es la solicitada para ejecutar el
código asociado a dicha opción. public void commandAction(Command c, Displayable
s){ if (s instanceof Form) { if(c== salir){ destroyApp(false); notifyDestroyed(
); } if(c== ir){ inicia_pagina(); pantalla.setCurrent(pagina);
33
} } else if (s instanceof TextBox) { TextBox obj = (TextBox) s; if (obj == pagin
a) { if(c== volver){ inicia_editor(); pantalla.setCurrent(editor); } if(c== sali
r){ destroyApp(false); notifyDestroyed(); } } if (obj == editor) { if(c== volver
){ pantalla.setCurrent(formulario); } if(c== salir){ destroyApp(false); notifyDe
stroyed(); } } } } } Si se siguen los pasos anteriores y se ejecuta la aplicació
n se observa un interfaz como el que se presenta, en la primera pantalla se soli
cita la URL y el fichero en el que se desea almacenar. A continuación está la pa
ntalla con la página recién descargada, y en caso de seleccionar la opción Ver F
ich, se obtendrá la pantalla Visualiza RMS que contendrá el fichero a visualizar
. Una vez creado todo el código comienza la fase de compilación, a la que seguir
án la de preverificación, creación del .jar y ejecución, para ello basta con esc
ribir lo siguiente: Compilación %COMPI%javac.exe -g:none -bootclasspath %RUTAJ2M
E%\lib\midpapi.zip -d %RUTAFUENTES%\tmpclasses -classpath %RUTAFUENTES% %RUTAFUE
NTES%\*.java Para compilar los archivos .java (Conexión.java, Fichero.java y Com
unicación.java) basta con escribir el comando anterior. Se han utilizado variabl
es de entorno para simplificar el comando. %COMPI% es la ruta donde se encuentra
instalado el jkd1.3, %RUTAJ2ME% indica el directorio base de el j2me wireless t
oolkit y por último en %RUTAFUENTES% como su nombre indica contiene la ruta de l
os fuentes. Las opciones empleados son –g:none para no incluir información de de
puración, -
34
bootclasspath para indicar la ruta de las clases j2me a utilizar, con -d directo
rio indicamos dónde queremos que nos deje el compilador las clases recién compil
adas y por último –classpath que será la ruta dónde se encuentran los fuentes a
compilar. Preverificación %RUTAJ2ME%\bin\preverify.exe -classpath %RUTAJ2ME%\lib
\midpapi.zip;%RUTAFUENTES%\tmpclasses -d %RUTAFUENTES%\classes %RUTAFUENTES%\tmp
classes Como ya se ha mencionado anteriormente, J2ME realiza parte de la preveri
ficación “off -line”, con este comando podemos llevarlo a cabo. Las opciones y r
utas son las mismas que en la compilación salvo el directorio tmpclasses que ser
á donde se almacenarán las clases preverificadas. Creación del archivo jar %COMP
I%jar cmf %RUTAFUENTES%\META-INF\MANIFEST.MF %RUTAFUENTES%\Comunicacion.jar -C %
RUTAFUENTES%\classes . Una vez compiladas y preverificadas las clases se pasa al
empaquetamiento mediante la utilidad jar, para ello basta indicarle las clases
a empaquetar así como los recursos adicionales a incluir, en este caso será el m
anifiesto que será distribuido con el MidLet Suite. Las opciones cmf indican que
se desea empaquetar (c) incluyendo un manifiesto (m) para obtener un fichero (f
) que en este caso será Comunicación.jar. El manifiesto incluido en esta aplicac
ión será el siguiente:
MIDlet-1: Comunicacion, Comunicacion.png, Comunicacion MIDlet-Name: Comunicacion
MIDlet-Vendor: Sun Microsystems MIDlet-Version: 1.0 MicroEdition-Configuration:
CLDC-1.0 MicroEdition-Profile: MIDP-1.0
Ejecución
set CLASSPATH=%RUTAJ2ME%\lib\kvem.jar; %RUTAJ2ME%\lib\kenv.zip; %RUTAJ2ME%\lib\l
ime.jar;%RUTAFUENTES%
%COMPI%java.exe -Dkvem.home=%RUTAJ2ME% -classpath %CLASSPATH% com.sun.kvem.midp.
Main DefaultGrayPhone -descriptor Comunicacion.jad Como se ha mencionado anterio
rmente es necesario incluir un archivo denominado descriptor para se establece m
ediante la opción –descriptor, en nuestro caso es el archivo Comunicación.jad, c
on DefaultGrayPhone se indica el simulador a utilizar (el j2me wireless toolkit
proporciona varios con diferentes tamaños de pantalla), finalmente con –Dkvem.ho
me=<nombre> se establece la ruta para buscar las clases de la aplicación y sus r
ecursos.
35
El fichero descriptor del ejemplo es el siguiente:
MIDlet-1: Comunicacion, Comunicacion.png, Comunicacion MIDlet-Jar-Size: 4390 MID
let-Jar-URL: Comunicacion.jar MIDlet-Name: Comunicacion MIDlet-Vendor: Sun Micro
systems MIDlet-Version: 1.0
Finalmente se muestran los resultados de la ejecución.
36
GLOSARIO
CDLC: Acrónimo de Connected Device Limited Configuration, es una de las configur
ación existentes para J2ME. Configuración: Definición de la características comu
nes de una franja horizontal de dispositivos. Descriptor: Fichero con extensión
.JAD que contiene información sobre el MIDlet Suite. Este información es requeri
da por el gestor de instalación de aplicaciones para cerciorarse que es adecuado
para la instalación en dicho dispositivo. JAR: Extensión de los ficheros que em
paquetan un conjunto de MIDlets haciendo posible su distribución a través de la
red. Manifiesto: Fichero que describe el contenido de un fichero .JAR. MIDLET: A
plicación desarrollada en J2ME que implementa MIDP para dispositivos móviles. MI
DLET suite: Agrupación de MIDlets MIDP: acrónimo de Mobile Information Device Pr
ofile es uno de los perfiles existentes hoy en día. Perfil: Definición de un con
junto de APIs y características de la franja vertical del mercado RMS: Record Ma
nagement System , es una base de datos simple definida por J2ME MIDP
37
BIBLIOGRAFÍA
• • • • • • • [SAMS 2001] Yu Feng y Dr. Jun Zhu. “Wireless Java Programming with
J2ME”, Junio 2001. [SAMS] Michael Morrison. “Wirele ss Java with J2ME in 21 Day
s”, Junio 2001. Application for Mobile Information Device. [White Paper] J2ME Te
chnology for creating Mobile Devices. [White Paper] CLDC Specification. Version
1.0a J2ME Wireless Toolkit User’s Guide. Version 1.0 Mobile Information Device P
rofile (JSR-37). Draft 0.9
DIRECCIONES DE INTERÉS <http://www.java.sun.com> <http://java.sun.com/j2se/1.3/d
ownload-windows.html>. <http://www.cun.com/forte/ffj/buy.html> <http://www.codew
arrior.com/> <http://www.inprise.com/jbuilder/hhe/> <http://java.sun.com/ produc
ts/j2mewtoolkit/ download.html>
38

You might also like