Download Manual de desarrollo de aplicaciones en J2ME
Document related concepts
no text concepts found
Transcript
0DQXDOGHGHVDUUROORGH DSOLFDFLRQHVHQ-0( 9HUVLyQGHOGRFXPHQWR )HFKDGHOGRFXPHQWRGH0DU]RGH ËQGLFH Ë1',&( ,1752'8&&,Ï1 5()(5(1&,$6 ,QVWDODFLyQHLQLFLRGH:LUHOHVV7RRONLW &UHDUQXHYRSUR\HFWR 'HVDUUROORGHOSURJUDPD &RPSLODFLyQ\GHSXUDFLyQ $1(;26 3.1. ANEXO A: EJEMPLOS DE APLICACIONES J2ME............................................................................. 6 (MHPSOR9LVRUGHLPiJHQHV (MHPSOR$ODUPD (MHPSOR7LPHU 2 ,QWURGXFFLyQ Los pasos a seguir para crear una aplicación Java para nuestro terminal Javaenabled. Lo primero de todo será conseguir e instalar los entornos de desarrollo necesarios para empezar a desarrollar: - J2SDK 1.3 (o superior) Proporciona la base sobre la que se instalan el resto de aplicaciones. - J2ME Wireless Toolkit 1.0.1 (o superior) Ofrece un entorno de compilación, depuración y ejecución para la creación de MIDlets bajo la plataforma J2ME. Una vez instalados todos estos componentes comenzaremos el proceso de desarrollo. Para ello se seguirán los siguientes pasos: ,QVWDODFLyQHLQLFLRGH:LUHOHVV7RRONLW 1RWD Durante la instalación de este programa se preguntará al usuario entre dos tipos de instalación: “Integrated” y “Stand Alone”. - La primera permitirá a aquellos usuarios de Forte for Java crear aplicaciones (MIDlets) desde dicho entorno, para lo cual deberá estar instalado ya el programa. - La segunda opción no incluye esta posibilidad y será el usuario el que edite el código fuente con el programa que desee. Una vez instalado correctamente este software de desarrollo se instalará en nuestro menú ,QLFLR un acceso directo al programa. Para iniciarlo nos bastará con ejecutar el icono N7RROEDU que ejecutará el programa principal del :LUHOHVV7RRONLW. 1RWD En algunos sistemas operativos como Windows NT o Windows 2000 puede que no se cree este acceso al programa. En este caso bastará con ejecutar el fichero NWRROEDUEDW del directorio ELQ de la aplicación. 3 &UHDUQXHYRSUR\HFWR Para iniciar el desarrollo de un nuevo proyecto pulsaremos el botón “New Project” de la pantalla principal de la aplicación. Durante la creación de un nuevo proyecto deberemos incluir el nombre del proyecto y de la clase principal. Además aparecerá una pantalla de preferencias donde se deberán configurar opciones del MIDlet 4 Como resultado de la creación del nuevo proyecto se crearán una serie de directorios a partir del directorio MPHZWDSSV que son: ELQ: Contiene los ficheros resultantes de la compilación y verificación del código. UHV: Contiene los recursos que se van a utilizar, por ejemplo, imágenes, ficheros de datos, etc… VUF: Contiene el código fuente de las clases que componen la aplicación. Todos los ficheros *.java deben encontrarse en este directorio. FODVVHV \ WPSFODVVHV: Directorios secundarios con clases temporales de la aplicación. 'HVDUUROORGHOSURJUDPD La aplicación se podrá desarrollar con cualquier editor de textos, la única limitación es que los ficheros residan en los directorios antes mencionados. Para crear una aplicación el programador deberá ceñirse al API ofrecido por el entorno MIDP de J2ME. (Debido a la extensión de este API se recomienda consultar la versión HTML del mismo para más información). &RPSLODFLyQ\GHSXUDFLyQ La fase de compilación se deberá efectuar bajo el entorno del :LUHOHVV7RRONLW. Este entorno ofrece una serie de posibilidades de depuración y emulación que dependen de la versión instalada. Una vez creados los ficheros fuentes y colocados en el directorio VUF anteriormente comentado se pulsará el botón %XLOG de la pantalla principal. En ese momento se realiza la compilación, preverificación de clases y empaquetamiento de todos los recursos (clases, imágenes, datos, etc..) necesarios para la ejecución. Los ficheros resultantes son dos: fichero.jar y fichero.jad. El primero es propiamente el fichero que contiene la aplicación en sí. El segundo contiene la definición de los datos existentes en el anterior fichero. 5HIHUHQFLDV En los siguientes links encontrará numerosa información sobre J2ME: x http://wireless.java.sun.com 5 x x x x http://www.java.sun.com http://www.corej2me.com http://www.cswl.com http://www.billday.com $QH[RV $QH[R$(MHPSORVGHDSOLFDFLRQHV-0( Las siguientes aplicaciones son un ejemplo de las facilidades que permite Java para dispositivos móviles: (MHPSOR9LVRUGHLPiJHQHV La siguiente aplicación consiste en un visor de imágenes en formato PNG. Estas imágenes las obtiene de la URL que le especifiquemos, haciendo una conexión y descargando la imagen para visualizarla. El código fuente de esta aplicación es el siguiente: import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import javax.microedition.io.*; import java.io.*; /*-------------------------------------------------* Main class definition *-------------------------------------------------*/ public class pngViewer extends MIDlet implements CommandListener { private Display display; private TextBox tbxMain; private Form frmViewPng; private Command cmdExit; private Command cmdView; private Command cmdBack; /*-------------------------------------------------* Constructor for the class. *-------------------------------------------------*/ public pngViewer() 6 { display = Display.getDisplay(this); // Create the Main textbox with a maximum of 50 characters tbxMain = new TextBox("Enter png "http://www.corej2me.com/scratch/spin.png", 50, 0); url", // Create commands and add to textbox cmdView = new Command("View", Command.SCREEN, 1); cmdExit = new Command("Exit", Command.SCREEN, 1); tbxMain.addCommand(cmdView ); tbxMain.addCommand(cmdExit); // Set up a listener to "capture" button presses tbxMain.setCommandListener(this); // --------------------------------------// Create the form that will hold the png image frmViewPng = new Form("Png Image"); // Create commands and add to form cmdBack = new Command("Back", Command.BACK, 1); frmViewPng.addCommand(cmdBack); // Set up a listener to "capture" button presses frmViewPng.setCommandListener(this); } /*-------------------------------------------------* Called by the Application Manager on the device * to start the MIDlet. *-------------------------------------------------*/ public void startApp() { // Display the Main textbox display.setCurrent(tbxMain); } /*-------------------------------------------------* A required method. * Does nothing in this MIDlet *-------------------------------------------------*/ public void pauseApp() { } /*-------------------------------------------------* A required method. * Does nothing in this MIDlet 7 *-------------------------------------------------*/ public void destroyApp(boolean unconditional) { } /*-------------------------------------------------* Process events *-------------------------------------------------*/ public void commandAction(Command c, Displayable s) { // If the Command button pressed was "Exit" if (c == cmdExit) { destroyApp(false); notifyDestroyed(); } else if (c == cmdView) { // If the Command button pressed was "View" // Remove anything that may be on the form if (frmViewPng.size() > 0) for (int i = 0; i < frmViewPng.size(); i++) frmViewPng.delete(i); // Get the image from the web and append to the form Image img; if ((img = getImage(tbxMain.getString())) != null) frmViewPng.append(img); // Display the form with the image display.setCurrent(frmViewPng); } else if (c == cmdBack) { // If the Command button pressed was "Back" display.setCurrent(tbxMain); } } /*-------------------------------------------------* Open an http connection and download a png file * into a byte array. *-------------------------------------------------*/ private Image getImage(String imageStr) { try { HttpConnection conn = (HttpConnection) Connector.open(imageStr); // Check to see if we successfully opened the connection int response = conn.getResponseCode(); 8 if(conn.getResponseCode() == HttpConnection.HTTP_OK ) { int length = (int) conn.getLength(); if (length > 0) { byte imageData[] = new byte[length]; InputStream in = conn.openInputStream(); // Read the png into an array in.read(imageData); // Create the image from the byte array return Image.createImage(imageData, 0, length); } } else { frmViewPng.append("Error getting png"); } } catch (IOException e) { frmViewPng.append("IO Error"); } return null; } } De la ejecución de esta aplicación se obtiene una serie de pantallas como estas: 9 (MHPSOR$ODUPD Esta aplicación consiste en una simple alarma programable que emite un pitido al llegar la hora fijada. El código fuente de esta aplicación es el siguiente: import java.util.*; import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import java.util.Timer; import java.util.TimerTask; public class alarm extends MIDlet implements ItemStateListener, CommandListener { private Display display; // Reference to display object private Form frmMain; // The main form private Command cmdalarm; // Start the timer private Command cmdReset; // Reset to current date/time private Command cmdExit; // Exit the MIDlet private DateField dtfalarmTime; // How long to sleep private int dateIndex; // Index of the DateField on the Form private Date currentTime; // Current time...changes when pressing reset private Timer timerMaster; // The timer - keeps track of system time private alarmTimer timerSlave; // Called by the timer private boolean dateOK = false; // Was the user input valid? public alarm() { display = Display.getDisplay(this); // The main form frmMain = new Form("When to sound the alarm:"); // Save today's date currentTime = new Date(); // DateField with todays date as a default dtfalarmTime = new DateField("", DateField.DATE_TIME); dtfalarmTime.setDate(currentTime); // All the commands/buttons cmdalarm = new Command("Sleep", Command.SCREEN, 1); cmdReset = new Command("Reset", Command.SCREEN, 1); cmdExit = new Command("Exit", Command.EXIT, 1); 10 // Add to form and listen for events dateIndex = frmMain.append(dtfalarmTime); frmMain.addCommand(cmdalarm); frmMain.addCommand(cmdReset); frmMain.addCommand(cmdExit); frmMain.setCommandListener(this); frmMain.setItemStateListener(this); } public void startApp () { display.setCurrent(frmMain); } public void pauseApp() {} public void destroyApp(boolean unconditional) {} public void itemStateChanged(Item item) { if (item == dtfalarmTime) { // If the user selected date and/or time that is earlier // than today, set a flag. We are using getTime() // method of the Date class, which returns the # of // milliseconds since January 1, 1970 if (dtfalarmTime.getDate().getTime() < currentTime.getTime()) dateOK = false; else dateOK = true; } } public void commandAction(Command c, Displayable s) { if (c == cmdalarm) { if (dateOK == false) { Alert alr = new Alert("Unable to set alarm", "Please choose another date and time.", null, null); alr.setTimeout(Alert.FOREVER); alr.setType(AlertType.ERROR); display.setCurrent(alr); } else { // Create a new timer 11 timerMaster = new Timer(); alarmTimer timerSlave = new alarmTimer(); // Amount of time to delay long amount = dtfalarmTime.getDate().getTime() - currentTime.getTime(); timerMaster.schedule(timerSlave,amount); // Remove the commands frmMain.removeCommand(cmdalarm); frmMain.removeCommand(cmdReset); // Remove the DateField frmMain.delete(dateIndex); // Change the Form message frmMain.setTitle("Sleeping..."); } } else if (c == cmdReset) { // Reset to the current date/time dtfalarmTime.setDate(currentTime = new Date()); } else if (c == cmdExit) { destroyApp(false); notifyDestroyed(); } } // Handle the timer task private class alarmTimer extends TimerTask { public final void run() { Alert alr = new Alert("Time to wake up!"); alr.setTimeout(Alert.FOREVER); alr.setType(AlertType.ALARM); AlertType.ERROR.playSound(display); display.setCurrent(alr); // Cancel this timer task cancel(); } } } 12 De la ejecución de esta aplicación se obtiene una serie de pantallas como estas: 13 (MHPSOR7LPHU Esta aplicación consiste en un contador gráfico. Mediante dos barras de tareas que se desplazan (incremento/decremento) se visualiza un transcurso temporal. El código fuente de esta aplicación es el siguiente: import java.lang.*; import java.io.*; import java.util.*; import javax.microedition.lcdui.*; import javax.microedition.midlet.*; /** * A simple class that shows an example of using a Timer and * a TimerTask. * * This MIDlet creates two gauges. One gauge gaugeOne, * sets elements from low to high. The other, gaugeTwo, * set elements from high to low. In effect, this has * gaugeOne "going up", and gaugeTwo "going down." * * The two timers fire at different intervals. * * There are two commands on our form: * * OK: toggles whether the times are active or not. * EXIT: exits the MIDlet. */ public class TimerMIDlet extends MIDlet implements CommandListener { // number of elements in gauge final private static int GAUGE_MAX = 10; private boolean timersRunning; // tracks state of timers private Display myDisplay; // handle to the display private Gauge gaugeOne; private Gauge gaugeTwo; // "going up" gauge // "going down" gauge private Form myScreen; // form on which to // place gauges 14 private Command cmdOK; private Command cmdExit; // OK command // EXIT command private Timer timer; private MyTimerTask timerTaskOne; private MyTimerTask timerTaskTwo; /** * Internal class that provides a TimerTask. */ private class MyTimerTask extends TimerTask { private Gauge myGauge; // reference to gauge private boolean goUp; // if true, go up private int num; // number of times called /** * Public constructor: stores "direction" and a reference to * a gauge. */ public MyTimerTask(Gauge g, boolean up) { myGauge = g; goUp = up; } /** * As the timer fires, this method is invoked. Set gauge * based on goUp */ public void run() { num++; myGauge.setValue(goUp ? GAUGE_MAX -(num % GAUGE_MAX) : num % GAUGE_MAX); } } /** * Public constructor: gets handle to display, * creates form, gauges, and commands. */ public TimerMIDlet() { myDisplay = Display.getDisplay(this); myScreen = new Form("TimerMIDlet"); gaugeOne = new Gauge("Up Gauge", false, GAUGE_MAX, 0); myScreen.append(gaugeOne); gaugeTwo = new Gauge("Down Gauge", 15 false, GAUGE_MAX, GAUGE_MAX); myScreen.append(gaugeTwo); cmdOK = new Command("OK", Command.OK, 1); cmdExit = new Command("Exit", Command.EXIT, 1); myScreen.addCommand(cmdOK); myScreen.addCommand(cmdExit); myScreen.setCommandListener(this); } /** * Changes the state of timers to/from active to/from * not-active. */ private void flipFlop() { if (timersRunning) { timerTaskOne.cancel(); timerTaskTwo.cancel(); timer.cancel(); timersRunning = false; } else { timer = new Timer(); timerTaskOne = new MyTimerTask(gaugeOne, false); timerTaskTwo = new MyTimerTask(gaugeTwo, true); timer.schedule(timerTaskOne, 0, 1000); timer.schedule(timerTaskTwo, 0, 1500); timersRunning = true; } } /** * Called by the system to start our MIDlet. * @exception MIDletStateChangeException */ protected void startApp() throws MIDletStateChangeException { myDisplay.setCurrent(myScreen); flipFlop(); } /** * Called by the system to pause our MIDlet. * No actions required by our MIDLet. */ protected void pauseApp() {} /** * Called by the system to end our MIDlet. 16 * No actions required by our MIDLet. */ protected void destroyApp(boolean unconditional) {} /*** * Respond to command selections. Process two commands: * * OK: flip flop the timers to/from active * EXIT: exit this MIDlet * */ public void commandAction(Command c, Displayable d) { if (c == cmdOK) { flipFlop(); } else if (c == cmdExit) { destroyApp(false); notifyDestroyed(); } } } De la ejecución de esta aplicación se obtiene una serie de pantallas como estas: 17