Sunday, April 22, 2007

JAVA 認證心得 -- SCMAD (12)



  • Timer class is Thread-safe
  • AlertType.playSound(Display display) -> boolean
  • Display.callserially(Runnable r)
  • readUTF() to read a UTF string from the associated stream
  • StringBuffer method

    Ø char charAt (int index)

    Ø string toString()

  • MIDLet code and description

JAVA 認證心得 -- SCMAD (11)

Wireless Messaging API 1.1 (WMA)


  • CBS (Cell Broadcast Service) can only be received by an application and cannot be sent. If the send() method is called with a CBS address, IOException will be thrown.
  • WMA provides separate permissions for SMS and CBS protocol.
  • Messages can be received asynchronously by creating a class implementing the MessageListener interface and registering an instance of the class to the connection using the MessageConnection.setMessageListener()
  • TextMessage.setPayloadText(String msg)
  • BinaryMesage.setPayloadData(byte[] byte)
  • Messages are delivered to the application in the same order as the device received them.
  • When a large message is spilt into multiple SMS messages, ordering is handled correctly when they are automatically concatenated back into a single Message object.
  • MessageConnection.numberOfSegments(Message msg)
  • An application can have several MessageConnection instances open simultaneously and these connections can be both in client and server mode.
  • Message.getTimeStamp method always returns null for received cell broadcast.
  • A text message can be sent by passing either the constant MessageConnection.TEXT_MESSAGE or the value “text” in the MessageConnection.newMessage(String Type) method. Same as MessageConnection.BINARY_MESSAGE / “binary”
  • The Message length of an SMS depends on two factors
    • Encoding used, such as GSM 7-bit alphabet, and UCS-2 16 bit
    • Presence/absence of port number

  • An IllegalArgumentException would be thrown if the message is sent using a MessageConnection that is different from the MessageConnection which was used to create the message using the newMessage() method. If a timeout occurs an InterruptedIOException is thrown.
  • A message can be received either

    Ø Synchronously: Using MessageConnection.receive() blocking method

    Ø Asynchronously: By creating a class implementing the MessageListener interface and registering an instance of the class to the connection using the MessageConnection.setMessageListener() method.

  • The MessageListener interface has a notifyIncomingMessage() method, which would be called when a message arrives. The listener mechanism allows applications to receive incoming messages without needing to have a thread blocked in the receive() method call. If multiple messages arrive very closely together in time, the implementation has the option of calling this listener from multiple threads in parallel. Applications MUST be prepared to handle this and implement any necessary synchronization as part of the application code, while obeying the requirements set for the listener method.
  • The GSM standard specifies two mechanisms for SMS message concatenation.
  • The system property wireless.messaging.sms.smsc contains the SMSC address.

JAVA 認證心得 -- SCMAD (10)

MMAPI (Media using MIDP 2.0 and Mobile Media API)


  • DataSource is available. DataSource.getStreams() be used to Get the collection of streams that this source manages. The collection of streams is entirely content dependent. The MIME type of this DataSource provides the only indication of what streams may be available on this connection.
  • Player’s Lifecycle
  • Controllable Interface is the base interface.

    Ø Player implements the interface and plays media data.

    Ø SourceStream implements the interface and provides custom protocol support. Not in MIDP 2.0.

    Ø DataSource is a class used to provide custom media protocols. Not in MIDP 2.0.


  • Control interface is the super-interface for all controls that can be implemented by a Player. Only the identified controls are supported in MIDP 2.0.

    Ø Audio Controls

    - ToneControl controls the Tone Seqeuence format. Supported in MIDP 2.0.(setSequence(byte[] seq) can be called in UNREALIZED and REALIZED)

    - VolumeControl controls the Player’s volume. Supported in MIDP 2.0.

    - MIDIControl controls MIDI playback.

    - PitchControl controls the pitch of a MIDI note.

    - TempoControl controls the tempo of a MIDI note.

    Ø Video Controls

    - VideoControl controls video media playback.

    - FramePositioningControl controls the framing of video.

    Ø General Controls

    - StopTimeControl allows you to set a preset stop time. This is like a sleep-time.

    - RateControl is used in conjunction with TimeBase to calibrate time used by Player. It controls the playback rate of a Player. Rates are specified in “milli-percetage”

    - GUIControl is used to display a user interface for the associated Player.

    - RecordControl is used to record the media played by the Player.

    - MetaDataControl can be used to get some general meta-data information about the media content.

  • PitchControl raises or lowers the playback pitch of audio without changing the playback speed. PitchControl does not influence playback volume in any way.
  • PitchControl can be implemented in Players for MIDI media or sampled audio. It is not possible to set audible output to an absolute pitch value. This control raises or lowers pitch relative to the original.
  • The pitch change is specified in number of "milli- semitones" to raise the pitch. A Player which supports only 0 pitch change must not implement PitchControl.
  • MetaDataControl is used to retrieve metadata information included within the media streams. A MetaDataControl object recognizes and stores metadata and provides XML-like accessor methods to retrieve this information. Predefined keys are provided to refer to commonly used metadata fields (title, copyright, data, author).
  • The USE_GUI_PRIMITIVE constant defines a mode on how the GUI is displayed.
  • Manager class is a factory to get Player implementations.

