Herramientas de programación JAVA de dispositivos móviles

32
Tutorial: Herramientas de programación JAVA de dispositivos móviles Versión: 1.0, Septiembre, 2006 Autor: Manuel Gómez Olmedo Web: http://decsai.ugr.es/~mgomez , Mail: [email protected] (C) Dpto. de CCIA Web: http://decsai.ugr.es Introducción En este tutorial se inicia al alumno en el uso de la herramienta KToolbar, una de las herramientas disponibles para la realización de aplicaciones para dispositivos móviles. En ella, una vez escrito el código fuente, puede crearse un proyecto que permite compilar y preparar el código para su ejecución en un emulador apropiado. De hecho, el producto final de esta herramienta puede ser instalado, de forma directa, en el dispositivo móvil en que vaya a emplearse. Así no tendremos que descargar nada, ni pagar.... Índice 1. Herramientas necesarias. Instalación 2. MIDlets y MIDlet suites 3. Ejecución de MIDlets 4. Uso de KToolbar Herramientas necesarias. Instalación Para poder compilar y ejecutar aplicaciones para dispositivos móviles necesitamos disponer de las siguientes herramientas:

Transcript of Herramientas de programación JAVA de dispositivos móviles

Page 1: Herramientas de programación JAVA de dispositivos móviles

Tutorial: Herramientas de

programación JAVA de dispositivos

móviles

Versión: 1.0, Septiembre, 2006

Autor: Manuel Gómez Olmedo Web: http://decsai.ugr.es/~mgomez, Mail: [email protected]

(C) Dpto. de CCIA Web: http://decsai.ugr.es

Introducción

En este tutorial se inicia al alumno en el uso de la herramienta KToolbar, una

de las herramientas disponibles para la realización de aplicaciones para

dispositivos móviles. En ella, una vez escrito el código fuente, puede crearse

un proyecto que permite compilar y preparar el código para su ejecución en un

emulador apropiado. De hecho, el producto final de esta herramienta puede

ser instalado, de forma directa, en el dispositivo móvil en que vaya a

emplearse. Así no tendremos que descargar nada, ni pagar....

Índice

1. Herramientas necesarias. Instalación

2. MIDlets y MIDlet suites

3. Ejecución de MIDlets

4. Uso de KToolbar

Herramientas necesarias. Instalación

Para poder compilar y ejecutar aplicaciones para dispositivos móviles

necesitamos disponer de las siguientes herramientas:

Page 2: Herramientas de programación JAVA de dispositivos móviles

Java 2 SDK, o bien cualquier otro entorno de desarrollo que ofrezca un

compilador en linea de comandos para JAVA. Se recomienda el uso del

SDK de JAVA, ya que los ejemplos vistos en clase se centrarán sobre

esta herramienta. Se puede descargar de la página de SUN, en la

siguiente dirección: http://java.sun.com/javase/downloads/index.jsp.

Nosotros trabajeremos en el aula de prácticas con la versión 5,

actualización 6, aunque ya hay disponibles versiones más recientes

(actualización 8, e incluso verión 6 en modo beta).

Java 2 Micro Edition. Se trata del paquete completo de desarrollo

necesario. Incluye la herramienta KToolbar, junto con el perfil MIDP.

Mediante la herramienta KToolbar se puede compilar código sin

necesidad de interactuar directamente con CLDC, al mismo tiempo que

se dispone de un emulador de terminal telefónico. De esta forma se

puede comprobar el funcionamiento de la aplicación sobre un teléfono

móvil. Se puede descargar en la

direcciónhttp://java.sun.com/javame/downloads/index.jsp. La versión

más reciente es la 2.5, aunque nosotros trabajaremos con la 2.2. Esta

versión puede descargarse

desde http://java.sun.com/products/sjwtoolkit/download-2_2.html.

CLDC 1.1. Esta herramienta sólo se necesita si se trabaja a bajo nivel,

por ejemplo, para incorporar código nativo (en lenguaje C) que se

quiera incorporar a la aplicación. Se trata de la versión más reciente de

CLDC. El software necesario se puede encontrar en la

dirección: http://www.sun.com/software/communitysource/j2me/cldc/d

ownload.xml. Para instalar convenientemente CLDC hemos de seguir

los siguientes pasos (para linux):

1. Una vez descargado el archivo j2me_cldc_1_1-fcs-src-

winunix.zip (se trata de los fuentes del CLDC, comunes para

windows, linux y otras plataformas), procederemos a

