Presentation is loading. Please wait.

Presentation is loading. Please wait.

MIDlet Development Virginie. March 2005.

Similar presentations


Presentation on theme: "MIDlet Development Virginie. March 2005."— Presentation transcript:

1 MIDlet Development Virginie. March 2005

2 Overview Introduction: J2ME target and architecture HelloWorld MIDlet 1.User Interface 2.Deployment 3.Persistent storage 4.Networking 5.Security Optimizations References Quizz

3 Motivation Sun Mobility Developer Newsletter, December 2004: –280+ Java handset models available from 32 manufacturers –installed base of Java handsets: 267 million at the beginning of 2004, and is projected to reach 1.5 billion by the end of 2007 –in Japan 50% of all handsets are J2ME-enabled, and have earned operators $1.4 billion –J2ME Wireless Toolkit won JavaPro Best Mobile Development Tool Award

4 J2ME Configurations minimum platforms for the targeted range of devices: –a core collection of java classes –+ specific classes (generic connection framework : javax.microedition.io) CLDC CDC J2SE  no interface java.lang.Comparable  no package java.net  no package java.awt  no class java.math.BigDecimal

5 J2ME Profiles CLDCCDC Foundation RMIPersonal basis Personal Digital Set Top Box IMPDAMID 1.0 & 2.0

6 Other J2ME APIs and Optional Packages Java API for Bluetooth (JSR 82) Wireless Messaging API (JSR 120: SMS & JSR 205: MMS) JDBC Optional Package for CDC Foundation Profile (JSR 169): provides functionality equivalent the java.sql package Location API (JSR 179): GPS or E-OTD… SIP API (JSR 180): standard for VoIP and more Mobile 3D Graphics API (JSR 184) Mobile Media API (JSR 135): sound and multimedia Web Service Access (JSR 172): access to web services: XML parsing, XML based RPC communication support … many more existing or in progress…

7 MIDlet Lifecycle loaded by device new constructor() startApp() Destroyed Paused paused by MIDlet paused by AMS notifyPaused() pauseApp() resumed by AMS resumeRequest() resume requested by MIDlet notifyDestroyed() end requested by MIDlet end requested by AMS destroyApp(true) destroyApp(arg) launched for the first time startApp throws MIDletStateChangeException Terminated yes no yes no arg=true? throws MIDletStateChangeException ? Active