Ø Default constants provided for Tone Sequence (TONE_DEVICE_LOCATOR) and MIDI playback (MIDI_DEVICE_LOCATOR). MIDI is not supported in MIDP 2.0.

  • Manager.playTone(int note, int duration, int volume) can be used to generate simple monotones.
  • Class Manager

    static Player createPlayer(InputStream stream, String type)

    static Player createPlayer(String locator)

  • Player class is used to play media data. An implementation is obtained from the Manager factory.

Ø TimeBase is used by the Player to track time.

  • MIDP media API supports only InputStream where data is streamed sequentially.
  • Random seeking capabilities are provided in the DataSource and SourceStream classes, which are provided in the MMAPI.
  • Convenience constants MIDI_DEVICE_LOCATOR and TONE_DEVICE_LOCATOR can be used to get a MIDI (audio/midi) or Tone Sequence (audio/x-tone-seq) Player.
  • A TimeBase is a constantly ticking source of time. It measures the progress of time and provides the basic means of synchronizing media playback for Players.
  • In STARTED The following methods will throw an IllegalStateException if invoked .

    Ø setTimeBase()

    Ø setLoopCount()

  • PlayerListener is a listener interface that can be implemented and registered to a Player to listen to the Player’s events.
  • PlayerListener can have more than one associated listener. Only one method called playerUpdate()

JAVA 認證心得 -- SCMAD (9)



  • Canvas

- protected void keyPressed(int keyCode)

- protected void keyReleased(int keyCode)

- protected void keyPepeated(int keyCode)

- int getGameAction(int keyCode)

- Boolean hasPointerEvents()

- int getKeyCode(int gameAction)