descomprimirlo. Supongamos que el directorio donde está

ubicado el zip es $HOME/java. Si aquí se descomprime el

archivo (mediante el comando unzipnombrearchivo ), se generará

el directorio j2me_cldc, donde se extraerán los archivos

integrados en el zip. Uno de los subdirectorios creados

bajo j2me_cldc es build. Bajo el directorio build se pueden

encontrar diversos directorios, relativos a las diferentes

plataformas para las que está disponible CLDC. Mirad si se

encuentra el directorio $HOME/java/j2me_cldc/bin/linux. En

Page 3: Herramientas de programación JAVA de dispositivos móviles

caso afirmativo, aquí termina el proceso de instalación. En caso

contrario es preciso continuar.

2. El siguiente paso a realizar consiste en situarnos en el directorio

asociado a la plataforma para la que se va a hacer la instalación.

En nuestro caso cambiaremos al directorio linux (dentro del

directorio build). El contenido de este directorio es un

archivo Makefile, que contiene las órdenes necesarias para

instalar la versión adecuada de CLDC. Basta ejecutar, en dicho

directorio, el comando make.

3. Así se genera la máquina virtual, en el

directorio $HOME/java/j2me_cldc/bin/linux. La máquina

virtual se denomina kvm.

Netbeans. Se trata de un entorno completo de desarrollo de

aplicaciones JAVA, con módulos especiales para aplicaciones sobre

dispositivos móviles. Dicha herramienta se puede descargar de la

dirección: htpp://www.netbeans.org. Nosotros usaremos la versión 5,

aunque hay disponibles versiones beta más recientes.

MIDlets y MIDlet suites

Las aplicaciones JAVA que se ejecutan en dispositivos que implementan

MIDP se denominan MIDlets. Un MIDlet consta de al menos una clase

JAVA, que debe derivar de la clase base

abstracta javax.microedition.midlet.MIDlet. El tiempo de ejecución de un

MIDlet viene controlado por una serie de métodos definidos en dicha clase y

que, forzosamente, todas las clases derivadas deben implementar.

Un grupo de MIDlets relacionados pueden agruparse en un MIDlet suite.

Todos los MIDlets de un suite se agrupan e instalan en un dispositivo como si

fuesen un único elemento, de forma que sólo pueden desinstalarse y

eliminarse en conjunto. Los MIDlets agrupados en un suite comparten tanto

recursos estáticos como dinámicos:

Page 4: Herramientas de programación JAVA de dispositivos móviles

En tiempo de ejecución, si los dispositivos soportan ejecución

concurrente, todos los MIDlets se ejecutarán en la misma máquina

virtual. Por tanto, todos los MIDlets comparten las mismas instancias

de todas las clases, así como los recursos cargados en la máquina

virtual. Entre otras cosas, esto supone que se pueden compartir datos

entre MIDlets y que las primitivas de sincronización no sólo deben

usarse para proteger frente al acceso concurrente dentro de cada

MIDlet, sino también el producido por otros MIDlets asociados al

mismo suite.

El almacenamiento persistente es gestionado de forma globar para

todos los MIDlets del suite. Por tanto, los MIDlets pueden acceder

tanto a sus propios datos persistente como a los de otras clases del

MIDlet.

Como ejemplo de la forma en que los MIDlets de un suite comparten

recursos, supongamos un suite que contiene una clase denominada Contador,

destinada a mantener la cuenta del número de instancias de MIDlets

del suite que se ejecutan en cada momento.

public class Contador {

// Contador del numero de instancias

private static int instancias;

public static synchronized void incrementar(){

instancias++;

}

public static synchronized void decrementar(){

instancias--;

}

public static int obtener(){

return instancias;

}

}

Una única instancia de esta clase se cargará en la máquina virtual, sin importar

cuántos MIDlets de los que integren el suite están en ejecución en la máquina

virtual. Esto significa que el mismo dato miembro estático instancias será

usado por todos los MIDlets, por lo que los

métodos incrementar y decrementar afectarán al mismo contador. En este

caso es necesaria la sincronización para asegurar que las operaciones de

incremento y decremento sean realmente atómicas.

Es importante indicar que los MIDlets deben empaquetarse antes de poderse

instalar en los dispositivos de destino. Todo lo necesario de un suite debe

empaquetarse en un archivo JAR. La información del paquete debe incluirse

Page 5: Herramientas de programación JAVA de dispositivos móviles

en un archivo de manifiesto. Esta información también estará especificada en

