Taller de Programación de Dispositivos Móvileszeus.inf.ucv.cl/~jrubio/docs/2010-2/ICI...
Transcript of Taller de Programación de Dispositivos Móvileszeus.inf.ucv.cl/~jrubio/docs/2010-2/ICI...
Taller de Programación de Dispositivos Móviles
José Miguel Rubio L.Oficina 3-20
http://www.inf.ucv.cl/[email protected]
Parte 11.Programación de dispositivos móviles 2.Limitaciones de los dispositivos móviles 3.Sistemas operativos móviles 4.Desarrollo de aplicaciones móviles5.Java 2 Mobile Edition 6.Configuración CDC 7.Configuración CLDC 8.Paquetes opcionales en J2ME 9.MIDP: MIDlets10.MIDP: Interfaces Gráficas de Usuario 11.MIDP: Persistencia 12.MIDP: Conexión por red 13.Persistencia II: Ficheros 14.Para terminar
MIDP: Midlets
MIDP: MIDlets
●Una aplicación MIDP requiere la implementación de un MIDlet, cuya estructura recuerda los Appletsy Servlets de J2SE
import javax.microedition.midlet.MIDlet;
public class EjemploMidlet extends MIDlet
{ public void startApp() { // Arrancar aplicación
}
public void pauseApp() { // Parar aplicación }
public void destroyApp(boolean unconditional) { // Eliminar recursos
} }
Sistemas operativosmóviles
MIDP: Midlets
●De manera similar a un Applet, un MIDlet requierela implementación de tres operaciones de la clase
MIDlet: ●startApp(). Es llamada automáticamente cuando
la aplicación debe comenzar su ejecución. ●pauseApp(). El dispositivo puede solicitar la parada
temporal de la aplicación en cualquier momento.La reanudación implicará una nueva llamada astartApp() o la terminación definitiva mediante lallamada a destroyApp().
●destroyApp(). Es invocada para solicitar la liberación de los recursos del MIDlet y cualquier tareanecesaria antes de su eliminación de memoria.
Sistemas operativosmóviles
MIDP: Midlets
●Un conjunto de MIDlets se distribuye en un fichero.jar
●El MANIFEST del fichero jar es más complicado quelos que conocemos
●Primero se indica el nombre global del conjunto deMIDlets del fichero jar, su versión, autor y las versio-nes de CLDC y MIDP necesarias ●Después cada MIDlet se describe mediante un nom-bre, el icono correspondiente y el nombre de la clase que lo implementa
MIDlet-Name: EjemplosMIDPMIDlet-Version: 1.0 MIDlet-Vendor: ajruedaMicroEdition-Configuration: CLDC-1.1 MicroEdition-Profile: MIDP-2.0 MIDlet-1: Ejemplo,ejemplo.png,EjemploMidlet
Sistemas operativosmóviles
MIDP: Interfaces Gráficasde Usuario
MIDP: Interfaces Gráficas de Usuario
●MIDP proporciona una forma sencilla de construirinterfaces de usuario adaptada a las limitaciones depantalla, potencia de cálculo y batería de los dispo-sitivos móviles. ●En comparación con toolkits como Swing, la varie-dad y número de componentes existentes es muypequeño. ●La interfaz se construye a base de distintas panta-llas, en lugar de ventanas o diálogos. ●Las acciones del usuario definen la transición de una pantalla a otra .
Sistemas operativosmóviles
MIDP: Interfaces Gráficasde Usuario
●Es importante tener en cuenta el pequeño tamañola pantalla del dispositivo a la hora de diseñar lainterfaz. ●La mayoría de los dispositivos dispone de un parde botones de acción cuyo efecto se puede progra-mar para cada pantalla.
Sistemas operativosmóviles
MIDP: Interfaces Gráficasde Usuario
●Para empezar hay que obtener el objeto Displayque permite manejar la pantalla del dispositivo. ●La operación estática getDisplay() de esta clasedevuelve el objeto
Display d = Display.getDisplay() ●A continuación podemos establecer la pantalla ac-tual mediante:
d.setCurrent(Displayable pantalla) ●Una vez obtenido el display, el MIDlet sigue elsiguiente esquema de funcionamiento: 1.Crear una pantalla 2.Mostrarla mediante setCurrent() 3.Esperar las acciones del usuario 4.Elegir otra pantalla en función de estas acciones (volver a 1)
Sistemas operativosmóviles
MIDP: Interfaces Gráficasde Usuario
●Las clases que implementan la interfaz Displayable son las siguientes:
TextBox List Alert Form
Sistemas operativosmóviles Canvas
●Crear y activar una pantalla TextBox es muy sencillo:
TextBox t = new TextBox( Escribe un poema , , 500 , TextField.ANY);
d.setCurrent(t);
●Un Alert es similar a un messageBox de Swing,admitiendo distintos tipos. ●El tiempo de visualización del Alert es configurable mediante setTimeout() ●Al llamar a setCurrent() es necesario indicarel siguiente displayable a mostrar tras el Alert
Alert a = new Alert( Error , Error al salvar la in formación , null, AlertType.ERROR);
a.setTimeout(5000);
d.setCurrent(a, siguienteDisp);
móviles
MIDP: Interfaces Gráficasde Usuario
●El displayable Form permite definir una pantallacon múltiples Item (o componentes):
● StringItem. Similar a un label de Swing. ●Spacer. Un espacio con un ancho y alto determinado. Útil para distribuir los
componentes. ● TextField. Un editor de texto con una etiqueta asociada. ● ImageItem. Una imagen con una etiqueta. ● DateField. Un editor que permite introducir una fecha/hora. ● Gauge. Sirve para representar de manera gráfica un valor entero. ●ChoiceGroup. Sirve para seleccionar valores de una lista predeterminada.Puede ser múltiple, exclusiva o popup ● Cualquier Item definido por el usuario
móviles
MIDP: Interfaces Gráficasde Usuario
●Los Form permiten crear interfaces mucho más ricas: Form f = new Form("Ficha deportiva"); f.append(new TextField("Apellidos", null, 40, TextF ield.ANY)); f.append(new TextField("Nombre", null, 40, TextFiel d.ANY)); f.append(new DateField("Fecha de nacimiento", DateFi eld.DATE)); f.append(new TextField("E-mail", null, 20, TextField.EMAILADDR)); String[] tipos = {"Profesor", "Alumno"}; f.append(cg = new ChoiceGroup("Tipo", ChoiceGroup.EX CLUSIVE, tipos, null));
d.setCurrent(f);
Sistemas operativosmóviles
●Para asociar acciones a los botones del dispositivose utiliza la clase Command
●Las activación de un comando es capturada porun CommandListener, cuya única operación es
commandAction() class listenerTextBox implements CommandListener { public commandAction(Command cm, Displayable ds) { if (cm == cFin) {
// Procesar el comando }
} }
TextBox t = new TextBox( Escribe un poema , , 500 , TextField.ANY);
t.addCommand(cFin = new Command( Fin , Command.OK, 0)); t.setListener(new listenerTextBox());
d.setCurrent(t);
Tarea:Siguiendo el ejemplo que hemos desarrollado en la asignatura, crear unvisor móvil de nuestra cuenta
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import java.util.*;
public class MidletCuenta extends MIDlet{ private Cuenta c;
private Display d; private TextField tCodigo; private Command cEntrar, cSalir, cVolver, cMovimiento s;
private Form fPeticionCodigo, fInfoCuenta; private List lMovCuenta;
public MidletCuenta() { d = null;
}
void crearComandos() { cEntrar = new Command("Entrar", Command.OK, 0); cSal ir = new Command("Salir", Command.EXIT, 1); cVolver = newCommand("Volver", Command.BACK, 0); cMovimientos = newCommand("ver Mov.", Command.SCREEN, 0); }
MIDP: Interfaces Gráficasde Usuario
public void startApp() { if (d == null) { d = Display.getDisplay(this); } crearComandos();
crearFormPeticionCodigo(); d.setCurrent(fPeticionCodigo); }
void crearFormPeticionCodigo() { fPeticionCodigo = new Form("Información de cuentas"); fPeticionCodigo.append(tCodigo = new TextField("Códig o de cuenta ", null, 10, TextField.NUMERIC)); fPeticionCodigo.addCommand(cEntrar); fPeticionCodigo.addCommand(cSalir);
fPeticionCodigo.setCommandListener(new listenerPetic ionCodigo()); tCodigo.setLayout(Item.LAYOUT_2 | Item.LAYOUT_CENT ER); }
class listenerPeticionCodigo implements CommandListene r { public void commandAction(Command cm, Displayable s) { if(cm == cEntrar) {
// Cargar la cuenta aquí
crearFormInformacionCuenta(); d.setCurrent(fInfoCuenta); } elseif (cm == cSalir) { destroyApp(true);
notifyDestroyed(); }
} }
Sistemas operativosmóviles
MIDP: Interfaces Gráficasde Usuario
void crearFormInformacionCuenta() { // Crear formulario de información dae la cuenta fIn foCuenta = newForm("Información de cuenta"); fInfoCuenta.append(n ewStringItem("Código:", Long.toString(c.leerNumero()) ));
fInfoCuenta.append(new StringItem("Titular:", c.leer Titular()));
fInfoCuenta.append(new StringItem("Interés:", Float.toString(c.leerInteres()))); fInfoCuenta.appe nd(newStringItem("Saldo:", Float.toString(c.leerSaldo())) );
fInfoCuenta.addCommand(cMovimientos); fInfoCuenta.addCommand(cVolver); fInfoCuenta.setCommandListener(new listenerInformaci onCuenta());
// Crear lista de movimientos lMovCuenta = new List("Ultimos movimientos", List.IMPLICIT); Movimiento m; int nMov, nm; for (nMov = 10, nm = c.numMovimientosHistorico() - 1;
nMov > 0 && nm >= 0; nm--, nMov--) { m = c.leerMovimientoHistorico(nm); lMovCuenta.append(cadenaDate(m.fecha) + ' ' + m.t ipo + '
' + m.importe + ' ' + m.saldo, null); }
lMovCuenta.addCommand(cVolver); lMovCuenta.setCommandListener(new listenerInformacio nMovimientos());
}
Sistemas operativosmóviles
MIDP: Interfaces Gráficasde Usuario
class listenerInformacionCuenta implements CommandList ener{ public void commandAction(Command cm, Displayable s) { if(cm == cVolver) {
d.setCurrent(fPeticionCodigo); } else if (cm == cMovimientos) { d.setCurrent(lMovCuenta); }
} }
class listenerInformacionMovimientos implements Comman dListener { public void commandAction(Command cm, Displayable s) {
if (cm == cVolver) { d.setCurrent(fInfoCuenta);
} }
}
Sistemas operativosmóviles
MIDP: Persistencia
MIDP: Persistencia
●La capacidad de almacenamiento persistente de undispositivo móvil puede ser muy limitada.
●El soporte de tarjetas de memoria, cada vez máscomún, ha aumentado mucho las prestaciones (8Gben iPhone o Nokia N95) posibilitando una estructurade ficheros similar a la de un computador convencional. ●Sin embargo el perfil MIDP es conservador y pro-porciona un soporte sencillo de persistencia a través de registros de bloques de bytes.
Sistemas operativosmóviles
MIDP: Persistencia
●Un MIDlet puede abrir un almacén de registroscon un nombre arbitrario mediante:
RecordStore RecordStore.openRecordStore(“nombre”, true); ●El segundo parámetro indica que el almacéndebe abrirse si no existe. ●A través de las operaciones del objeto RecordStore podremos manejar los registros. ●Normalmente un almacén no se comparte conotros MIDlets, aunque puede habilitarse este acceso. ●El almacén de registros se cierra mediante:
closeRecordStore()
Sistemas operativosmóviles
MIDP: Persistencia
●El acceso a los registros se realiza a través de un identificador numérico, que es devuelto al aña-dir un registro:
int addRecord(byte[] datos, int offset, int numBytes) ●Para recuperar un registro debemos indicar suidentificador:
int getRecord(int id, byte[] buffer, int offset) ●Modificar un registro ya existente:
void setRecord(int id, byte[] nuevosDatos, int offset, int numBytes) ●Eliminar un registro:
void deleteRecord(int id)
Sistemas operativosmóviles
MIDP: Persistencia
●Es posible recorrer los registros de un almacéncreando una enumeración:
RecordStore rs = RecordStore.openRecordStores( ejem plo, true);
RecordEnumeration re = re.enumerateRecords(null, nu ll, false); while (re.hasNextElement()) {
byte[] datos = re.nextRecord(); // Operar con los datos
}
re.destroy(); rs.closeRecordStore();
●La operación enumerateRecords() admite la es-pecificación de clases de filtrado y ordenación de los registros del almacén.
Sistemas operativosmóviles
MIDP: Persistencia
Tarea:Crear un gestor de persistencia para las cuentas corrientes medianteun almacén de registros.
import java.io.*; import java.util.*; import javax.microedition.rms.*;
public class DAOCuentaRS { static DAOCuentaRS instancia = null;
public static DAOCuentaRS obtenerInstancia() throws RecordStoreException{ if (instancia == null) {
instancia = new DAOCuentaRS(); } return instancia;
}
private DAOCuentaRS() {}
public boolean existe(long numero) throws RecordStore Exception, IOException{ RecordStore rs = null; try { rs = RecordStore.openRecordStore("cuentas", true); return (buscarRegistroCuenta(rs, numero) != -1); } finally {
if (rs != null) rs.closeRecordStore(); }
}
Sistemas operativosmóviles
MIDP: Persistencia
public Cuenta cargar(long numero) throws RecordStoreE xception, IOException{ RecordStore rs = null; DataInputStream dis = null; Cuenta c = null;
try { rs = RecordStore.openRecordStore("cuentas", true);
int idReg = buscarRegistroCuenta(rs, numero); if (idReg == -1) {
return null; }
dis = new DataInputStream(newByteArrayInputStream(rs.getRecord(idReg))); c = ne wCuenta(dis.readLong(), dis.readUTF(), dis.readFloat ()); c.saldo = dis.readFloat(); int nMov = dis.readInt(); for (int nm = 0; nm < nMov; nm++) { c.movimientos.addElement(new Movimiento(new Date(dis. readLong()), dis.readChar(), dis.readFloat(), dis.readFloat())); }
} finally { if (dis != null) dis.close(); if (rs!= null) rs.closeRecordStore(); }
return c; }
Sistemas operativosmóviles
MIDP: Persistencia
public void salvar(Cuenta c) throws RecordStoreExceptio n, IOException{ RecordStore rs = null; ByteArrayOutputStream bos = null; DataOutputStream dos = null; try {
rs = RecordStore.openRecordStore("cuentas", true); d os = newDataOutputStream(bos = new ByteArrayOutputStream());
dos.writeLong(c.leerNumero()); dos.writeUTF(c.leerT itular()); dos.writeFloat(c.leerInteres()); dos.writeFloat(c.l eerSaldo());
Movimiento m; int nMov = c.numMovimientosHistorico(); dos.writeInt( nMov);
for (int nm = 0; nm < nMov; nm++) { m = c.leerMovimientoHistorico(nm);
dos.writeLong(m.fecha.getTime()); dos.writeChar(m.t ipo); dos.writeFloat(m.importe); dos.writeFloat(m.saldo); }
int idReg = buscarRegistroCuenta(rs, c.leerNumero()); if (idReg != -1) {
rs.setRecord(idReg, bos.toByteArray(), 0, bos.size()); } else {
rs.addRecord(bos.toByteArray(), 0, bos.size()); }
} finally { if (dos != null) dos.close(); if (rs!= null) rs.closeRecordStore(); }
} Sistemas operativos
móviles
MIDP: Persistencia
private int buscarRegistroCuenta(RecordStore rs, long numero) throws RecordStoreException, IOException { RecordEnumeration re = null; DataInputStream dis = null; long recNum; int id;
try { re = rs.enumerateRecords(null, null, false); while (re.hasNextElement()) {
id = re.nextRecordId(); dis = new DataInputStream(newByteArrayInputStream(rs.getRecord(id))); recNum = di s.readLong(); if (recNum == numero)
{ return id; } dis.close(); dis = null;
} } finally { if (dis != null) dis.close(); if (re != null) re.destroy();
}
return -1; }
}
Sistemas operativosmóviles
MIDP: Persistencia
En el MIDlet debemos crear un atributo para referenciar el gestor de persis-tencia, y realizar su inicialización en startApp()
public void startApp() { if (d == null) {
d = Display.getDisplay(this); }
if (dc == null) { try {
dc = DAOCuentaRS.obtenerInstancia(); } catch(Exception e) {
d.setCurrent(new Alert("Error", "No es posible abrir el almacén de registros", null, AlertType.ERROR));
destroyApp(true); notifyDestroyed(); return;
} }
// Crear las cuentas de ejemplo si no existen crearCuentasEjemplo();
crearComandos(); crearFormPeticionCodigo(); d.setCurrent(fPeticionCodigo); }
Sistemas operativosmóviles
MIDP: Persistencia
class listenerPeticionCodigo implements CommandListene r { public void commandAction(Command cm, Displayable s) { if(cm == cEntrar) {
try { c = dc.cargar(Long.parseLong(tCodigo.getString ())); if (c == null) {
d.setCurrent(new Alert("Error", "Cuenta inexistente" , null, AlertType.ERROR), fPeticionCodigo); return;
} } catch(Exception e) {
d.setCurrent(new Alert("Error", "Error de lectura de cuenta", null, AlertType.ERROR), fPeticionCodigo);
return; }
crearFormInformacionCuenta(); d.setCurrent(fInfoCuenta); } elseif (cm == cSalir) { destroyApp(true);
notifyDestroyed(); }
} }
Sistemas operativosmóviles
MIDP: Conexión por red
MIDP: Conexión por red
●MIDP es especialmente potente en lo que se refie-re a la conexión por red mediante sockets, http yotros protocolos ●La clase Connection representa una conexión ge-nérica y es extendida a tres conexiones que admi-ten E/S mediante streams: InputConnection, Output-Connection y StreamConnection●La clase StreamConnection es extendida a variasclases que representan distintos tipos de conexiones:
CommConnection, HttpConnection, httpsConnection,SocketConnection, etc.
Sistemas operativosmóviles
MIDP: Conexión por red
●La clase Connector es una factoría que a partir de un url devuelve la clase de conexión correspon-diente: Connection Connector.open(String url)
HttpConnection con1; con1 = (HttpConnection) Connector.open(http://www .google.es/search?hl=es&q=j2me);
SocketConnection con2; con2 = (SocketConnection) Connector.open(socket:/ /miservidor:79);
●La conexión debe cerrarse al final con close() ●A partir de la conexión podemos obtener un streamde lectura o escritura HttpConnection con1; con1 = (HttpConnection) Connector.open(http://www .google.es/search?hl=es&q=j2me);
InputStream is = con1.openInputStream(); // Utilizar el streamcon1.close();
Sistemas operativosmóviles
MIDP: Conexión por red
Ejemplo:El siguiente gestor de persistencia obtiene los datos de la cuentadesde un servidor web
import java.io.*; import java.util.*; import javax.microedition.io.*; import javax.microedition.io.file.*;
public class DAOCuentaNC { static DAOCuentaNC instancia = null;
public static DAOCuentaNC obtenerInstancia() { if (instancia == null) {
instancia = new DAOCuentaNC(); } return instancia;
}
private DAOCuentaNC() { }
public boolean existe(long numero) { try {
cargar(numero); } catch(Exception e)
{ return false; } return true;
} Sistemas operativos
móviles
MIDP: Conexión por red
public Cuenta cargar(long numero) throws IOException{ InputConnection ic = null; DataInputStream dis = null; Cuenta c = null;
try { ic = (InputConnection) Connector.open(urlCuenta(num ero)); dis = ic.openDataInputStream(); c = new Cuenta(dis.readLong(), dis.readUTF(), dis.r eadFloat()); c.saldo= dis.readFloat();
int nMov = dis.readInt(); for (int nm = 0; nm < nMov; nm++) { c.movimientos.addElement(new Movimiento(new Date(dis. readLong()), dis.readChar(), dis.readFloat(), dis.readFloat())); }
} catch(Exception e) { // No se encuentra la cuenta returnnull;
} finally { if (ic != null) ic.close();
}
return c; }
private String urlCuenta(long codigo) { return "http://robin.ujaen.es/asignaturas/progav/cu entas/"
+ Long.toString(codigo) + ".cnt"; }
}
Sistemas operativosmóviles
Persistencia II: Ficheros
Persistencia II: Ficheros
●El File Connection and PIM API (JSR 75) defineun nuevo tipo de conexión denominado FileConnec-tion que permite trabajar con ficheros de manerasimilar a un computador convencional. ●Este API no está disponible en todos los disposi-tivos. ●El acceso al sistema de ficheros requiere permisosespeciales si la aplicación no está certificada, paraevitar daños en el mismo.
Sistemas operativosmóviles
Persistencia II: Ficheros
El siguiente ejemplo lee una imagen guardada en el dispositivo
FileConnection fc; InputStream is;
fc = (FileConnection) Connector.open( /Imagenes/flo wer.jpg , Connector.READ); is = fc.openInputStream(); Image mi = Image.createImage(is); // Utilizar la imagen
is.close();
●La clase FileConnection permite abrir un stream deE/S al fichero pero también contiene operacionespara la creación, renombrado y borrado de ficherosy directorios.
Sistemas operativosmóviles
Persistencia II: Ficheros
●No obstante existe un problema importante: la estructura del sistema de ficheros de cada dispositivo no es estándar ●Cada dispositivo contiene una raíz para cada uno de los medios de almacenamiento: memoria interna (/root, /internal, /InternalMemory) y tarjetas de memoria (/SDCard1, /MemoryCard) ●Es posible enumerar las distintas raices existentes mediante el registro del sistema de ficheros: Enumeration raicesSF = FileSystemRegistry.listRoots(); while (raicesSF.hasMoreElements()) { raizSF = (String) raicesSF.nextElement(); // Hacer algo con la raiz encontrada }
Sistemas operativosmóviles
Persistencia II: Ficheros
Este gestor de persistencia utiliza el API JSR 75
import java.io.*; import java.util.*; import javax.microedition.io.*; import javax.microedition.io.file.*;
class FileConnectionAPIInexistente extends Exception {}
public class DAOCuentaFC { static DAOCuentaFC instancia = null; String raizSF;
public static DAOCuentaFC obtenerInstancia() throws Fil eConnectionAPIInexistente{ if (instancia == null) {
String versionFCAPI = System.getProperty( "microedition.io.file.FileConnection.version"); if (versionFCAPI == null) {
throw new FileConnectionAPIInexistente(); } instancia = new DAOCuentaFC();
} return instancia;
}
private DAOCuentaFC() { obtenerRaizSistemaFicheros(); }
Sistemas operativosmóviles
Persistencia II: Ficheros
public boolean existe(long numero) { try {
cargar(numero); } catch(Exception e)
{ return false; } return true;
}
public Cuenta cargar(long numero) throws IOException{ FileConnection fc = null; DataInputStream dis = null; Cuenta c = null;
try { fc = (FileConnection) Connector.open(urlCuenta(nume ro), Connector.READ); if (!fc.exists()) {
return null; }
dis = fc.openDataInputStream(); c = new Cuenta(dis.readLong(), dis.readUTF(), dis.readFloat()); c.saldo = dis.readFloat();
Sistemas operativosmóviles
Persistencia II: Ficheros
int nMov = dis.readInt(); for (int nm = 0; nm < nMov; nm++) { c.movimientos.addElement(new Movimiento(new Date(dis. readLong()), dis.readChar(), dis.readFloat(), dis.readFloat())); }
} finally {
if (fc != null) fc.close(); }
return c; }
public void salvar(Cuenta c) throws IOException{ FileConnection fc = null; DataOutputStream dos = null;
try { fc = (FileConnection) Connector.open("file:///" +
raizSF + "cuentas", Connector.READ_WRITE); if (!fc.exists()) {
fc.mkdir(); } fc.close();
fc = (FileConnection) Connector.open(urlCuenta(c.leerNumero()), Connector.READ_WRITE); if (!fc.exists())
{ fc.create(); }
Sistemas operativosmóviles
Persistencia II: Ficheros dos = fc.openDataOutputStream();
dos.writeLong(c.leerNumero()); dos.writeUTF(c.leerTitular()); dos.writeFloat(c.leerInteres()); dos.writeFloat(c.leerSaldo());
Movimiento m; int nMov = c.numMovimientosHistorico(); dos.writeInt(nMov); for (int nm = 0; nm < nMov; nm++)
{ m = c.leerMovimientoHistorico(nm); dos.writeLong(m.fecha.getTime()); dos.writeChar(m.tipo);
dos.writeFloat(m.importe); dos.writeFloat(m.saldo); }
} finally { if (fc != null) fc.close();
} }
private String urlCuenta(long codigo) { return "file:///" + raizSF + "cuentas/" + Long.toString(codigo) + ".cnt"; }
private void obtenerRaizSistemaFicheros() { Enumerat ionraicesSF = FileSystemRegistry.listRoots(); if(raicesSF.hasMoreElements()) {
raizSF = (String) raicesSF.nextElement(); }
} } Sistemas operativos
móviles
Persistencia II: Ficheros
●Otro problema adicional son las restricciones deseguridad existentes en algunos dispositivos, quesólo permiten el acceso a determinados directorios públicos (/Imagenes, /Sonidos, etc.)
Sistemas operativosmóviles
Para terminar
Para terminar
●Hemos estudiado MIDP a nivel básico ●En función de las necesidades de la aplicaciónmóvil a implementar será necesario estudiar conmayor profundidad algunos de los APIs que hemos visto y otros nuevos
● PIM API JSR 75 ● API MIDP para juegos ●
Mobile Media API JSR JSR 184 ●
Wireless Messaging API JSR 135 ● Bluetooth API JSR 82 Sistemas operativos
móviles