- protected abstract void paint(Graphic g)

  • Canvas class can have a Ticker, cannot hold item and show list.Only Form class or its sub-classes can hold Item objects.
  • GameCanvas

    - int getKeyStates()

    - void flushGraphics({int x,int y,int width,int height})

    Does’t return until the flush has been completed. The contents of the off-screen buffer remain unmodified after the flushing operation.

    - protected Graphics getGraphics()

    - void paint(Graphic g)

  • A dedicated buffer is created for each GameCanvas instance. The buffer is initially filled with white pixels. The developer can assume that the contents of this buffer are modified only by calls to the Graphics object(s) obtained from the GameCanvas instance; the contents are not modified by external sources such as other MIDlets or system-level notifications.
  • When the GameCanvas becomes invisible, getKeyStates() returns 0. The visibility of the GameCanvas can be verfied by calling Displayable.isShown(), which would return false if the GameCanvas is invisible and vice versa. Once the GameCanvas becomes visible, it will initially indicate that all the keys are unpressed(0).
  • The GameCanvas class provides methods for immediate painting and for examining the state of the device keys. These new methods make it possible to enclose the entire functionality of a game in a single loop, under the control of a single thread.
  • TRANS_MIRROR Causes the Sprite to appear reflected about its vertical center
  • Transforms are applied to the original Sprite images; they are not cumulative, nor can they be combined.
  • The Sprite.defineCollisionRectangle(int x, int y, int w, int h) defines the Sprite’s bounding rectangle that is used for collision detection purposes.
  • A Sprite object has 7 transformations.
  • Calling the setImage(Image image, int frameWidth, int frameHeight) will cause a new frame set to be loaded into the Sprite.

    Ø If the new Image contains more frames than the current Image

    - The current frame remains unchanged.

    - If the defined frame sequence is a custom sequence, it remains unchanged. If it is default, the frame sequence will be reset to the default sequence of the NEW Image.

    Ø If the new Image contains less frames than the current Image

    - The current frame will be set to the 0th frame.

    - The frame sequence will be set to the default frame sequence of the new Image, regardless of whether the current frame seqeuence is default or not.

    Ø The reference pixel is unchanged in its definition as well as its location.

    - If the frame size is different, the top-left co-ordinate will be shifted such that the reference pixel will remain stationary.

    - If the frame size is different, the collision rectangle will be reset to the new size of the Sprite (which would be the size of the frame).

  • Sprite is been added in MIDP 2.0, Frame sequence of sprite class starts from 0, The developer must programatically switch the current frame in the frame sequence of Sprite in order to get animation affect.
  • When a transform is applied, the Sprite is automatically repositioned such that the reference pixel appears stationary in the painter's coordinate system. Thus, the reference pixel effectively becomes the center of the transform operation. Since the reference pixel does not move, the values returned by getRefPixelX() and getRefPixelY() remain the same; however, the values returned by getX() and getY() may change to reflect the movement of the Sprite's upper-left corner.
  • In Sprite class the frames have to be switched manually using the nextFrame() and prevFrame() methods. This switching is circular and so calling preFrame() on the first frame will give the last frame in the sequence and vice versa. The frame located in the upper-left corner of the Image is first assigned an index of 0. The remaining frames are then numbered consecutively in row-major order.

Ø The Layer appended will have the highest index (farthest from user).

Ø If the Layer is previously present, it will be removed.

Ø Start at 0

JAVA 認證心得 -- SCMAD (8)



  • StringItem(String label, String text)

StringItem(String label, String text, int appearanceMode)

appearanceMode - Item.PLAIN,



  • Public final boolean

- collidesWith(Sprite s, boolean pixelLevel)

- collidesWith(Image image, int x, int y, boolean pixelLevel)

- collidesWith(TiledLayer t, boolean pixelLevel)

pixelLevel : true to test for collision on a pixel-by-pixel basis, false to test using simple bounds checking

Any transforms applied to the Sprites are automatically accounted for.

  • The newly created Item default state

Ø The Item is not contained within ("owned by") any container.

Ø There are no Commands present.

Ø The default Command is null.

Ø The ItemCommandListener is null.

Ø the layout directive value is LAYOUT_DEFAULT;

Ø both the preferred width and preferred height are unlocked.

  • Same Ticker could be added to two different Displayable. Displayable.setTicker (Ticker t) is used to add Ticker to a Displayable. Displayable.AddCommand(Command c)
  • The label of a Spacer is restricted to always be null, and the application is not allowed to change it.
  • The primary purpose of a Spacer object is to position other items and is hence, non-interactive. And the application is not allowed to add Commands to a Spacer. The setDefaultCommand(Command cmd) method of the Spacer object will always throw an IllegalStateException.
  • Each MIDlet sub-class will be provided an instance of the Display object to control its display.
  • The maximum number of characters allowed in a TextBox is implementation dependent.


  • A TiledLayer can be rendered in two ways:

Ø By manually calling its paint(graphicsObject) method

Ø By using a LayerManager object

  • TiledLayer.fillCells(int col, int row, int numCols, int numRows, int titleIndex) throws IndexOutOfBoundsException, IllegalArgumentException
  • It is recommended that the contents of a Screen object be done when the Screen is not visible.
  • An application cannot set more than one Listener to a Displayable.
  • The index of TileLayer must start from 1, a tile index of 0 indicates that the cell is empty


  • ImageItem(String label, Image img, int layout, String altText, {int appearanceMode})

altText - the text that may be used in place of the image if the image exceeds the capacity of the display. It maybe null.

  • ImageItem.setImage(Image img)