otro archivo denominado descriptor de aplicaciones JAVA (JAD: java

application descriptor), que se mantiene separado del archivo JAR.

Los archivos de manifiesto y JAD son archivos de texto con la siguiente

estructura:

nombre_atributo: valor_atributo

El nombre del atributo y su valor están separados por dos puntos, siendo el

espacio adicional opcional. Todos los atributos que son relevantes para la

instalación de MIDlets comienzan por el prefijo "MIDlet-". Una lista

completa de atributos, junto con una breve descripción de sus valores

asociados, aparece en la tabla siguiente. Los valores en las columnas JAD y

JAR indican que el atributo es obligatorio (M), opcional (O) o ignorado (I).

Nombre de

atributo

JAR JAD Valor y significado

MIDlet-Name M M El nombre del suite integrado en el archivo

JAR. El usuario podrá ver este nombre

MIDlet-

Version

M M El número de versión del suite empaquetado

en el archivo JAR. Los número de versión

tienen la forma a.b.c, donde valores

mayores indican versiones más recientes, teniendo los números de la izquierda mayor

precedencia

MIDlet-

Vendor

M M El nombre del fabricante del suite. Se trata

de texto libre.

MIDlet-n M I Atributo que describe cada uno de los

MIDlets que integran el suite. El valor

numérico n comienza en 1 y sirve para

identidicar cada uno de los MIDlets

MIDlet-Description

O O Una descripción del suite, para servir de información a los usuarios

MIDlet-Icon O O Un icono que representa al suite durante la

instalación o configuración. Se debe tratar

de una imagen en formato png (Portable Network Graphics)

MIDlet-Info-

URL

O O Dirección URL de un archivo que contiene

información adicional sobre el suite. El

contenido del archivo se mostrará al usuario, de forma que éste pueda decidir si desea o

no instalar dicho suite.

Page 6: Herramientas de programación JAVA de dispositivos móviles

MIDlet-Data-

Size

O O Mínima cantidad de espacio de

almacenamiento persistente para que el

suite funcione de forma correcta. Se trata de espacio usado por el suite para almacenar

datos de larga duración. Se espcifica en

bytes. Si no se proporciona este atributo, se

asume que el suite no precisa almacenamiento persistente

MIDlet-Jar-

URL

I M La dirección URL del archivo JAR que

contiene el suite

MIDlet-Jar-

Size

I M El tamaño del JAR que contiene el suite, en

bytes

MIDlet-

Install-Notify

I O Una dirección URL usada para indicar

condiciones de error o de éxito en la

instalación del suite. Se trata de un atributo

no incluido en la especificación MIDP, pero soportado por J2ME.

MIDlet-

Delete-

Confirm

I O Mensaje a mostrar en caso de que el suite

vaya a ser borrado del dispositivo. Con este

atributo ocurre lo mismo que se indicó respecto al anterior: se trata de un atributo

no incluido en la especificación de MIDP

MIDlet-

specific attributes

O O Los desarrollados de MIDlets pueden

proporcionar atributos específicos

MicroEdition-

Profile

M I La versión de especificación MIDP con la que

el suite puede trabajar. Cuando aparecen

varias versiones deben separarse mediante

espacios. Las versiones especificadas en este atributo se comparan con el valor de la

propiedad microedition.profiles para

determinar la compatibilidad del suite con la

versión de MIDP disponible

MicroEdition-

Configuration

M I La configuración J2ME precisada por el suite.

El valor de este atributo se compara con la

propiedad microedition.configurationpara

determinar la compatibilidad

Se aprecia que alguna información aparece duplicada en el archivo de

manifiesto del JAR y en el archivo JAD. Veremos por qué esto es necesario.

La función del archivo de manifiesto es indicar al dispositivo el nombre y

versión del suite almacenado en el JAR, así como indicar cuáles de los

archivos empaquetados se corresponden con cada uno de los MIDlets. Para

usar esta información el dispositivo debe descargar el JAR y extraer el archivo

Page 7: Herramientas de programación JAVA de dispositivos móviles

de manifiesto. Una vez hecho esto, se pueden mostrar los valores de los

atributos MIDlet-Name, MIDlet-Version, MIDlet-Vendor. También de los

atributos opcionales MIDlet-Description y MIDlet-Icon. Estos atributos

permiten al usuario decidir sobre la descarga. No obstante, el archivo JAR

podría ser muy grande, por lo que llevaría mucho tiempo recuperarlo en