8 Skeleton MIDlet Class import javax.microedition.midlet.*; public class MyMIDlet extends MIDlet { // optional constructor, some initializations go here public MyMIDlet() { } // main MIDlet code goes here, some initializations also go here public void startApp() { } // operations to save current state before releasing the screen go here public void pauseApp() { } // operations to release resources before the MIDlet exits go here public void destroyApp(boolean unconditional) { }

9 HelloWorld MIDlet 1/3: install 1.Download and install the J2ME Wireless Toolkit 2.2: 2.Launch the KToolbar 3.Create a new project: –Project name: MasterOfScience –MIDlet class name: HelloWorld –Keep the default configuration and finish project creation

10 HelloWorld MIDlet 2/3: code 4.In yourPath\WTK22\apps\MasterOfScience\src, create HelloWorld.java : import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class HelloWorld extends MIDlet { private Form welcomeScreen; public HelloWorld() { welcomeScreen = new Form("My First MIDlet"); StringItem message = new StringItem("Hello World!","I'm a MIDlet!"); welcomeScreen.append(message); } protected void startApp() throws MIDletStateChangeException { Display.getDisplay(this).setCurrent(welcomeScreen); } protected void pauseApp() {} protected void destroyApp(boolean arg0) {} }

11 HelloWorld MIDlet 3/3: execution 5.In the WTK, press the Run button 6.On the phone, press Launch

12 User Interface: Display Device screen on which a MIDlet displays its user interface: Display object (package javax.microedition.lcdui ) To obtain a reference to it: displayManager = getDisplay(this) (this is the current MIDlet) To display something on that screen: displayManager.setCurrent(something) where something is Displayable

13 User Interface: Displayable ScreenCanvas Alert Form List TextBox GameCanvas Displayable setTitle setTicker... ItemStringImage ChoiceGroup TextField StringItem Gauge DateField... append javax.microedition.lcdui javax.microedition. lcdui.game

14 User Interface: Exercise

15 User Interface: Good Practices Inputting text can be tedious on portable devices, help the user by: providing pre-filled in fields providing lists to choose from rather than text input boxes remembering previously typed in information organizing easy navigation within the MIDlet screens keeping screens simple: few elements, short texts so there is no need to scroll down

16 Interaction and Commands Only a simple “window” displayed at the time Need commands to change displayed content according to user input Command items may be added ( addCommand method) to a Displayable to be presented to the user. Most important commands may be access directly, remaining commands are automatically presented in a menu. Command behavior is defined in a CommandListener associated to the Displayable. Most displayable items have set and get methods to change displayed content and get user input.

17 Interaction and Commands: Example 1/2 import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class FirstCommands extends MIDlet implements CommandListener { private Form welcomeScreen; private TextField userInput; private Ticker banner; private final Command QUIT = new Command("Exit",Command.EXIT, 2); private final Command CHANGE = new Command("Change",Command.SCREEN,1); public FirstCommands() { welcomeScreen = new Form("First Command"); welcomeScreen.addCommand(QUIT); welcomeScreen.addCommand(CHANGE); welcomeScreen.setCommandListener(this); banner = new Ticker("Welcome here! "); welcomeScreen.setTicker(banner); userInput = new TextField("enter banner text:","",40,TextField.ANY); welcomeScreen.append(userInput); }

18 Interaction and Commands: Example 2/2 protected void startApp() throws MIDletStateChangeException { Display.getDisplay(this).setCurrent(welcomeScreen); } protected void pauseApp() {} protected void destroyApp(boolean arg0) {} public void commandAction(Command c, Displayable d) { if (c == QUIT) notifyDestroyed(); if (c == CHANGE) banner.setString(userInput.getString()); }

19 Interaction and Commands: Exercise 1/2 press “up” 4 times then press OK start on screen 1 with gauge to 0 It displays screen 2, where the text indicates the gauge value Change gauge value with keyboard and press OK It displays screen 1 with gauge value set to the specified value

20 Interaction and Commands: Exercise 2/2 public class CommandsExercise extends MIDlet implements CommandListener { private Form screen1, screen2; private TextField gaugeValue; private Gauge bars; private Command cmdQuit; private Command cmdOK; public CommandsExercise() { screen1 = new Form("Screen 1"); bars = new Gauge("",true,4,0); screen1.append(bars); cmdQuit = new Command("Quit",Command.EXIT, 2); screen1.addCommand(cmdQuit); cmdOK = new Command("OK",Command.OK, 1); screen1.addCommand(cmdOK); screen1.setCommandListener(this); screen2 = new Form("Screen 2"); gaugeValue = new TextField("gauge value:","",2,TextField.NUMERIC); screen2.append(gaugeValue); screen2.addCommand(cmdOK); screen2.setCommandListener(this); protected void startApp() throws MIDletStateChangeException { Display.getDisplay(this).setCurrent(screen1); public void commandAction(Command c, Displayable d) { if (c == cmdQuit) notifyDestroyed(); if ((c == cmdOK) && (d == screen1)) { gaugeValue.setString(String.valueOf(bars.getValue())); Display.getDisplay(this).setCurrent(screen2); if ((c == cmdOK) && (d == screen2)) { bars.setValue(Integer.parseInt(gaugeValue.getString())); Reorder magnets and find the missing ones

21 Compilation and Preverification Compile: Hello\sources>javac -d../classes -bootclasspath c:\WTK22\lib\midpapi20.jar;c:\WTK22\lib\cldcapi 11.jar HelloWorld.java Preverify (required to load a class in a CLDC-conformant VM): \Hello>c:\WTK22\bin\preverify -classpath c:\WTK22\lib\midpapi20.jar;c:\WTK22\lib\cldcapi 11.jar classes (Result placed in output repository) Test with emulator: \Hello\output>c:\WTK22\bin\emulator -classpath. HelloWorld

22 Packaging Create a MANIFEST.MF file: MIDlet-1: Hello MIDlet,,HelloWorld MIDlet-Name: Hello MIDlet MIDlet-Vendor: Virginie Galtier MIDlet-Version: 1.0 MicroEdition-Configuration: CLDC-1.1 MicroEdition-Profile: MIDP-2.0 \Hello\output>jar cvfm Hello.jar MANIFEST.MF HelloWorld.class Create a JAD file HelloWorld.jad: MIDlet-1: Hello MIDlet,,HelloWorld MIDlet-Jar-Size: 1130 MIDlet-Jar-URL: Hello.jar MIDlet-Name: Hello MIDlet MIDlet-Vendor: Virginie Galtier MIDlet-Version: 1.0 MicroEdition-Configuration: CLDC-1.1 MicroEdition-Profile: MIDP-2.0 Test with emulator: \Hello\output>c:\WTK22\bin\emulator -classpath. -Xdescriptor HelloWorld.jad

23 Accessing JAD and Manifest Information getAppProperty(String key) method of the MIDlet class, key is the attribute name in the.jad and manifest files –Example: getAppProperty("MicroEdition-Configuration") returns “CLDC 1.1” Useful for “about” information Useful to pass parameter to the MIDlet: you can define your own attribute in the jad file. If you decide to change the values of thoses parameters, change only the.jad file, no need to modify the jar file!

24 Over The Air Deployment Test Place jar and jad file on a web server Install and execute: \Hello\output>c:\WTK22\bin\emulator - Xjam:transient=http://localhost/Hello/HelloWorld.jad List installed MIDlet: \Hello\output>c:\WTK22\bin\emulator -Xjam:list Result: Running with storage root DefaultColorPhone [1] Name: Hello MIDlet Vendor: Virginie Galtier Version: 1.0 Storage name: #Virginie%0020#Galtier_#Hello%0020#M#I#Dlet_ Size: 2K Installed From: MIDlets: Hello MIDlet Remove installed MIDlet: \Hello\output>c:\WTK22\bin\emulator -Xjam:remove=1 Install: \Hello\output>c:\WTK22\bin\emulator - Xjam:install=http://localhost/Hello/HelloWorld.jad Execute: \Hello\output>c:\WTK22\bin\emulator -Xjam:run=1

25 Over The Air Deployment create a hello.html file linking to the jad file: HelloWorld.jad launch the AMS: \Hello\output>c:\WTK22\bin\emulator -Xjam

26 Installing and Running MIDlet on PocketPC 1.install IBM Workplace Client Technology Micro Edition 2.click on Start / programs / MIDlet HQ 3.enter jad URL

27 Installing and Running MIDlets on PalmOS 1.download IBM WebSphere Micro Environment Toolkit for Palm OS at 2.install IBMWME/prc/ARM/J9JavaVMMidpNG.prc on the Palm device 3.use MIDlet HQ as for the Pocket PC or 3.transform JAR or JAD files to.prc file with the IBM tools jartoprc or jad2prc 4.install the resulting.prc file on the Palm device

28 MIDlet Suite Group of related MIDlets Packaged and installed as a single entity, can be uninstalled only as a group If device supports concurrent running of multiple MIDlets, all active MIDlets from a suite run in the same Java VM. To package a MIDlet suite with the WTK: –Open the project, “settings” tab, “MIDlets” tab, provide the name and class name of each MIDlet in the suite To package “by hand”: –Add a new line “MIDlet-x” with the name and class name of the MIDlet x in the suite in the JAD and MANIFEST files –Build the JAR including all class files

29 Image supported format: PNG example: Image i = Image.createImage("/rainbow.png"); ImageItem ii = new ImageItem("rainbow", i, ImageItem.LAYOUT_DEFAULT, null); mainScreen.append(ii); path to the image file: –in WTK, “/” is the “res” subdirectory –when packaging by hand, add the image file to the JAR

30 MIDlet Icon PNG image displayed in front of the name of a MIDlet of a suite With WTK: –Place icon image in res directory –On the KToolBar: “Settings” tab, “MIDlets tab”, edit the MIDlet line and add the icon file name (in this context, “/” = res directory) “By hand”: –Add the icon file to the JAR –Modify the MIDlet line in the MANIFEST and JAD files: –MIDlet-5: test two,/iconTwo.png,TestIconTwo (in this context, “/” = root of the JAR file)

31 Exercise See Exercise 1 on the web site

32 Persistent Storage Save information as collections of records record = an array of bytes with associated integer identifier record store = a collection of records identified by a name class javax.microedition.rms.RecordStore record store names are shared by all MIDlets in a MIDlet suite: allows information sharing  ! caution when accessing a RecordStore with multiple threads!

33 Record Stores Create and/or open: –static RecordStore openRecordStore(String name, boolean create) –If no record with the given exists If create is true: a new one is created If create is false: a RecordStoreNotFoundException is thrown Close: –closeRecordStore –If a record store is opened more than once by a MIDlet, it won’t be closed until each open instance is closed Other operations: –static void deleteRecordStore(String name) –static String[] listRecordStores() –String getName() –long getLastModified() –int getVersion(): incremented each time a record is added, removed or modified –…

34 Records: creation int addRecord(byte[] data, int offset, int size) Returns identifier Identifiers start at 1, increased by one at each record creation, identifiers of removed records are not reused Record contains range of bytes from data[offset] to data[offset + size – 1] Simple way to create a record from class instance fields: ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeUTF(secretary.name); dos.writeInt(secretary.age); dos.close(); byte[] data = baos.toByteArray(); int id = recordStrore.addRecord(data,0,data.length);

35 Records: other operations Retrieve information from a record store: byte[] data = recordStore.getRecord(recordId); ByteArrayInputStream bais = new ByteArrayInputStream(); DataInputStream dis = new DataInputStream(bais); Person secretary = new Person(); secretary.name = dis.readUTF(); secretary.age = dis.readInt(); dis.close(); Update: void setRecord(int recordId, byte[] data, int offset, int size) Remove: void deleteRecord(int recordId)

36 Record Store events Changes to the content of a record store are reported as events to objects that implement the RecordListener interface and register with the RecordStore using the addRecordListener() method. RecordListener interface: –void recordAdded(RecordStore recordStore, int recordId) –void recordChanged(RecordStore recordStore, int recordId) –void recordDeleted(RecordStore recordStore, int recordId)

37 Record Enumerations The list of active record identifiers can quickly become sparse  Use RecordEnumeration: a list of active records for (int i = 1; i < store.getNextRecordID(); i++) { try { byte[] data = store.getRecord(i); display(data); } catch (InvalidRecordIDException irie) {} } inefficient RecordEnumeration enum = recordStore.enumerateRecords(null, null, false); while (enum.hasNextElement()) { int id = enum.nextRecordId(); // display } False: static snapshot of the records True: keep the enumeration updated when record store is modified

38 Record Enumerations store.getRecord(enum.nextRecordId) ↔ enum.nextRecord() Convenient for read access to the records  Not suitable to modify the data Forwards: –hasNextElement(), nextRecordId(), nextRecord() Backwards: –hasPreviousElement(), previousRecordId, previousRecord() reset() : restart iteration from the beginning When finish, release resources used by a RecordEnumeration with destroy()

39 Record Filters RecordEnumeration enum = recordStore.enumerateRecords(filter, null, false); Contains only the records fulfilling a criterion verified by the filter A filter = object implementing the RecordFilter interface: public boolean matches(byte[] data)

40 Record Comparators Impose an order on the records in a RecordEnumeration by supplying an object implementing the RecordComparator interface: public int compare(byte[] dataA, byte[] dataB) Return value: –RecordComparator.EQUIVALENT –RecordComparator.PRECEDES : “dataA” then “dataB” –RecordComparator.FOLLOWS : “dataB” then “dataA”

41 Exercise See Exercise 2 on the web site

42 Networking no java.net package in the CLDC network functionalities are in Generic Connection Framework (GCF) implemented in javax.microedition.io: –class Connector –interface Connection and its sub-interfaces

43 Connector Provides static methods to open a Connection: public static Connection open(String name, int mode, boolean timeout) name: general form: protocol:address;parameters Examples: socket://localhost:1122 comm:0;baudrate=1600 mode (optional): Connector.READ or WRITE or READ_WRITE timeout (optional): indicates that application code can make use of timeouts on read or write operations (if supported by implementation)

44 Connection DatagramConnection OutputConnectionInputConnection StreamConnectionNotifier ServerSocketConnection StreamConnection UDPDatagramConnection SocketConnection SecureConnection ContentConnection HttpConnection HttpsConnection CommConnection envisages the exchange of information with defined message boundaries logical serial port waits for connection establishment requests: public StreamConnection acceptAndOpen() receive and send Datagram Datagram d = myDatagramConnection.newMessage(messageBytes, length) delivery and duplicate protection are not guaranteed: low overhead but not reliable provide: XputStream to work with bytes DataXputStream to work with java data type (X=in or out) https:// comm:portID[;option;..;option] ssl://host:port socket://host:port socket:// file:// socket://:port datagram://[host]:[port] CLDC 1.0 MIDP 1.0 MIDP 2.0 reliable streams required for all MIDP 2.0 devices required for all MIDP devices inbound reliable streams

45 Client Socket Example 1/4 objective: open a socket connection to a web server and read some data from it import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import javax.microedition.io.*; import java.io.*; public class WebClientSocket extends MIDlet { private Form welcomeScreen; public WebClientSocket() { welcomeScreen = new Form("Client socket example"); StreamConnection socket = null; OutputStream os = null; InputStream is = null;

46 Client Socket Example 2/4 try { socket = (StreamConnection)Connector.open( "socket://www.google.com:80",Connector.READ_WRITE); // send a message to the server String request = "GET / HTTP/1.0\n\n"; os = socket.openOutputStream(); os.write(request.getBytes()); os.close();

47 Client Socket Example 3/4 // read the server's reply, up to a maximum of 128 bytes is = socket.openInputStream(); byte[] buf = new byte[128]; int total = 0; while (total < 128) { int count = is.read(buf, total, 128-total); if (count < 0) break; total += count; } is.close(); String reply = new String(buf, 0, total); socket.close(); // display reply StringItem web = new StringItem("web",reply); welcomeScreen.append(web); } catch (Exception e) { System.err.println(e);

48 Client Socket Example 4/4 } finally { if (socket != null) socket = null; if (is != null) is = null; if (os != null) os = null; } protected void startApp() throws MIDletStateChangeException { Display.getDisplay(this).setCurrent(welcomeScreen); } protected void pauseApp() {} protected void destroyApp(boolean arg0) {} } free up resources even if error occurs (helping the garbage collector is specially important on devices with low capabilities)

49 Exercise See Exercise 3 on the web site

50 Security (with presentation extracts from)

51 HTTPS and certificates 1.download the code for the InternetBrowser MIDlet and create a MIDlet suite containing only that MIDlet 2.run the MIDlet and type the URL 3.run again the MIDlet and type the URL https://www.verisign.com problem: javax.microedition.pki.CertificateException: “Not a CA” or “Root CA’s public key is expired” explanation: Public Key Certificates are needed in order to use HTTPS, but no certificates are present in the keystore when the WTK is installed, or the certificates have expired… to install certificates: –with the WTK: File / Utilities / Manage Certificates (import J2SE certificates; or open the web page with internet explorer, display the certificate and use the “save to a file” option, then import certificate from that file) –by hand: use the MEKeyTool command

52

53

54

55

56

57

58 Sign Exercise 1.using the WTK, create JAR and JAD files for the HelloWorld MIDlet (Project / Package / Create Package) 2.copy the files on a web server and create a web page pointing towards them 3.launch OTA provisioning on the emulator: c:\WTK22\bin\emulator -Xjam 4.launch installation indicating the address of the web page  MIDlet appears “untrusted” 5.sign the MIDlet (Project / Sign / Sign MIDlet suite…) 6.copy the new JAR and JAD on the web site and launch OTA  the MIDlet doesn’t appear “instrusted” anymore

59 Other Security Issues Sending user’s money without their permission (downloading information, sending SMS or MMS…) Disclosing user’s private information (address book…) Denial of service and other malicious code

60

61

62 Security Domains Assigning a security domain to the certificate, designates the level of trust the certificate holder has to access protected APIs and the level of access to those APIs. Untrusted: origin and integrity of the JAR file cannot be trusted by the device (for example, unsigned MIDlet suites) Trusted: JAR file signed with a certificate chain that the device can verify Minimum: all permissions to protected APIs are denied, including access to push functionality and network protocols Maximum: Same as trusted; all permissions to access protected APIs for push functionality and network protocols are allowed

63

64

65 Optimizations for Execution Speed and Memory Consumption Obfuscator –Not much memory + limited network connection  the smaller the jar file, the better  obfuscators appreciated! (“Proguard” is included in the WTK) Free unused variables and resources –close connections –null references Loop condition checking –move constant expressions out of the loop –prefer local variables to instance or class variables Avoid recursion Use array instead of Vector Use record stores instead of a Vector on the heap memory Write a suite of small MIDlets rather than a single multi-purpose MIDlet

66 References Books at INT library: –J2ME in a Nutshell –J2ME, Applications Java pour terminaux mobiles –Java 2 micro edition application development (also on Safari) On line: –Sun J2ME web site (http://java.sun.com/j2me/): toolkit, specifications, code examples, links to developer sites… –J2ME FAQ: –Benhui.net (http://benhui.net): J2ME web sites list, MIDP 2.0 phones, J2ME and Bluetooth… –More: google it in!

67 Quizz from the Sun web site

68 Quizz – Question 1 A midlet is a Java class that extends the abstract class: A.javax.microedition.MIDlet B.javax.microedition.midlet C.javax.microedition.midlet.MIDlet D.javax.microedition.midlet.midlet

69 Quizz – Question 2 Which one of the following methods of the MIDlet abstract class must be implemented by a midlet: A.initApp, startApp B.startApp, destroyApp C.startApp, pauseApp, destroyApp D.initApp, startApp, pauseApp, destroyApp

70 Quizz – Question 3 After compiling your midlet, you must process it with a command to ensure that it is valid before use by the Kilo virtual machine (KVM). What is the name of that command? A.midp B.javac-bootclasspath C.preverify D.jar

71 Quizz – Question 4 A Java Application Descriptor (JAD) file is a text file that is similar to a manifest, except that it is not packaged in a JAR file. Some of the shared attributes that must have identical values are: MIDlet-Name, MIDlet-Version, and MIDlet-Vendor. If any shared attributes are different, then: A.The ones in the descriptor override those in the manifest B.The ones in the manifest override those in the descriptor

72 Quizz – Question 5 When downloading application descriptors (.jad files) from a web server, the web server must return a MIME type of: A.text/vnd.sun.j2me.midp B.text/vnd.sun.j2me.jad C.text/vnd.sun.j2me.app-descriptor D.text/vnd.sun.j2me.midapp

73 Quizz – Question 6 A midlet suite is a set of midlets that are packed together into a single JAR file. Midlets within the same suite: A.Can share the classes and resources contained in the JAR file B.Cannot share the classes and resources contained in the JAR file

74 Quizz – Question 7 What is the difference between a configuration (such as the CLDC) and a profile (such as the MIDP)? A.a configuration defines the set of class libraries available for a particular domain of devices, and a profile provides I/O and network APIs. B.a configuration defines a vertical set of classes that a profile can use. C.a configuration defines a minimum set of class libraries for a wide range of devices, and a profile defines the set of APIs available for a particular family of devices. D.a profile is the foundation for a configuration.

75 Quizz – Question 8 All MIDP implementations are required to support what image format? A.GIF B.JPG C.BMP D.PNG

76 Quizz – Question 9 If a midlet needs to receive high-level events from the implementation, which interface should it implement? A.ActionListener B.CommandListener C.Windows Listener D.ChoiceListener

77 Quizz – Question 10 All MIDP GUI classes are contained in what package? A.javax.microedition.gui B.javax.microedition.lcd C.javax.microedition.lcdui D.javax.microedition.display

78 Quizz – Question 11 Which class would you use to write applications to access low-level input events or to issue graphics calls for drawing to the display? A.Display B.Command C.Screen D.Canvas

79 Quizz – Question 12 What is the correct syntax, using the Generic Connection framework, to open an HTTP connection: A.Connection c = Connection.open("http://developer.java.sun.com"); B.Connector c = Connector.open("http://developer.java.sun.com"); C.Connection c = Connector.open("http://developer.java.sun.com"); D.Connector c = Connection.open("http://developer.java.sun.com");

80 Quizz – Question 13 The MIDP provides a mechanism for MIDlets to persistently store data in a platform-dependent file and retrieve it later. This mechanism is: A.Object Serialization B.JDBC C.RMS D.ODBC

81 Quizz – Question 14 Which of the following statements is true about J2ME? A.J2ME is a single specification B.J2ME is a family of related specifications C.J2ME is a platform for creating applications for the well- established desktop market D.J2ME is a platform for creating server-side enterprise applications

82 Quizz – Question 15 A J2ME-enabled device: A.Can support only a single profile B.Can support multiple profiles


Download ppt "MIDlet Development Virginie. March 2005."

Similar presentations


Ads by Google