img - the Image for this ImageItem, or null if none


  • The CustomItem subclass are responsible for calling Item.notifyStateChanged() to trigger notification of listeners that the CustomItem’s value has changed. And defining its dimensions.


  • The EXCLUSIVE constant in the Choice interface is used to define having exactly one element selected at time. (radio button)
  • The Choice.IMPLICIT type is valid only for the List implementation. The Choice.POPUP type is valid only for ChoiceGroup implementation.


  • Gauge update types have special meaning for non-interactive gauges with indefinite range.
  • Gauge(String label, boolean interactive, int maxValue, int initialValue)




  • High-Level-API : form, screen, item

    Low-Level-API : Canvas, Sprite, TiledLayer

  • The setLayout() method cannot be called on an item if it is within an Alert object.

JAVA 認證心得 -- SCMAD (7)

Push Registry


  • SMS and CBS are the valid protocols that support by Push Registry.
  • Push Registry supports CBS protocol but filtering is not performed.
  • The Push entries in the JAD file should have contiguous numbers and any break in the numbering will result in the entries after the break being ignored by the application.
  • When an application is registered for the message via Push Registry but is not running, when the message is received by the device the AMS will receive the message, start the application, and then deliver the message to the application.
  • MIDP 2.0 defines socket and datagram connection types for PushRegistry.
  • A Push Registered application can be actived using a TCP/IP Socket connection(stream-based connections), UDP Datagram Connection, CBS(packet-based connections), or an SMS Connection(Message-based connections). è IN WMA spec
  • The ConnectionNotFoundException exception is thrown when a protocol specified in the connection string for a Push Registry entry is not supported by the device.
  • The PushRegistry.getFilter(String connection) retrieves the registered filter for a requested connection as specified in the AllowedSender attribute of a MIDlet-Push-n attribute in DD.
  • The following attributes MUST be present in the Application Descriptor (JAD) or the manifest file of the JAR of the application.

If error, not be installed!!
  • An application can register itself for an alarm using the registerAlarm(String class, long time).

    Ø The class should be a MIDlet in the currently running MIDlet suite which is to be notified.

    Ø Upon receipt of an event, the class will be notified after the time expires.

    Ø At most, only one alarm can be registered per registry entry.

    Ø The MIDlet must be registered in the descriptor or the manifest file.

    Ø the time parameter is obtained using the Date.getTime() method

  • Datagram and Socket support for Push Registry is optional.
  • For SMS messages, the push address is the phone’s number(and port)
  • Class PushRegistry
  • public static String[] listConnections(boolean available)

    Return a list of registered connections for the current MIDlet suite.


    available - if true, only return the list of connections with input available, otherwise return the complete list of registered connections for the current MIDlet suite


    array of registered connection strings, where each connection is represented by the generic connection protocol, host and port number identification

  • public static long registerAlarm(String midlet, long time) throws ClassNotFoundException, ConnectionNotFoundException
  • public static void registerConnection(String connection, String midlet, String filter) throws ClassNotFoundException, IOException, ConnectionNotFoundException, IllegalArgumentException, SecurityException

JAVA 認證心得 -- SCMAD (6)

MIDP Persistent Storage


  • Public static RecordStore

openRecordStore (String recordName, boolean create)

openRecordStore (String recordName, boolean create, int authmode, boolean writable)

openRecordStore (String recordName, String vendor, String suite)

Ø Created if one is not already available

Ø Name cannot exceed 32 characters

Ø if recordStoreName is invalid throw an IllegalArgumentException

  • Authmode


1. means only the MIDlet suite that created the RecordStore can access the RecordStore.

2. Authorization to allow access only to the current MIDlet suite.

3. it has a value of 0.


1. Authorization to allow access to any MIDlet suites.