situaciones de conexiones lentas, por ejemplo. Para evitar este problema,

algunos de los atributos del manifiesto, con información extra, se duplica en el

archivo JAD. Esto permite descargar inicialmente el archivo JAD en lugar del

JAR. De esta forma, se puede mostrar al usuario la información del suite antes

de haber descargado el archivo de sus clases. El archivo JAD contendrá

información contenida en el manifiesto y alguna particular. Típicamente, los

atributos que aparecen en él son:

MIDlet-Name

MIDlet-Vendor

MIDlet-Version

MIDlet-Description

MIDlet-Icon

MIDlet-Info-URL

MIDlet-Data-Size

MIDlet-Jar-Size

MIDlet-Jar-URL

El objetivo de estos atributos, como se indicó con anterioridad, es ofrecer

información sobre los MIDlets incluidos en el suite. Supongamos que

desarrollamos un suite denominado Notas que permiten al usuario acceso

directo a sus notas desde un dispositivo móvil. El suite contiene dos MIDlets:

uno para ver las notas y otro para enviar información sobre posibles errores en

ellas. Para desarrollar la clase se han usado métodos de utilidad,

pertenecientes a la clase Utilidades. En definitiva, las clases involucradas

serían las siguientes (teniendo en cuenta que forman parte del

paquete desarrollo.moviles):

desarrollo.moviles.VerNotas

desarrollo.moviles.ErrorNotas

desarrollo.moviles.Utilidades

El manifiesto para este suite podría ser el siguiente:

MIDlet-Name: Notas

MIDlet-Vendor: Programas Pepe

MIDlet-Version: 1.0.1

MIDlet-Description: Conjunto de midlets para ver notas

MIDlet-Icon: /desarrollo/moviles/iconos/notas.png

MIDlet-Info-URL: http://www.programaspepe.com/notas/info.html

MIDlet-Data-Size: 512

MicroEdition-Profile: MIDP-1.0

MicroEdition-Configuration: CLDC

MIDlet-1:

Visualizador,/desarrollo/moviles/iconos/ver.png,desarrollo.moviles.Ver

Notas

Page 8: Herramientas de programación JAVA de dispositivos móviles

MIDlet-2:

Errores,/desarrollo/moviles/iconos/error.png,desarrollo.moviles.ErrorN

otas

En el archivo JAR correspondiente, el archivo de manifiesto aparecería como

META.INF/MANIFEST.mf. El archivo JAR también contendría los

siguientes archivos:

/desarrollo/moviles/VerNotas.class

/desarrollo/moviles/ErrorNotas.class

/desarrollo/moviles/Utilidades.class

/desarrollo/moviles/iconos/notas.png

/desarrollo/moviles/iconos/ver.png

/desarrollo/moviles/icones/error.png

Conviene hacer algunos comentarios en relación al valor de los atributos y al

contenido del archivo JAR:

El archivo JAR contiene las clases correspodientes a ambos MIDlets.

Aunque la clase de utilidades se incluye no hay ninguna referencia a

ella en el manifiesto.

El atributo MIDlet-Icon contiene la ruta absoluta del archivo que

contiene el icono del suite.

Asociado a cada MIDlet hay un atributo que describe su nombre y le

asocia un identificador. El valor del atributo incluye nombre, icono y

clase asociada.

El archivo JAD asociado a este MIDlet contendrá la siguiente información:

MIDlet-Name: Notas

MIDlet-Vendor: Programas Pepe

MIDlet-Version: 1.0.1

MIDlet-Description: Conjunto de midlets para ver notas

MIDlet-Info-URL: http://www.programaspepe.com/notas/info.html

MIDlet-Data-Size: 512

MicroEdition-Jar-Size: 10132

MIDlet-Jar-URL: http://www.programaspepe.com/notas/Notas.jar

Este archivo contiene la información que la pantalla del dispositivo mostrará

al usuario, junto con la dirección URL del archivo JAR. En este caso, los

atributos comunes tienen el mismo valor tanto en el archivo de manifiesto

como en el archivo JAD. Para que el suite sea portable, es preciso que el

archivo JAR esté codificado usando la codificación iso-8859-1, ya que se

precisa que todas las implementaciones de MIDP soporten esta codificación.

En tiempo de ejecución los MIDlets pueden acceder a los archivos del JAR

asociado al suite y obtener información sobre los valores de los atributos.

Page 9: Herramientas de programación JAVA de dispositivos móviles

Ejecución de MIDlets

