J2ME. JavaME

988 views

Published on

CLE formación. Plataformas masivas para movilidad. JavaME

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
988
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
394
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

J2ME. JavaME

  1. 1. Curso JME CLE formación 1
  2. 2. Plataformas masivas para movilidad  JavaME (Oracle)  Windows Mobile/Phone (Microsoft)  IPhone (Apple)  Android (Google)  BlackBerry (RIM)  Symbian (Nokia)  BREW (Qualcomm) 2
  3. 3. J2ME • Versión de la plataforma Java orientada a dispositivos de recursos limitados. 3 JavaME (anteriormente J2ME)
  4. 4. J2ME Relación entre ediciones de Java 4
  5. 5. Configuraciones 5
  6. 6. 6 Configuraciones: CDC y CLDC  CDC = Connected Device Configuration  CLDC = Connected Limited Device Configuration
  7. 7. CDC 7 y Blu-ray (BD-J)
  8. 8. CLDC 8 Dos versiones: 1.0 y 1.1
  9. 9. Perfiles 9 Ejemplo: las configuraciones CDC y CLDC no definen APIs de GUI ni comunicaciones red porque hay dispositivos sin GUI y sin comunicaciones
  10. 10. Universidad de DeustoUniversidad de Deusto . . . . . . . . . Configuraciones/Perfiles • MIDP (Mobile Information Device Profile). • Dentro de CLDC • Dirigido a dispositivos móviles (combinación CLDC/MIDP). 10
  11. 11. MIDP (Mobile Information Device Profile) 11
  12. 12. J2ME Universidad de Deusto • CLDC: funcionalidades independientes del dispositivo (librerías generales y de comunicación). • MIDP: funcionalidades específicas (GUI, comunicación ampliada, almacenamiento persistente) 12 MIDP (Mobile Information Device Profile)
  13. 13. MIDP (Mobile Information Device Profile)  Dos versiones: 1.0 y 2.0 La v2.0 introduce  APIs específicas para juegos  Reproducción de sonidos  Criptografía y comunicaciones seguras (HTTPS, SSL)  Mejoras en los “forms” 13
  14. 14. J2ME Arquitectura J2ME 14
  15. 15. Comparación CLDC/MIDP MIDP CLDC 15
  16. 16. Fragmentacion 1) Problemas con las implementaciones MIDP • El estándar no es muy preciso por lo que el comportamiento depende del móvil 2) Diferencias entre dispositivos • Maximo tamaño de aplicación admitido • Cantidad de memoria disponible • Cantidad de almacenamiento (RMS) disponible • Tamaño de pantalla y profundidad de color • Modo de navegacion (teclado, QWERTY, stylus) • APIs disponibles. 16
  17. 17. Estandarización JTWI (Java Technology for the Wireless Industry) 17  JSR-120: Wireless Messaging API  JSR-135: Mobile Media API
  18. 18. Estandarizacion JTWI y MSA 18 MSA: Mobile Service Architecture • Es el JSR 248 que engloba a todos los JSRs (sucesor del JTWI) • Los JSRs fuera del MIDP se llaman paquetes opcionales
  19. 19. La máquina virtual 19
  20. 20. KVM (I) 20 CLDC 1.1 ya define float y double
  21. 21. KVM (II) 21
  22. 22. KVM (III) 22
  23. 23. MIDLets 23
  24. 24. MIDLets: Requisitos funcionales 24
  25. 25. MIDLet: Ciclo de vida 25
  26. 26. MIDLet: Ciclo de vida 26
  27. 27. Empaquetado de un MIDlet MIDlet-Version: 1.0.0 MIDlet-Vendor: Midlet Suite Vendor MIDlet-Jar-URL: CursoJME.jar MicroEdition-Configuration: CLDC-1.1 MicroEdition-Profile: MIDP-2.0 MIDlet-1: Bug,,com.lm2a.bug.TestBug MIDlet-Name: CursoJME Midlet Suite JAD JAR manifiesto Clases comprimidas 27
  28. 28. MIDLet: Ciclo de vida 28
  29. 29. MIDLet: Ciclo de vida 29
  30. 30. MIDLet: Ciclo de vida 30
  31. 31. MIDLet: Ciclo de vida 31
  32. 32. MIDLet: Ciclo de vida 32
  33. 33. MIDLet: Ciclo de vida 33
  34. 34. MIDLet: Ciclo de vida 34
  35. 35. MIDLets: Proceso de desarrollo 35
  36. 36. MIDLets: Etapas del proceso de desarrollo 36
  37. 37. J2ME Universidad de Deusto CLDC • Dos grupos de clases: – Heredadas de J2SE. Encuadradas dentro de las librerías: • java.util • java.lang • java.io – Específicas de esta configuración • javax.microedition.io 37
  38. 38. J2ME CLDC: java.lang • Boolean • Byte • Character • Class • Integer • Long • Math • Object • Runnable • Runtime • Short • String • StringBuffer • System • Thread • Throwable 38
  39. 39. J2ME CLDC: java.util • Calendar • Date • Enumeration • Hashtable • Random • Stack • TimeZone • Vector 39
  40. 40. J2ME CLDC: java.io • ByteArrayOutputStream • ByteArrayInputStream • DataOuput • DataInput • DataInputStream • DataOutputStream • InputStream • InputStreamReader • OutputStream • OutputStreamWriter • PrintStream • Reader • Writer 40
  41. 41. Paquete javax.microedition.midlet 41
  42. 42. Otros paquetes propios de J2ME • javax.microedition.lcdui – Clases asociadas con GUI y el soporte de eventos. • javax.microedition.rms – Mecanismos para el almacenamiento persistente. • javax.microedition.io – APIs para establecer diferentes tipos de comunicación. – MIDP amplia el Generic Connection Framework de CLDC – GCF: interfaces y clases que representan los diferentes tipos de conexiones: http, socket, datagramas, serie, etc. 42
  43. 43. Clase javax.microedition.midlet.MIDlet 43
  44. 44. Clase javax.microedition.midlet.MIDlet 44
  45. 45. Mi primer MIDlet import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Form; import javax.microedition.midlet.MIDlet; public class HolaMundo extends MIDlet { protected Display pantalla; protected Form formulario; public HolaMundo() { } public void startApp() { if (pantalla != null) return; this.pantalla = Display.getDisplay(this); this.formulario = new Form("Hola Mundo"); pantalla.setCurrent(formulario); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } } 45
  46. 46. Jerarquía de clases GUI 46
  47. 47. Clase Display La clase Display es la encargada de administrar la pantalla. Además de otros métodos relativos a las capacidades gráficas del dispositivo, sus métodos más importantes son: void setCurrent(Alert a, Displayable d) Establece la pantalla d despues de la alerta a void setCurrent(Displayable d) Establece la pantalla d void setCurrentItem(Item item) Establece el foco en item 47
  48. 48. Displayable 48
  49. 49. Displayable Más métodos: 49
  50. 50. Ticker  Un Ticker es una línea de texto que se mueve continuamente por la pantalla Ejemplo: la banda de resumen de noticias o cotizaciones de bolsa en TV  Sólo puede haber un Ticker en la pantalla 50
  51. 51. Ticker import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Form; import javax.microedition.lcdui.Ticker; import javax.microedition.midlet.MIDlet; public class HolaMundoTicker extends MIDlet { protected Display pantalla; protected Form formulario; public HolaMundoTicker() { } public void startApp() { if (pantalla != null) return; this.pantalla = Display.getDisplay(this); this.formulario = new Form("Hola Mundo"); formulario.setTicker(new Ticker("Este es un Ticker")); pantalla.setCurrent(formulario); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } } 51
  52. 52. Comandos 52
  53. 53. Comandos 53
  54. 54. Ejemplo Comandos import javax.microedition.lcdui.Command; import javax.microedition.lcdui.CommandListener; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; import javax.microedition.midlet.MIDlet; public class HolaMundoCommand extends MIDlet implements CommandListener { protected Display pantalla; protected Command salir; protected Form formulario; public HolaMundoCommand() { } public void startApp() { if (pantalla != null) return; this.pantalla = Display.getDisplay(this); this.formulario = new Form("Hola Mundo"); 54
  55. 55. Ejemplo Comandos this.salir = new Command("Salir","Salir del Programa",Command.EXIT,0); formulario.addCommand(salir); formulario.setCommandListener(this); pantalla.setCurrent(formulario); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable d) { if (c == salir) { destroyApp(true); notifyDestroyed(); } } } 55
  56. 56. Clase Screen y derivadas 56
  57. 57. Clase Alert 57
  58. 58. Alert 58
  59. 59. Ejemplo de Alert package util; public class RTException extends RuntimeException { protected Throwable ex; public RTException(Throwable ex) { this.ex = ex; } public RTException(String msg,Throwable ex) { super(msg); this.ex = ex; } public void printStackTrace() { if (ex != null) ex.printStackTrace(); super.printStackTrace(); } } 59
  60. 60. Ejemplo de Alert import java.io.IOException; import javax.microedition.lcdui.*; import javax.microedition.midlet.MIDlet; import util.RTException; public class EjemploAlert extends MIDlet implements CommandListener { protected Command salir, aler1, aler2,aler3; protected Display pantalla; protected Form formInicial; public EjemploAlert() { } public void startApp() { if (pantalla != null) return; this.pantalla = Display.getDisplay(this); this.salir = new Command("Salir", Command.EXIT, 1); this.aler1 = new Command("Alerta Modal", Command.SCREEN, 1); this.aler2 = new Command("Alerta No Modal", Command.SCREEN, 1); this.aler3 = new Command("Alerta con Imagen", Command.SCREEN, 1); 60
  61. 61. Ejemplo de Alert // Creo la pantalla principal del MIDlet this.formInicial = new Form("Programa principal"); formInicial.addCommand(salir); formInicial.addCommand(aler1); formInicial.addCommand(aler2); formInicial.addCommand(aler3); formInicial.setCommandListener(this); pantalla.setCurrent(formInicial); } public void pauseApp() { } public void destroyApp(boolean unconditional) {} public void commandAction(Command c, Displayable d) { if (c == salir) { destroyApp(false); notifyDestroyed(); } 61
  62. 62. Ejemplo de Alert else if (c == aler1) { // Creo la pantalla de alerta 1 Alert alerta = new Alert("Alerta Modal", "Esta alerta desaparecerá" + "cuando pulses el botón de Salir", null, AlertType.INFO); alerta.setTimeout(Alert.FOREVER); pantalla.setCurrent(alerta, formInicial); } else if (c == aler2) { // Creo la pantalla de alerta 2 Alert alerta = new Alert("Alerta No Modal", "Esta alerta desaparecera" + " cuando pasen 5 segundos",null, AlertType.INFO); alerta.setTimeout(5000); pantalla.setCurrent(alerta, formInicial); } 62
  63. 63. Ejemplo de Alert else if (c == aler3) { // Creo la pantalla de alerta 3 Image img; try { img = Image.createImage("/i.png"); } catch(IOException ex) { throw new RTException(ex); } Alert alerta = new Alert("Alerta Modal con Imagen", "Pulsa Salir",img, AlertType.INFO); alerta.setTimeout(Alert.FOREVER); pantalla.setCurrent(alerta, formInicial); } } } 63
  64. 64. TextBox 64
  65. 65. TextBox 65
  66. 66. TextBox 66
  67. 67. TextBox 67
  68. 68. TextBox 68
  69. 69. Ejemplo con TextBox public class EjemploTextBox extends MIDlet implements CommandListener { protected Display pantalla; protected TextBox box; protected Command mostrar,insertar,limpiar,restric; protected void startApp() { if (pantalla != null) return; this.pantalla = Display.getDisplay(this); // String title, String text, int maxSize, int constraints) this.box = new TextBox("Ejemplo TextBox","Esto es nun texto",100,TextField.ANY); this.mostrar = new Command("Mostrar",Command.SCREEN,0); box.addCommand(mostrar); this.insertar = new Command("Insertar",Command.SCREEN,0); box.addCommand(insertar); this.limpiar = new Command("Limpiar",Command.SCREEN,0); box.addCommand(limpiar); this.restric = new Command("Ver Restric",Command.SCREEN,0); box.addCommand(restric); box.setCommandListener(this); pantalla.setCurrent(box); } 69
  70. 70. Ejemplo con TextBox protected void pauseApp() { } protected void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable d) { if (c == mostrar) { String texto = box.getString(); Alert alerta = new Alert("Alerta Modal",texto,null,AlertType.INFO); alerta.setTimeout(Alert.FOREVER); pantalla.setCurrent(alerta, pantalla.getCurrent()); } else if (c == insertar) { int pos = box.getCaretPosition(); box.insert("Jose María", pos); } else if (c == limpiar) { box.delete(0,box.size()); // Alternativa: box.setString(""); } 70
  71. 71. Ejemplo con TextBox else if (c == restric) { int constraints = box.getConstraints(); boolean esAny = (constraints & TextField.CONSTRAINT_MASK) == TextField.ANY; String texto = esAny ? "¡SI!" : "¡NO!"; Alert alerta = new Alert("¿Es Modo ANY?",texto,null,AlertType.INFO); alerta.setTimeout(Alert.FOREVER); pantalla.setCurrent(alerta, pantalla.getCurrent()); } } } 71
  72. 72. Ejercicio  Hacer un MIDlet que muestre un TextBox que sólo admita caracteres numéricos y los oculte mientras se escribe  Añadir dos comandos: uno para salir de la aplicación y otro para mostrar con un diálogo modal el contenido de la caja de texto 72
  73. 73. Ejercicio: Solución public class EjercicioTextBox extends MIDlet implements CommandListener { protected Display pantalla; protected TextBox box; protected Command salir,mostrar; protected void startApp() { if (pantalla != null) return; this.pantalla = Display.getDisplay(this); // String title, String text, int maxSize, int constraints) this.box = new TextBox("Ejercicio TextBox","",100, TextField.NUMERIC | TextField.PASSWORD); this.salir = new Command("Salir",Command.EXIT,0); box.addCommand(salir); this.mostrar = new Command("Mostrar",Command.SCREEN,1); box.addCommand(mostrar); box.setCommandListener(this); pantalla.setCurrent(box); } 73
  74. 74. Ejercicio: Solución protected void pauseApp() { } protected void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable d) { if (c == salir) { destroyApp(false); notifyDestroyed(); } if (c == mostrar) { String texto = box.getString(); Alert alerta = new Alert("Alerta Modal",texto,null,AlertType.INFO); alerta.setTimeout(Alert.FOREVER); pantalla.setCurrent(alerta, pantalla.getCurrent()); } } } 74
  75. 75. List 75
  76. 76. List 76
  77. 77. List 77
  78. 78. List 78
  79. 79. Ejemplo Lista Implícita public class ListaImplicita extends MIDlet implements CommandListener { protected Command atras, salir; protected Display pantalla; protected List menu; public void startApp() { if (pantalla != null) return; this.pantalla = Display.getDisplay(this); this.atras = new Command("Atras", Command.BACK, 1); this.salir = new Command("Salir", Command.EXIT, 1); this.menu = new List("Lista Implícita",Choice.IMPLICIT); menu.append("Opción 1", null); menu.append("Opción 2", null); menu.append("Opción 3", null); menu.addCommand(salir); menu.setCommandListener(this); pantalla.setCurrent(menu); } 79
  80. 80. Ejemplo Lista Implícita public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable d) { if (c == List.SELECT_COMMAND) { // Selección de item Form form = null; switch (menu.getSelectedIndex()) { //opcion del menu case 0: form = new Form("Formulario 1"); break; case 1: form = new Form("Formulario 2"); break; case 2: form = new Form("Formulario 3"); break; } final Displayable anterior = pantalla.getCurrent(); // menu form.addCommand(atras); form.setCommandListener(new CommandListener() { public void commandAction(Command c, Displayable d) { //Selecciono comando “Atrás” pantalla.setCurrent(anterior); } } ); pantalla.setCurrent(form); } 80
  81. 81. Ejemplo Lista Implícita else if (c == salir) { // Selecciono salir de la aplicacion destroyApp(false); notifyDestroyed(); } } } 81
  82. 82. Ejemplo Lista Exclusiva public class ListaExclusiva extends MIDlet implements CommandListener { protected Display pantalla; protected Command salir, salvar; protected List lista; public void startApp() { if (pantalla != null) return; this.pantalla = Display.getDisplay(this); this.salir = new Command("Salir", Command.EXIT, 1); this.salvar = new Command("Salvar", Command.ITEM, 1); String opciones[] = {"Opción 1", "Opción 2", "Opción 3"}; this.lista = new List("Lista exclusiva", Choice.EXCLUSIVE, opciones, null); lista.addCommand(salvar); lista.addCommand(salir); lista.setCommandListener(this); pantalla.setCurrent(lista); } public void pauseApp() { } public void destroyApp(boolean unconditional) { } 82
  83. 83. Ejemplo Lista Exclusiva public void commandAction(Command c, Displayable d) { if (c == salvar) { int opcionElegida = lista.getSelectedIndex(); Alert alerta = new Alert("Opción Elegida", "Ha sido elegida :" + (opcionElegida + 1), null, AlertType.INFO); alerta.setTimeout(5000); pantalla.setCurrent(alerta, lista); } else { destroyApp(false); notifyDestroyed(); } } } 83
  84. 84. Ejemplo Lista Múltiple public class ListaMultiple extends MIDlet implements CommandListener { protected Display pantalla; protected List lista; protected Command salir, salvar; public void startApp() { if (pantalla != null) return; this.pantalla = Display.getDisplay(this); this.salir = new Command("Salir", Command.EXIT, 1); this.salvar = new Command("Salvar", Command.ITEM, 1); this.lista = new List("Lista Multiple", Choice.MULTIPLE); lista.insert(menu.size(),"Opción 1", null); lista.insert(menu.size(),"Opción 2", null); lista.insert(menu.size(),"Opción 3", null); lista.addCommand(salir); lista.addCommand(salvar); lista.setCommandListener(this); pantalla.setCurrent(lista); } 84
  85. 85. Ejemplo Lista Múltiple public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable d) { if (c == salvar) { boolean seleccionados[] = new boolean[lista.size()]; lista.getSelectedFlags(seleccionados); StringBuffer buf = new StringBuffer(); for (int i = 0; i < seleccionados.length; i++) { if (!seleccionados[i]) continue; // Alternativa: lista.isSelected(i) buf.append("Opción "); buf.append( i + 1 ); buf.append( "n" ); } Alert alerta = new Alert("Seleccionados:",buf.toString(), null, AlertType.INFO); alerta.setTimeout(5000); pantalla.setCurrent(alerta, lista); } 85
  86. 86. Ejemplo Lista Múltiple else { destroyApp(false); notifyDestroyed(); } } } 86
  87. 87. Ejercicio  Hacer una lista múltiple con 5 opciones  Añadir tres comandos Salir de la aplicación Seleccionar todos Eliminar los seleccionados mostrando en un diálogo la lista de los eliminados 87
  88. 88. Ejercicio: Solución public class EjercicioListaMultiple extends MIDlet implements CommandListener { protected Display pantalla; protected List lista; protected Command salir,eliminar,selecTodos; public void startApp() { if (pantalla != null) return; this.pantalla = Display.getDisplay(this); this.salir = new Command("Salir", Command.EXIT, 1); this.eliminar = new Command("Eliminar Selec", Command.ITEM, 1); this.selecTodos = new Command("Seleccionar Todos", Command.ITEM, 1); this.lista = new List("Lista Multiple", Choice.MULTIPLE); for(int i = 1; i <= 5; i++) lista.append("Opción " + i, null); lista.addCommand(salir); lista.addCommand(eliminar); lista.addCommand(selecTodos); lista.setCommandListener(this); pantalla.setCurrent(lista); } 88
  89. 89. Ejercicio: Solución public void pauseApp() { } public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable d) { if (c == eliminar) { boolean seleccionados[] = new boolean[lista.size()]; lista.getSelectedFlags(seleccionados); StringBuffer buf = new StringBuffer(); for (int i = seleccionados.length - 1; i >= 0; i--) { if (!seleccionados[i]) continue; buf.append("Opción "); buf.append( i + 1 ); buf.append( "n" ); lista.delete(i); } Alert alerta = new Alert("Eliminados:",buf.toString(), null, AlertType.INFO); alerta.setTimeout(5000); pantalla.setCurrent(alerta, lista); } 89
  90. 90. Ejercicio: Solución else if (c == selecTodos) { for (int i = 0; i < lista.size(); i++) lista.setSelectedIndex(i,true); } else { destroyApp(false); notifyDestroyed(); } } } 90
  91. 91. Form 91
  92. 92. Clase javax.microedition.midlet.MIDlet 92
  93. 93. Ejecucion Hola Mundo 93
  94. 94. Form 94
  95. 95. Strings en un formulario 95
  96. 96. Form 96
  97. 97. Ejercicio de cambio de pantallas 97
  98. 98. Solucion 98
  99. 99. Solucion 99
  100. 100. Solucion 100
  101. 101. Diseño de formularios 101
  102. 102. Diseño de formularios 102
  103. 103. Diseño de formularios 103
  104. 104. Diseño de formularios 104
  105. 105. Diseño de formularios 105
  106. 106. Diseño de formularios 106
  107. 107. Diseño de formularios 107
  108. 108. Diseño de formularios 108
  109. 109. Diseño de formularios 109
  110. 110. Diseño de formularios 110
  111. 111. Diseño de formularios 111
  112. 112. Diseño de formularios 112
  113. 113. Diseño de formularios 113
  114. 114. Diseño de formularios 114
  115. 115. Diseño de formularios 115
  116. 116. Diseño de formularios 116
  117. 117. Diseño de formularios 117
  118. 118. Diseño de formularios 118
  119. 119. Diseño de formularios 119
  120. 120. Diseño de formularios 120
  121. 121. Diseño de formularios 121
  122. 122. Diseño de formularios 122
  123. 123. Diseño de formularios 123
  124. 124. Diseño de formularios 124
  125. 125. Diseño de formularios 125
  126. 126. Diseño de formularios 126
  127. 127. Diseño de formularios 127
  128. 128. Diseño de formularios 128
  129. 129. Diseño de formularios 129
  130. 130. Diseño de formularios 130
  131. 131. Diseño de formularios 131
  132. 132. Diseño de formularios 132
  133. 133. Diseño de formularios 133
  134. 134. Diseño de formularios 134
  135. 135. Diseño de formularios 135
  136. 136. Interfaz de bajo nivel 136
  137. 137. Objetivos 137
  138. 138. Introduccion 138
  139. 139. Clases de la API 139
  140. 140. Canvas 140
  141. 141. Ejemplo 141
  142. 142. Ejemplo 142
  143. 143. Eventos de bajo nivel 143
  144. 144. Eventos de bajo nivel 144
  145. 145. Eventos de bajo nivel 145
  146. 146. Manejo de las pantallas gráficas 146
  147. 147. Manejo de las pantallas gráficas 147
  148. 148. Manejo de las pantallas gráficas 148
  149. 149. Manejo de las pantallas gráficas 149
  150. 150. Manejo de las pantallas gráficas 150
  151. 151. Manejo de las pantallas gráficas 151
  152. 152. Manejo de las pantallas gráficas 152
  153. 153. Manejo de las pantallas gráficas 153
  154. 154. Manejo de las pantallas gráficas 154
  155. 155. Manejo de las pantallas gráficas 155
  156. 156. Manejo de las pantallas gráficas 156
  157. 157. Manejo de las pantallas gráficas 157
  158. 158. Ejercicio 158
  159. 159. Ejercicio 159
  160. 160. Threads 160
  161. 161. Threads 161
  162. 162. 162
  163. 163. Manejo de las pantallas gráficas 163
  164. 164. Conectividad 164
  165. 165. Jerarquia 165
  166. 166. Networking (Generic Connection Framework) • Las diferentes posibilidades de comunicación están representadas por 7 interfaces: – Connection – ContentConnection – DatagramConnection – InputConnection – OutputConnection – StreamConnection – StreamConnectionNotifier • Todas las conexiones se crean de la misma manera: – Connection Connector.open(String s) Universidad de Deusto . . . . . . . . . 166
  167. 167. Networking • Formato del String pasado como parámetro: – {protocol}:[{target}][{params}] • Valores para protocol: – file – comm – socket – datagram – http • Target hostname,puerto,nombre de un archivo. • Params opcional (información adicional) 167
  168. 168. Networking • Ejemplos: – Connection c=Connector.open(http://www.javasoft.com) – Connection c=Connector.open(“socket://localhost:8080”) – Connection c=Connector.open(“datagram://www.deusto.es:9000”) – Connection c=Connector.open(“comm:0;baudrate=9000”) – Connection c=Connector.open(“file:/foo.dat”) • Otros métodos de Connector: – open(String s,int mode) – open(String s,int mode,boolean timeouts) – DataInputStream openDataInputStream(String s) – DataOutputStream openDataOutputStream(String s) – InputStream openInputStream(String s) – OutputStream openOutputStream(String s) 168
  169. 169. Networking (sockets) • No todos los móviles soportan este tipo de conexión. • Envío de datos OuputConnection OutputStream • Recepcion de datos InputConnection InputStream • StreamConnection recepción y envío de datos • Hay que cerrar el socket al finalizar la aplicación. 169
  170. 170. SocketConnection Con setSocketOption se puede parametrizar la conexión: Definiendo el tamaño de los buffers de entrada (RCVBUF) y salida (SNDBUF). Con getSocketOption se puede saber las medidas que usa el sistema. Lo normal (el sistema deberia hacerlo) es ajustarlos al MTU (Max. Transmission Unit) y el MSS (Max. Segment Size, cuerpo) de la red. Parametros: //SocketConnection properties private int KEEPALIVE_VALUE=1; private int LINGER_VALUE=5; private int RCVBUF_SIZE=256; private int SNDBUF_SIZE=256; private int DELAY_VALUE=0;//Nagle algorithm is turned off with 0 value! 170
  171. 171. Networking (http) • Ejemplo: Interacción con un jsp. public class Conexion { private String URL="http://localhost:8080/numero/numero.jsp"; public Conexion(){ } public String enviarNumero(int i)throws IOException{ HttpConnection c=null; DataInputStream is=null; OutputStream os=null; StringBuffer b=new StringBuffer(); try { c = (HttpConnection)Connector.open(URL); c.setRequestMethod(HttpConnection.POST); c.setRequestProperty( "Accept","application/octet-stream" ); 171
  172. 172. Networking (http) c.setRequestProperty( "User-Agent","Profile/MIDP-1.0 Configuration/CLDC-1.0" ); c.setRequestProperty("Content-Language", "en-CA"); c.setRequestProperty("Content-Type", "application/x-www-form-urlencoded") c.setRequestProperty( "Connection","close"); os = c.openOutputStream(); os.write(("numero="+i).getBytes()); os.close(); is = c.openDataInputStream(); int ch; while((ch=is.read())!= -1) { b.append((char)ch); } String st=b.toString(); return st.trim(); }finally { if(is!= null) { is.close(); }... 172
  173. 173. Persistencia 173
  174. 174. Almacenamiento persistente • Dos tipos de memoria: – Ejecución de las aplicaciones. – Almacenamiento persistente. • RMS (Record Management System) • javax.microedition.rms • RecordStore tabla • record registro 174
  175. 175. RMS-RecordStore 175
  176. 176. Almacenamiento (RecordStore) • Fichero consistente en un grupo de records. • Métodos: – RecordStore openRecordStore(String nombre,boolean create) – closeRecordStore() – deleteRecordStore(String nombre) • Un RecordStore tiene una cabecera y una serie de bloques de datos (registros o records). – int getVersion() – int getNumRecords() – int getNextRecordId() – long getLastModified() 176
  177. 177. Creación de un RecordStore try{ // Abro el RecordStore tablaDatosPersonales = RecordStore.openRecordStore("DatosPersonales",true); // Imprimo los valores de la propiedades del Record Store System.out.println("Nombre: " + tablaDatosPersonales.getName()); System.out.println("Version: " + tablaDatosPersonales.getVersion()); System.out.println("Ultima modificacion: " + tablaDatosPersonales.getLastModified()); System.out.println("Tamaño: " + tablaDatosPersonales.getSize()); System.out.println("Espacio disponible: " + tablaDatosPersonales.getSizeAvailable()); // Cierro el RecordStore tablaDatosPersonales.closeRecordStore(); } catch (RecordStoreException e) { System.out.println(e.toString()); } 177
  178. 178. Registros y streams DataOutputStream ByteArrayOutputStream byte1 byte2 byte3 byte4 ByteArrayInputStreamDataInputStream Long, Int, String 178
  179. 179. Agregar registros // Creo los streams de soporte ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream (baos); // Vuelco los parámetros de entrada en DataOutputStream try{ try{ dos.writeUTF(nombre); dos.writeUTF(dirIP); dos.writeInt(puerto); } catch (IOException ioe){ System.out.println(ioe.toString()); } // Vuelco ByteArrayOutputStream en el RecordStore byte[] vectorDatos = baos.toByteArray(); System.out.println("Añadiendo un registro"); tablaConexiones.addRecord(vectorDatos, 0, vectorDatos.length); } catch (RecordStoreException rse) { System.out.println(rse.toString()); } 179
  180. 180. Recuperar un registro // Crea los streams de soporte a partir del registro ByteArrayInputStream bais; DataInputStream dis; try{ bais = new ByteArrayInputStream(tablaConexiones.getRecord(recordId)); dis = new DataInputStream (bais); // Extraigo la información try{ String nombre = dis.readUTF(); String dirIP = dis.readUTF(); int puerto = dis.readInt(); System.out.println("Conexión " + nombre + ", hacia " + dirIP + ": " + puerto); } catch (IOException ioe){ System.out.println(ioe.toString()); } } catch (RecordStoreException rse) { System.out.println(rse.toString()); } 180
  181. 181. Filtrado de registros MIDlet <RecordFilter> public boolean matches (byte[] registro) 181
  182. 182. RecordFilterpublic boolean matches (byte[] registro){ boolean resultado=false; String dirIP; // Creo streams de soporte ByteArrayInputStream bais; DataInputStream dis; try{ bais = new ByteArrayInputStream(registro); dis = new DataInputStream (bais); // Extraigo la información String nombre = dis.readUTF(); dirIP = dis.readUTF(); int puerto = dis.readInt(); resultado=dirIP.equals(dirIPDestino); } catch (IOException ioe){ System.out.println(ioe.toString()); } // Devuelvo la comparación return resultado; } 182
  183. 183. Ordenado de registros MIDlet <Comparator> public int compare (byte[] registro1, byte[] registro2) 183
  184. 184. public int compare (byte[] registro1, byte[] registro2){ int resultado=RecordComparator.EQUIVALENT; // Crea streams de soporte ByteArrayInputStream bais1; DataInputStream dis1; ByteArrayInputStream bais2; DataInputStream dis2; try{ // Para el registro 1 bais1 = new ByteArrayInputStream(registro1); dis1 = new DataInputStream (bais1); // Para el registro 2 bais2 = new ByteArrayInputStream(registro2); dis2 = new DataInputStream (bais2); // Extrae la información del registro 1 String nombre1 = dis1.readUTF(); String dirIP1 = dis1.readUTF(); int puerto1 = dis1.readInt(); // y del registro 2 String nombre2 = dis2.readUTF(); String dirIP2 = dis2.readUTF(); int puerto2 = dis2.readInt(); if (puerto1==puerto2){ resultado=RecordComparator.EQUIVALENT; } else if (puerto1<puerto2){ resultado=RecordComparator.PRECEDES; } else if (puerto1>puerto2){ resultado=RecordComparator.FOLLOWS; } } catch (IOException ioe){ System.out.println(ioe.toString()); } return resultado; } 184
  185. 185. MIDlet Suite A RecordStore 1 RecordStore 2 TimeStamp: 223234544332 Nombre: RecordStore1 Versión: 1.0 Registros: 3 1 2 3 Juan Perez, 18 Jose Carlos Zerep, 65 Mario Perelló Salamanca, 48 RecordStore 1 MIDlet Suite B 185
  186. 186. Almacenamiento (RecordStore) • Otros métodos: – int getSizeAvailable() – int getSize() – String[] listRecordStores() • Un RecordStore se bloquea durante una operación de lectura o escritura. 186
  187. 187. Almacenamiento (Record) • Cada una de las entradas a un RecordStore: – Son arrays de bytes. – Identificados únivocamente por un entero. • Métodos: – Int addRecord(byte[] data,int offset,int numBytes) – deleteRecord(int recordId) – getRecord(int recordId,byte[] buffer,int offset) – byte[] getRecord(int recordId) – setRecord(int recId,byte[] data,int offset,int num) 187
  188. 188. Almacenamiento (RecordListener) • Se pueden monitorizar los cambios en un RecordStore mediante el interface RecordListener. • Cuando se modifica un RecordStore se lanzá un evento al RecordListener registrado.Hay tres tipos de eventos: – recordAdded(RecordStore rs,int recordId) – recordChanged(RecordStore rs,int recordId) – recordDeleted(RecordStore rs,int recordId) 188
  189. 189. Almacenamiento (RecordListener) • Métodos: – addRecordListener(RecordListener rl) – removeRecordListener(RecordListener rl) • Un RecordStore puede tener registrados varios RecordListener. – Al contrario que un Displayable (sólo un CommandListener) o un Form (sólo un ItemStateListener). 189
  190. 190. Tablas con múltiples columnas • Un registro (record) en un RecordStore sólo tiene un campo representado por un array de bytes. • Se puede utilizar clases del paquete java.io para empaquetar diferentes tipos de datos en un array de bytes. – DataInputStream – DataOuputStream – ByteArrayOutputStream – ByteArrayInputStream Universidad de Deusto . . . . . . . . . 190
  191. 191. Tablas con múltiples columnas public class Persona{ int id; String nombre; String apellido; int edad; ... } public byte[] convertirBytes(){ byte[] datos; try{ ByteArrayOutputStream bos=new ByteArrayOutputStream(); DataOutputStream dos=new DataOutputStream(baos); dos.writeUTF(nombre); dos.writeUTF(apellido); dos.writeInt(edad); datos=baos.toByteArray(); baos.close(); dos.close(); }... 191
  192. 192. Tablas con múltiples columnas • Se guarda el array de bytes: public void guardar(Persona p){ RecorStore rs; try{ byte[] datos=p.convertirBytes(); int id=p.getId(); if(id==0){ id=rs.addRecord(datos,0,datos.length); p.setId(); } else{ rs.setRecord(id,datos,0,datos.length); } }... 192
  193. 193. Paquetes opcionales • MMAPI (Mobile Media API) – Influencia de JMF (++limitado) – Basado en: • Player: reproducir datos multimedia. • Control: controlar ciertas funciones de procesamiento de información. • DataSource: sirve de soporte de protocolos. • Manager: gestiona el proceso de creación de los Player y los DataSource asociados. • WMA (Wireless Messaging API) – Permite al desarrollador el acceso al servicio SMS. 193
  194. 194. Paquetes opcionales • Web Services API: – Abre nuevas posibilidades a J2ME: • Permite acceso remoto a web services mediante SOAP / XML. • Permite parsing XML. – Muy importante dado el auge actual de XML. 194
  195. 195. Descartadas 195
  196. 196. J2ME GUI (Interfaz gráfica) • No es un subconjunto de AWT o Swing. • javax.microedition.lcdui • Se compone de dos grupos de APIs: – De alto nivel: • Trabajan desde un punto de vista más conceptual mayor grado de portabilidad. • No hay acceso a las características nativas del dispositivo. – De bajo nivel: • Control total del diseño de la pantalla (juegos). • Menor portabilidad. 196
  197. 197. Representa los objetos que pueden renderizarse en la pantalla. - Canvas (bajo nivel) - Screen (alto nivel) • Estructuras predefinidas: Alert, TextBox, List • Pantalla genérica (Form), con la que puede presentarse una mezcla de componentes (imágenes, listas, etc.) GUI (Displayable) 197
  198. 198. GUI (Manejo de eventos) • Dos componentes: – Generadores de eventos. – Listener de eventos (asociado a Displayable). • Evento de alto nivel más importante Command. – CommandListener. – Cualquier Displayable puede ser el generador de un tipo de evento Command. • Displayable.addCommand(Command) • Displayable.removeCommand(Command) 198
  199. 199. GUI (Command) • Command(String label, int type, int priority) • Cuando se activa un Command se genera un evento se le pasa a un CommandListener asociado. • CommandListener interfaz que provee del método de procesamiento de eventos. – void commandAction(Command c, Displayable d) • Un objeto que implemente CommandListener puede escuchar a múltiples Displayable. • Cada Displayable sólo puede tener asociado un CommandListener – Displayable.setCommandListener(CommandListener) 199
  200. 200. GUI (Image) • Permite incluir imágenes (PNG) • Puede crearse un objeto Image a partir: – Un archivo incluido en el MIDlet. • Image.createImage(String name) – Un array de bytes. • Almacenado de forma persistente. • Descargada de un servidor. • Incluido en el propio programa. • Image.createImage(byte[] b,int offset,int length) – Otra imagen. • Image.createImage(Image source) 200
  201. 201. GUI (TextBox) • Permite al usuario introducir información. • TextBox(String title,String text,int max, int constraints). • Input constraints: permite limitar el tipo de información que el usuario puede introducir (ANY,NUMERIC,URL, PHONENUMBER,PASSWORD,etc.) 201
  202. 202. • Implementa el interface Choice. • Constructores: – List(String title,int type) – List(String title,int type,String[] opc,Image[] opc) • Tres tipos de objetos Choice: – Exclusive: sólo un elemento seleccionado. – Implicit: tipo especial de Exclusive. – Multiple: es seleccionable cualquier combinación de elementos. GUI (List) 202
  203. 203. GUI (List) • append(String s,Image i) añadir un elemento a la lista • delete (int i) borrar un elemento de la lista • int getSelectedFlags(boolean[]) devuelve el número de elementos seleccionados y guarda en el array de booleanos el estado de los elementos (true si está seleccionado) • int getSelected index() devuelve el elemento seleccionado • String getString(int i) • insert (int num, String s, Image i) • set (int num, String s, Image i) • int size() 203
  204. 204. J2ME GUI (Alert) • Tipo de pantalla predefinida que sirve para mostrar distintos tipos de mensajes al usuario (error,advertencia, alarma,etc.) • Constructores: – Alert(String title) – Alert(String title,String text,Image image, AlertType type) • TimeOut – Tiempo de expiración de la pantalla Alert. – Se mide en ms, aunque existe la posibilidad de configurarla como modal. – Alert.setTimeout(ms), Alert.setTimeout(Alert.Forever) 204
  205. 205. GUI (Alert) • Display.setCurrent(Alert a,Displayable d) Se indica el siguiente Displayable que debe mostrarse cuando el tiempo expire. -No se pueden añadir Commands a una pantalla de tipo Alert. -Tipos: Alarm, Confirmation, Error, Info, Warning (se diferencian en el sonido emitido al aparecer la pantalla) 205
  206. 206. GUI (Form & Item) • Tipo de pantalla (hereda de Screen) que puede contener diferentes tipos de componentes (imágenes,cuadros de texto,listas, etc.) • Constructores: – Form(String title) – Form(String title, Item[] items) • La clase Item es la superclase de los componentes que se pueden añadir a un Form. 206
  207. 207. GUI (Form & Item) • Un Item no puede situarse en dos Form. • Métodos más importantes de Form: – int size() – append (Image i) – append (Item item) – append (String s) – delete (int itemNum) – insert (int itemNum,Item item) – set (int itemNum,Item item) • Un Item no puede situarse en dos Form. • Métodos más importantes de Form: – int size() – append (Image i) – append (Item item) – append (String s) – delete (int itemNum) – insert (int itemNum,Item item) – set (int itemNum,Item item) 207
  208. 208. GUI (Item) 208
  209. 209. GUI (StringItem) • StringItem(String label, String text) • La aplicación puede modificar el contenido, pero no el usuario. • Métodos: – setText(String s) – String getText() 209
  210. 210. GUI (TextField) • Similar a un TextBox. La única diferencia es la clase de la que heredan. • Item que contiene un texto interactivo. • TextField(String label,String text,int maxSize,int constraints) 210
  211. 211. GUI (ImageItem) • ImageItem(String label,Image i,int layout,String altText) • Layout: – Parámetro que indica cómo se alinea el objeto Image en la pantalla. – Los diferentes valores pueden combinarse con operador OR ( | ). – Valores: DEFAULT, LEFT, RIGHT, CENTER, etc. – setLayout(int layout) 211
  212. 212. GUI (ChoiceGroup) • Implementa el interface Choice. • Similar a List. Única diferencia: – No hay tipo implicito (Implicit) • ChoiceGroup(String label,int type) • ChoiceGroup(String label,int type, String[] elements, Image[] images) • Los métodos son los mismos que hemos visto para List. 212
  213. 213. GUI (Gauge) • Item que implementa una barra que normalmente sirve de indicador. • Gauge (String label,boolean interactive,int maxValue,int initialValue) • Si es interactive el usuario puede cambiar su valor. • Métodos: – setMaxValue(int i) – setValue(int i) – boolean isInteractive() 213
  214. 214. GUI (DateField) • Item editable para presentar información sobre la fecha y la hora. • Constructores: – DateField(String label,int mode) – DateField(String label,int mode, TimeZone t) • Modos: – DATE: el usuario sólo puede configurar la fecha. – TIME: el usuario sólo puede configurar la hora. – DATE_TIME: el usuario puede configurar hora y fecha. 214
  215. 215. GUI (ItemStateListener) • Cuando el usuario interactúa con alguno de los Item: – Introducir texto en un TextField. – Seleccionar/deseleccionar una opción de un Choice. • Se genera un EVENTO ItemStateChanged • ItemStateListener Funciona de la misma manera que lo que hemos visto para Command y CommandListener, es decir, entre otras cosas puede escuchar a múltiples Forms. • Método que procesa los eventos: – void itemStateChanged(Item item) 215
  216. 216. GUI (Canvas) • Subclase de Displayable que implementa la API de bajo nivel. • Es una clase abstracta. Sus subclases deben implementar el método paint(Graphics g). • Métodos para soportar eventos de bajo nivel: – Pulsación de las teclas. • keyPressed(int keyCode) • keyReleased(int keyCode) • keyRepeated(int keyCode) – Pulsación con puntero. • pointerDragged(int x, int y) • pointerPressed(int x,int y) • pointerReleased(int x,int y) • Un Canvas también puede originar eventos de alto nivel (Command) 216
  217. 217. GUI (Canvas) • Métodos para conocer el tamaño de la pantalla: – int getHeight() – int getWidth() • La clase Graphics posibilita renderizar sobre el Canvas figuras geómetricas 2D. • Es muy parecida a la clase Graphics de java.awt de J2SE. • Existen métodos para dibujar líneas, imágenes, texto, rellenar rectángulos o dibujar arcos. 217
  218. 218. GUI (Canvas) 218
  219. 219. GUI (Canvas) • El sistema de coordenadas no representa a los pixels, sino el espacio entre los pixels: – Así el pixel de la parte superior izquierda se encuentra en el cuadrado determinado por las siguientes coordenadas: • (0,0),(1,0) • (0,1),(1,1) • Es importante diferenciar la forma en la que se ejecutan las operaciones de dibujado y relleno de un área. 219
  220. 220. GUI (Canvas) • Color: – Modelo de color de 24 bits (8r,8v,8a) – Si el dispositivo no lo soporta (Display.isColor()), la implementación midp los mapeará a los existentes. – setColor(int RGB) – setColor(int red,int green,int blue) – setGrayScale(int value) • Antes de dibujar sobre un Canvas, se fija el color de fondo. – setColor(int RGB) – fillRect() 220
  221. 221. GUI (Canvas) • Dos tipos de trazos: solido, de puntos – setStrokeStyle(int style) • Dibujado de líneas: – drawLine(int x1,int y1,int x2,int y2) • Dibujado y relleno de formas rectangulares – drawRect(int x,int y,int ancho,int alto) – fillRect(int x,int y,int ancho,int alto) 221
  222. 222. GUI (Canvas) • Dibujado de texto: – drawChar(char c,int x,int y,int anchor) – drawChars(char[] c,int offset,int length,int x,int y,int anchor) – drawString(String c,int x,int y,int anchor) – drawSubstring(String c, int offset,int length, int x,int y,int anchor) • Anchor Points (Puntos de anclaje): – El dibujado de texto se basa en estos puntos. – Hay tres constantes horizontales (LEFT,HCENTER,RIGHT) y cuatro verticales (TOP,BOTTOM,BASELINE,VCENTER) – Para la definición de un anchor point se hace uso de una constante htal y una vcal. 222
  223. 223. GUI (Canvas) 223
  224. 224. GUI (Canvas) • Font: – Representa las diferentes fuentes de texto. – En una aplicación no pueden crearse instancias de Font: • Font getFont(int face,int style,int size) • Style:STYLE_BOLD,STYLE_PLAIN,STYLE_ITALIC,STYLE_UNDERLINED • Size: SIZE_LARGE,SIZE_MEDIUM,SIZE_SMALL • Face: FACE_MONOSPACE,FACE_PROPORTIONAL,FACE_SYSTEM 224
  225. 225. GUI (Canvas) • Dibujado de imágenes: – drawImage(Image i,int x,int y,int anchor) • Traslación de coordenadas: – translate(int x,int y) • Clips: – Se usa cuando se quiere trabajar sobre un área concreta del Canvas • setClip(int x,int y,int ancho,int alto) • Los pixels que no se encuentren dentro del área determinada por el método no se verán afectadas por las operaciones gráficas. 225
  226. 226. GUI (Canvas) • En muchas aplicaciones se requiere que el usuario maneje eventos relacionados con juegos. – MIDP define las siguientes eventos: UP,DOWN,LEFT,RIGHT,FIRE,etc – Las teclas correspondientes a estos eventos dependen del dispositivo. – getGameAction(int keyCode) se usa para traducir el código de la tecla a una acción de un juego. • En muchas aplicaciones se requiere que el usuario maneje eventos relacionados con juegos. – MIDP define las siguientes eventos: UP,DOWN,LEFT,RIGHT,FIRE,etc – Las teclas correspondientes a estos eventos dependen del dispositivo. – getGameAction(int keyCode) se usa para traducir el código de la tecla a una acción de un juego. 226
  227. 227. GUI (Canvas) • Refresco de pantalla: – Objeto de tipo Screen cambios se reflejan de forma automática en pantalla. – Canvas la aplicación debe encargarse de refrescar la pantalla. • repaint(int x,int y,int ancho,int alto) • repaint() • Si el Canvas no está visible en pantalla el refresco no tiene ningún efecto. 227
  228. 228. GUI (Canvas) • El dibujado del Canvas se realiza de manera asíncrona el método repaint() devuelve el control sin esperar a que finalice el proceso paint() al que invoca. • Para conseguir sincronizar con la rutina de paint() – Display.callSerially(Runnable r) se invoca el método run() del objeto Runnable justo después de haber finalizado el proceso de “repintado”.Es muy útil para animaciones. 228

×