2. it has a value of 1

  • The owning MIDlet suite can always access the RecordStore and can set the authentication mode.
  • The record id is always a positive integer beginning from 1
  • Interface RecordListener

    void recordAdded(RecordStore store, int recordId)

    void recordChanged(RecordStore store, int recordId)

    void recordDeleted(RecordStore store, int recordId)

  • RecordStore.addRecordListener(RecordListener listener) can be used to register a listener to a RecordStore. Any number of listeners can be added to the RecordStore within memory limits
  • A record store is not thread-safe.
  • IllegalArgumentException exception will be thrown if the name passed while creating a record store is longer than 32 characters.
  • Interface RecordFilter

    - Boolean matches(byte[] candidate)

  • A record store is uniquely identified using a combination of its name and the MIDlet-Name and MIDlet-Vendor attribute values of the MIDlet that created the store.
  • A DataInputStream is used in conjunction with the ByteArrayInputStream to read various data types from a record in a record store while reading a record.


  • RecordEnumeration.destroy()
  • RecordEnumeration.reset() return the enumeration index to the same state as right after the enumeration was created.
  • RecordEnumeration.rebulid() recreation the internal indexes of the enumeration.
  • public interface RecordEnumeration

    An interface representing a bidirectional record store Record enumerator. The RecordEnumeration logically maintains a sequence of the recordId's of the records in a record store. The enumerator will iterate over all (or a subset, if an optional record filter has been supplied) of the records in an order determined by an optional record comparator.

  • public interface RecordFilter

    An interface defining a filter which examines a record to see if it matches (based on an application-defined criteria). The application implements the match() method to select records to be returned by the RecordEnumeration. Returns true if the candidate record is selected by the RecordFilter. This interface is used in the record store for searching or subsetting records. For example:

    RecordFilter f = new DateRecordFilter();

    if (f.matches(recordStore.getRecord(theRecordID)) == true)


JAVA 認證心得 -- SCMAD (5)

Application Model/ Delivery/Lifecycle/Provisioning

  • MIDP 2.0 compliant implementations

    Ø MUST support MIDP 1.0 and MIDP 2.0 MIDlets and MIDlet Suites.

    Ø MUST implement the OTA User Initiated Provisioning specification.

    Ø MUST provide support for accessing HTTP 1.1 servers.

    Ø MUST provide support for secure HTTP connections.

    Ø MUST support PNG image transparency.

    Ø MUST support Tone Generation in the media package.

    Ø MUST implement the mechanisms needed to support “Untrusted MIDlet Suites”.

    Ø SHOULD NOT allow copies to be made of any MIDlet suite unless the device implements a copy protection mechanism.

  • DataSource is not available in MIDP 2.0
  • public boolean Medlet.platformRequest (String URL) throws ConnectionNotFoundException

    URL - The URL for the platform to load. An empty string (not null) cancels any pending requests.

    This is a non-blocking method

    Does not handle multiple requests.

  • The correct ways to find the version of midp specification

    System.getProperty (“microedition.profiles”);

    Midlet.getAppProperty (”MicroEdition-profile”);

    microedition.hostname è get hostname

  • startApp() and destroyApp() can throw a MIDletStateChangeException
  • A SecurityException will be thrown if any class other than the AMS calls the no-argument constructor of a MIDlet or its sub-class
  • An application can initiate phone calls using the native phone application of the device by providing a telephone number in the form of the URL “tel://msisdn-number” by using the MIDlet.platformRequest() call
  • The MIDlet.platformRequest() method may be used to update a running MIDlet application.
  • MIDlet.resumeRequest() used by the application to let the AMS indicate that it would like to move to the active state.
  • If a connection gets terminated during transfer, the partially transferred MIDlet will be deleted automatically.
  • Only HTTP protocol is supported by the status report mechanism
  • If a cookie was returned when the application descriptor or MIDlet suite was retrieved, and the domain and path in the coookie match the URL in the MIDlet-Install-Nofigy attribute then the cookie MUST be included in the request header so that the server can indentify the installation which has been completed.
  • Persistent data of a MIDlet suite must be preserved when updating a MIDlet. The format, contents, and versioning of the RecordStores are the responsibility of the individual MIDlet suite.
  • It is mandatory for devices to support MIDlet updates.
  • If an attempt is made to install a MIDlet that is already installed in the device, the user SHOULD be notified.
  • During the download of a MIDlet suite, the HTTP request-headers used to fetch the content should include User-Agent, Accept-Language, and Accept. If supplied when requesting MIDlet suites, this header should include application/java and application/java-archive. For retrieving application descriptors, this header should include text/
  • If the platform has the appropriate capabilities and resources available, it SHOULD bring the appropriate application to the foreground and let the user interact with the content, while keeping the MIDlet suite running in the background. If the platform does not have appropriate capabilities or resources available, it MAY wait to handle the URL request until after the MIDlet suite exits. In this case, when the requesting MIDlet suite exits, the platform MUST then bring the appropriate application (if one exists) to the foreground to let the user interact with the content.