Simplemente, como comentario inicial, aunque se comentará más tarde, los

MIDlets deben derivar de la clase

abstractajavax.microedition.midlet.MIDlet, que contiene métodos

destinados a controlar el tiempo de ejecución de los MIDlets. Todos los

MIDlets deben tener un constructor público predeterminado (es decir, que no

requiera argumentos). La estructura básica de un MIDlet se muestra a

continuación:

public class EjemploMidlet extends MIDlet{

// Constructor: opcional. Bastaría con el constructor por

// defecto

public EjemploMidlet(){

}

// Método que iniciará la ejecución del MIDlet

public void startApp() throws MIDletStateChangeException{

}

// Método que interrumpe la ejecución del MIDlet

public void pauseApp(){

}

// Método para finalización del MIDlet

public void destroyApp(boolean unconditional)

throws MIDletStateChangeException{

}

}

En todo momento, los posibles estados en que podría estar un MIDlet son:

pausa

activo

destruido

Inicialmente, cuando se produce la carga de un MIDlet, éste estará en

estado pausa. Cuando se produce la llamada al métodostartApp() se produce

el paso al estado activo. En cualquier instante, la plataforma MIDP podría

poner a un MIDlet en estado de pausa. Por ejemplo, en los teléfonos móviles

esto ocurrirá cuando se detecta una llamada entrante. Esto se realiza mediante

una llamada al método pauseApp(). La vuelta al estado activo precisa de una

nueva llamada a startApp(). Cuando se precisa la finalización de un MIDlet

se usará una llamada a destroyApp(...). Al producirse esta llamada se liberan

los recursos que el MIDlet pudiera estar usando, siempre que el argumento de

este método sea true. Pero pudiera haber algunas situaciones en que este tipo

de finalización no es conveniente; por ejemplo, por haber datos que aún no se

Page 10: Herramientas de programación JAVA de dispositivos móviles

han almacenado. En este caso, la llamada al método debería hacerse usando

como argumento false. Esto produce el lanzamiento de la excepción

MIDletStateChangeException. El código debería estar preparado para capturar

la excepción y actuar en consecuencia.

Para ilustrar el ciclo de vida un MIDlet y la forma en que se controla, a la vez

que mostrar el funcionamiento de las herramientas de generación de MIDlets,

vamos a considerar un ejemplo sencillo de MIDlet, caracterizado por:

El MIDlet se llamará EjemploMIDlet1. El constructor imprime el

valor de la propiedad color (ya veremos para qué se hace esto) y

muestra un mensaje indicando que el midlet está construido y el valor

de la propiedad.

El método startApp() se encarga de mostrar un mensaje que permita

trazar el ciclo de vida del MIDlet. A continuación se hace lo siguiente:

o Si es la primera vez que se llama al método startApp(), entonces

se crea un objeto auxiliar de la clase Tarea, que permite, en una

hebra aparte, ejecutar una simple cuenta. Después de crear este

objeto se invoca al método start()del mismo, de forma que

empieze a desarrollarse la tarea indicada en el método run() de

la misma. Finalmente se cambiará el valor de la variable

booleana, de forma que la próxima vez que se llame al

método startApp() se sepa que se trata de una llamada

producida al salir de una pausa.

o Si no es la primera vez que se llama al método startApp(),

entonces se prosigue con la ejecución de la tarea realizada por la

hebra, desde el punto en que se quedara parada previamente

como consecuencia de la pausa. Cuando la tarea se finaliza, se

fuerza la destrucción del MIDlet, mediante la llamada

a destroyApp(true). El argumento true pasado

a destroyApp indica que se busca liberar todos los recursos que

el MIDlet pudiera estar usando.

El método pauseApp() se invoca al producirse una llamada telefónica,

por ejemplo. Para forzar este evento hay una opción concreta del menú

MIDlet de KToolbar. Al recibirse la llamada a este método, se muestra

un mensaje para seguir la traza de funcionamiento. Se imprime el

Page 11: Herramientas de programación JAVA de dispositivos móviles

estado de trabajo de la tarea auxiliar (de la cuenta) y se fuerza a que la

hebra deje de trabajar. Este es el objetivo de la

llamada tarea.interrumpir().

Como no se sabe aún lo suficiente como para construir interfaces de usuario

(aunque pronto se sabrá), todos los mensajes se enviarán a la salida estándar.

Se incluye a continuación el código correspondiente, y seguidamente se verá

cómo generar el suite, tanto de forma manual como automática.