JAVA 認證心得 -- SCMAD (4)


  • Examples of valid URLs
  • ConnectionNotFoundException would be thrown only when the device does not provide implementation for the attempted connection type.
  • Class Connector

    public static Connection open(String url, {int mode}, {int timeout})

    - IllegalArgumentException - If a parameter is invalid.

    - ConnectionNotFoundException - If the requested connection cannot be make, or the protocol type does not exist.

    - IOException - If some other kind of I/O error occurs.

    - SecurityException – If the application does not have sufficient permissions.

    - InterruptedIOException – If the timeout parameter is true and a connection times out.

  • GCF provided by CLDC 1.1 at implement level, a minimum of one class is needed for implementing each supported protocol.
  • GCF API is a functional subset of the package.
  • The GCF defined by the CLDC Specification does not specify the actual supported network protocols or mandate implementations of any specific networking protocols.
  • If the associated streams are open, then Connection.close() will wait till they are closed. In this case, the Stream objects can be accessed, but accessing a method of the Connection interface (or its sub-interface) will throw IOException.
  • Closing an already closed connection has no effect. If newMessage() is called on a closed connection, this method always returns a Message instance irrespective of the type theat was passed in.
  • The SecurityInfo interface defines methods to access information about a secure network connection. Protocols that implement secure connections may use this interface to report the security parameters of the connection, such as protocol name, Server certificate, and Cipher suite name.
  • Interface ServerSocketConnection

    String getLocalAddress()

    Int getLocalPort()

  • Interface HttpConnection.

    Int getResponseCode()

  • The valid constants for opening a connection are

    Ø Connector.READ

    Ø Connector.WRITE

    Ø Connector.READ_WRITE (default mode)

  • In a CommConnection, if the requested baud rate is not supported on the platform, the system may use an alternate valid setting.
  • A CommConnection can specify the baud rate in two ways

    Ø Via the optional parameter “baudrate” in the connection String

    Ø Using the CommConnection.setBaudRate() method

  • The Datagram.receive() method is a blocking call.
  • HttpsConnection , SecureConnection <-> SecurityInfo getSecurityInfo()

    DatagramConnection <-> int getNominalLength(), int getMaximumLength()

    StreamConnectionNotifier <-> StreamConnection acceptAndOpen()

  • interface

    - getLength()->when sending, “length” is the number of bytes to send. Before receiving, “length” is the maximum number of bytes to receive. After receiving, “length” is the number of bytes that were received.

    Before writing on a datagram, its ”read/write pointer”, “offset”, and “length” has to be set to zero. This has to be done by calling reset() on the Datagram.

  • Datagram interface extends interfaces and Datagrams can be reused. Before reusing a datagram is to set back the “length” to the maximum using setLength as “Length” variable would have changed due to previous operations.
  • Http is a request-response protocol in which the parameters of request must be set before the request is sent.The connection exists in one of the following three states:

    Ø Setup, in which the request parameters can be set

    Ø Connected, in which request parameters have been sent and the response is expected.

    Ø Closed, the final state, in which the HTTP connection has been terminated.

  • There are six basic interface types that are address by the GCF

    Ø A basic serial input connection

    Ø A basic serial output connection

    Ø A datagram oriented connection

    Ø A circuit oriented connection

    Ø A notificaion mechanism to inform a server of client-sercer connections

    Ø A basic Web server connection

  • The CertificateException encapsulates an error that occurred while a Certificate is being used. If multiple errors are found within a Certificate the more significant error should be reported in the exception.
  • javax.microedition.pki.CertificateException
  • Class CertificateException

    - Certificate getCertificate()-> Get the Certificate that caused the exception

    - bye getReason() -> Get the reason code.

  • The valid identifiers for a particular device and OS can be queried through the method System.getProperty() using the key "microedition.commports". A comma separated list of ports is returned which can be combined with a comm: prefix as the URL string to be used to open a serial port connection. -> "comm:"[] ;