import javax.microedition.midlet.MIDlet;

import javax.microedition.midlet.MIDletStateChangeException;

public class EjemploMIDlet1 extends MIDlet{

Tarea tarea;

boolean primeraVez;

// Constructor por defecto de la clase

public EjemploMIDlet1(){

String color=getAppProperty("color");

System.out.println("\n\n\nConstruido MIDlet con color: "+color);

primeraVez=true;

}

// Metodo para iniciar el funcionamiento del MIDlet

public void startApp() throws MIDletStateChangeException{

System.out.println("Metodo startApp");

if (primeraVez == true){

System.out.println("Ejecucion la primera vez.......");

System.out.println("Se inicia cuenta larga para

permitir pausar");

tarea=new Tarea();

tarea.start();

primeraVez=false;

}

else{

// Se reanuda la ejecucion tras salir de la pausa

System.out.println("Llamada tras pausa..... Valor de i:

"+tarea.getI());

tarea.continuar();

// Se destruye el midlet cuando la tarea termine

if (tarea.getFinalizado() == true){

destroyApp(true);

}

}

}

// Metodo para detener el funcionamiento del MIDlet

public void pauseApp(){

System.out.println("Metodo pauseApp");

System.out.println("Valor de i en el momento de la pausa:

"+tarea.getI());

tarea.interrumpir();

}

// Metodo para destruir el MIDlet

Page 12: Herramientas de programación JAVA de dispositivos móviles

public void destroyApp(boolean condition){

System.out.println("Metodo destroyApp. Condicion: "+condition);

if (condition == true){

// Se indica la finalizacion del midlet

notifyDestroyed();

}

}

}

class Tarea extends Thread{

int i;

boolean interrumpido;

boolean finalizado;

Tarea(){

i=0;

interrumpido=false;

finalizado=false;

}

public void run(){

for(; i < 9000000; ){

if (interrumpido == false){

i++;

}

else{

try{

sleep(100);

}

catch(InterruptedException e){

System.out.println("Problema al dormir hebra....");

}

}

//System.out.println("Valor de i: "+i);

}

// Se finaliza la tarea

finalizado=true;

}

// Metodo para obtener el valor de i

int getI(){

return i;

}

// Metodo para interrumpir

void interrumpir(){

interrumpido=true;

}

// Metodo para continuar

void continuar(){

interrumpido=false;

}

// Metodo para acceder al valor de finalizado

boolean getFinalizado(){

return finalizado;

}

}

Page 13: Herramientas de programación JAVA de dispositivos móviles

El código completo de este MIDlet puede descargarse directamente desde

aquí: EjemploMIDlet1.java Se trata de un MIDlet muy sencillo, que permitirá

practicar con los procedimientos de generación de MIDlets, así como los

posibles estados en que puede encontrarse un MIDlet en ejecución: pausa,

activo y destruido.

Uso de KToolbar

Seguiremos el proceso completo de trabajo sobre el MIDlet incluido

anteriormente. El primer paso consistirá en ejecutar la herramienta KToolbar.

Esta aplicación se encuentra en la instalación de Wireless Toolkit. Para

ejecutarla haremos lo siguiente (si no funciona, avisad al profesor.......).

ktoolbar

La ventana principal de KToolbar tiene la siguiente aparencia:

Crearemos un proyecto de suite, en el que incluiremos el MIDlet generado

con anterioridad. Para ello se pulsa en el botón New Project. Al pulsar sobre

él aparecerá la siguiente ventana:

Como se ve, hemos rellenado la información de ambos campos de texto.

Como nombre del proyecto podemos elegir cualquiera, sin necesidad de

coincidir con el nombre de la clase principal del MIDlet. En el segundo campo

Page 14: Herramientas de programación JAVA de dispositivos móviles

de texto hemos de especificar el nombre de la clase principal del suite que

queremos ejecutar en el emulador. En este caso es EjemploMIDlet1. En

cuanto se pulsa el botón Create Project aparecerá una nueva ventana donde

aparecen informaciones relativas al MIDlet.

Al mismo tiempo, en la ventana principal de KToolbar han aparecido varios

mensajes:

Page 15: Herramientas de programación JAVA de dispositivos móviles

Estos mensajes indican que se ha creado la estructura de directorios necesaria

para el proyecto, y que las clases que queramos formen parte del MIDleet

habrá que ubicarlas en el directorio src; recursos adicionales (como iconos)

irán en el directorio res y las librerías (si las hubiera) en el directorio lib.

Como se ve, el directorio del proyecto se crea en el directorio de instalación

de la herramienta, bajo el subdirectorio apps. En nuestro caso, la ruta

completa será $HOME/java/WTK2.2/apps/ejemplo1. Nuestro primer

MIDlet usará un icono muy sencillo (descargadlo aquí: iconoPeq.png).

Por tanto, lo primero que haremos será copiar el archivo con la clase asociada

al MIDlet en el directorio$HOME/java/WTK2.2/apps/ejemplo1/src/. El

icono se ubicará en el directorio $HOME/java/WTK2.2/apps/ejemplo1/res/.

Dentro de este directorio crearemos a su vez el directorio icons. Y en él será

donde se guarde el archivo png del icono. Para indicar que el icono del

MIDlet es este, debe modificarse la información sobre el icono. Para ello se

pulsa el botón Settings deKToolbar. Aparecerá la venta siguiente:

Page 16: Herramientas de programación JAVA de dispositivos móviles

Aprovechamos ahora para indicar que deseamos que el MIDlet sea conforme

a MIDP1.0. Para ello se selecciona esta opción de las disponibles al pulsar

sobre Target Platform. Para indicar el icono asociado, se selecciona la

pestaña MIDlets. Una vez hecho esto aparecerá

Page 17: Herramientas de programación JAVA de dispositivos móviles

Para poder cambiar el icono (el valor presente en la figura anterior se

introduce por defecto), basta con seleccionar la línea con los datos (la fila que

aparece rellena), con lo que se marcará con un color diferente para indicarnos

que está seleccionada:

Page 18: Herramientas de programación JAVA de dispositivos móviles

Ahora basta con pulsar sobre el botón Edit, lo que dará lugar a la aparición de

la ventana de edición:

Sobre esta ventana, en el recuadro Icon escribiremos /icons/iconoPeq.png, tal

y como se aprecia a continuación:

Page 19: Herramientas de programación JAVA de dispositivos móviles

Al finalizar se pulsa sobre el botón Aceptar de la ventana de edición. Con

esto queda registrado el cambio de la propiedad correspondiente al icono del

MIDlet:

Y pulsando sobre el botón OK desaparece la ventana de propiedades. Esto es

todo lo necesario para poder generar y ejecutar el MIDlet. En primer lugar,

procedemos a generar las clases a partir del código fuente. Para ello se pulsa

el botón Build. Si todo ha ido bien, aparecerá un mensaje indicado que la

Page 20: Herramientas de programación JAVA de dispositivos móviles

generación se realizó de forma correcta. En caso de haber errores, se

mostrarán en la ventana principal de KToolbar.

En cuanto se ha generado el MIDlet, podemos ejecutar mediante el

botón Run. Al pulsarlo, aparecerá el emulador con el MIDlet listo para

ejecución.

Page 21: Herramientas de programación JAVA de dispositivos móviles

Para lanzar la ejecución del MIDlet se pulsa sobre la tecla bajo el

mensaje Launch. En cuanto se produce esto el MIDlet se crea y el dispositivo

invoca al método startApp(). Esto explica los mensajes que se aprecian en la

consola de KToolbar:

Page 22: Herramientas de programación JAVA de dispositivos móviles

Se muestra el mensaje de traza puesto en el constructor, indicando que la

propiedad color no está definida. Arreglar esto se deja para más adelante.

También se aprecia la traza ubicada a la entrada del método startApp(), que

ha sido invocado por el sistema de gestión de ejecución de MIDlets del

dispositivo móvil. Los dos mensajes que aparecen a continuación son trazas

que muestran que el MIDlet se ejecuta por primera vez.

Para pausar el MIDlet, tras unos segundos de funcionamiento, basta con

actuar sobre el menú MIDlet del emulador telefónico y seleccionar la

opción Pause. Al hacerlo el emulador queda de la forma siguiente:

Page 23: Herramientas de programación JAVA de dispositivos móviles

A su vez, en la consola de KToolbar veremos los siguientes mensajes:

Page 24: Herramientas de programación JAVA de dispositivos móviles

Las nuevas líneas de traza indican que se ha invocado al método pauseApp().

Como comentamos previamente, esto ocurrirá al producirse una llamada de

teléfono sobre el móvil, por ejemplo. Se observa el valor de la cuenta en el

momento en que se produjo la pausa. Para continuar ejecutando el MIDlet (lo

que ocurriría al finalizar la llamada), forzamos la salida del modo de pausa.

Para ello volvemos a actuar sobre el menú MIDlet, seleccionado la

opción Resume. Esto hace que aparezcan nuevas líneas de traza indicando

que se ha producido una nueva llamada al método startApp(), pero sin

tratarse de la primera llamada al mismo.

Page 25: Herramientas de programación JAVA de dispositivos móviles

Por su parte, del emulador desaparece la indicación de llamada entrante:

Page 26: Herramientas de programación JAVA de dispositivos móviles

Si se observa el código del método startApp(), se aprecia que la destrucción

del MIDlet sólo se producirá en el caso en que ya haya finalizado la tarea de

cuenta. Para asegurarnos que esto ocurre, tras la salida del modo de pausa

esperaremos unos segundos, se genera una nueva pausa (pulsando, como se

indicón previamente, sobre la opción Pause del menú MIDlet) para, a

continuación forzar, mediante Resume (en el menú MIDlet), una nueva

llamada a startApp() una vez finalizada la cuenta. Cuando esto ocurra,

tendremos:

Page 27: Herramientas de programación JAVA de dispositivos móviles

Sólo cuando el MIDlet haya sido destruido de forma completa podrá volver a

lanzarse de forma correcta.

EJERCICIO 1: probad qué ocurre cuando se intenta lanzar de nuevo la

ejecución del MIDlet antes de que haya finalizado completamente la tarea de

cuenta. Justificad el comportamiento observado.

Cuando se usa destroyApp(false) permite que el método compruebe si se

cumplen las condiciones necesarias para finalizar o no. En caso de no

cumplirse, puede generar una excepción del

tipo MIDletStateChangeException, lo que genera a su vez una nueva

llamada startApp().

EJERCICIO 2: se propone que modifiquéis el código del MIDlet anterior de

la forma siguiente:

Montad un nuevo proyecto, ejemplo2, para trabajar sobre esta variante.

La clase del MIDlet se denominará EjemploMIDlet2. Podéis partir de

la clase EjemploMIDlet1 y modificarla.

En el método startApp(), en caso de no ser la primera llamada, después

de la sentencia tarea.continuar(), se realiza la llamada

Page 28: Herramientas de programación JAVA de dispositivos móviles

a destroyApp(false). Esta llamada habrá que encerrarla en un

bloque try-catch, ya que el método destroyApp()podría decidir

generar la excepción si considera que el MIDlet no debe finalizar.

Modificad el método destroyApp(), de forma que en caso de recibir

como argumento false, compruebe si la tarea ha finalizado o no. Si no

ha finalizado, lanza una excepción del

tipo MIDletStateChangeException, para dar tiempo a que la tarea de

conteo finalice. Si la tarea ha finalizado, se llama al

método notifyDestroyed(), con lo que el MIDlet indica que desea

finalizar.

En nuestro caso, el MIDlet usa un valor de atributo (color). Si se observa el

código, se comprobará que al imprimir su valor se muestra null. Si se intenta

manejar esta propiedad, sin haberla especificado de forma explícita, puede

ocurrir un error como el mostrado a continuación:

Pero, ¿cómo se define este atributo?. Para ello usaremos el botón Settings.

Cuando aparezca la ventana de propiedades del MIDlet, seleccionaremos la

Page 29: Herramientas de programación JAVA de dispositivos móviles

opción User Defined, que permitirá definir atributos propios. Sobre esta

ventana, pulsaremos el botón Add.

Al pulsar sobre Add aparecerá la ventana que hemos de usar para definir el

valor de la propiedad deseada:

Se escribe el nombre de la propiedad (color) y se pulsa sobre Aceptar. Con

esto la ventana de propiedades queda de la siguiente forma:

Page 30: Herramientas de programación JAVA de dispositivos móviles

Se pincha sobre el campo de texto en blanco y se introduce el valor deseado:

Page 31: Herramientas de programación JAVA de dispositivos móviles

Pulsamos OK y ya podemos volver a ejecutar el MIDlet. Ahora la traza inicial

indica:

Page 32: Herramientas de programación JAVA de dispositivos móviles

EJERCICIO 3: probad con los MIDlets de demo que vienen con la

herramienta. Activad la monitorización, activando las preferencias (Edit +

Preferences + Monitor) deseadas. Con esto podéis haceros una idea de la

capacidad de la plataforma de desarrollo. Haced un pequeño guión con

indicaciones sobre vuestra opinión al respecto: demos más interesantes,

limitaciones, puntos fuertes, etc.