Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
601,27 KB
Nội dung
122 MIDP 2.0 AND THE JTWI for (int i=0; i < connections.length; i++) { if(connections[i].equals(“sms://:1234”)){ new Thread(){ public void run(){ Receiver.openReceiver(); } }.start(); } } } One other use of the push registry should be mentioned before we leave this topic. The PushRegistry class provides the register- Alarm() method: public static long registerAlarm(String midlet, long time) This allows a running MIDlet to register itself or another MIDlet in the same suite for activation at a given time. The midlet argument is the class name of the MIDlet to be launched at the time specified by the time argument. The launch time is specified in milliseconds since January 1, 1970, 00:00:00 GMT. The push registry may contain only one outstanding activation time entry per MIDlet in each installed MIDlet suite. If a previous activation entry is registered, it will be replaced by the current invocation and the previous value returned. If no previous wakeup time has been set, a zero is returned. 3.3.5.3 The Push Registry and the Security Model The PushRegistry is a protected API and, as such, a signed MIDlet suite which registers connections statically or contains MIDlets which register connections and/or alarms, must explicitly request the javax.microedition.io.PushRegistry permission in its MIDlet-Permissions attribute, for example: MIDlet-Permissions: javax.microedition.io.PushRegistry, Note that a signed MIDlet suite must also explicitly request the per- missions necessary to open the connection types of any connections it wishes to register either statically or dynamically. If the protection domain to which the signed MIDlet suite would be bound grants, or potentially grants, the requested permission, the MIDlet suite can be installed and the MIDlets it contains will be able to register and deregister connections, and register alarms, either automatically, or with user permission, depending on the security policy in effect. MIDP 2.0 123 Untrusted MIDlets do not require a MIDlet-Permissions entry. Whether access is granted to the Push Registry API will depend on the security policy for the untrusted protection domain in effect on the device. On the Sony Ericsson P900/P908 and Nokia 6600, MIDlets in untrusted MIDlet suites can use the Push Registry APIs (Application Auto-Invocation function group) with user permission. On both the 6600 and the P900/P908, the default user permission is set to session. On the Nokia 6600, the default value can be changed by the user to oneshot or disal- lowed. For the Sony Ericsson P900/P908, the security policy in effect for MIDlets in MIDlet suites bound to the trusted protection domain allows automatic access to the Push Registry API. 3.3.5.4 Symbian’s Implementation At the time of writing, the current version of Symbian OS, Version 7.0s, supports the following connection types in its implementation of the MIDP 2.0 push architecture: • Server socket • Datagram • SMS. In Symbian’s implementation, all connections that can be registered as push connections are managed by the system AMS, even if they are not requested to be push-enabled by an application. In the case of server connections that spawn off a connected stream due to an incoming connection, the stream connections are also maintained through the system AMS. Future releases of Symbian OS are likely to increase the types of connections supported by the push architecture to include Bluetooth, L2CAP and RFCOMM connections. 3.3.6 Additions to the LCDUI 3.3.6.1 A Quick Tour The MIDP 2.0 specification introduces a number of new features to the LCDUI toolkit which are designed to give developers more control over their application’s user interface. In this section we briefly look at some of them. Display MIDP 2.0 introduces two useful new methods to the Display class which allow MIDlets to control the screen backlight and the vibration of the phone: 124 MIDP 2.0 AND THE JTWI public boolean flashBackLight(int duration) public boolean vibrate(int duration) The duration of the effect is specified by the duration parameter – a value of zero causes the action to stop. The return value is false if the relevant feature is not supported by the phone. Form MIDP 2.0 introduces a new layout algorithm for arranging items in a Form. The layout algorithm arranges items in rows according to a layout direction defined by the implementation for the language con- vention in use. For European and North American markets the default layout direction will be left to right. The layout algorithm then arranges items from left to right and starts a new row when there is insuffi- cient space in the row to accommodate the next Item. The layout algorithm uses the concept of current alignment. For an implementa- tion with a left to right layout direction the initial current alignment is Item.LAYOUT_LEFT. Other possible values for the current alignment are Item.LAYOUT_RIGHT and Item.LAYOUT_CENTER. The current alignment changes when the layout algorithm encounters an Item with a (horizontal) layout value other than the current setting (the layout direc- tive for an Item is set using the setLayout() method). When this happens, the layout algorithm adds that Item on a new row and uses the new alignment value until an Item with a different horizontal directive is encountered. Vertical layout directives provided are Item.LAYOUT_TOP, Item. LAYOUT_BOTTOM and Item.LAYOUT_VCENTER. These are used to indi- cate the required vertical alignment of an Item within the current row. MIDP 2.0 added the getPreferredWidth(), getPreferred- Height(), getMinimumWidth() and getMinimumHeight() meth- ods to the Item class. These are used by the form layout algorithm to position and size Items within rows. In addition a MIDlet can influence the size of an Item by using the Item.LAYOUT_EXPAND, Item.LAYOUT_VEXPAND and Item.LAYOUT_SHRINK and Item. LAYOUT_VSHRINK directives. When filling a row, the layout algorithm first adds each Item accord- ing to its preferred width (or minimum width, if the LAYOUT_SHRINK directive is set). Once the row has been filled, any remaining space is proportionately distributed amongst the items by expanding their widths. Any Item with the LAYOUT_SHRINK directive set is expanded to no more than its preferred size and then any remaining space is taken up expanding Items with the LAYOUT_EXPAND directive set. The height of a row is determined by the tallest Item in the row. The height of an Item is determined by its preferred height (unless the LAYOUT_VSHRINK directive has been set, in which case initially the MIDP 2.0 125 minimum height is used). Once the height of the row has been determined, any Item shorter than the row height that has its LAYOUT_VEXPAND directive set is expanded to the height of the row. Any Item with its LAYOUT_VSHRINK directive set is expanded to its preferred size or the height of the row, whichever is shorter. Finally, any Item with vertical directives (LAYOUT_TOP, LAYOUT_BOTTOM or LAYOUT_CENTER)setis positioned accordingly in the row. Remaining items with no vertical directive are positioned at the bottom of the row. It is possible to force a row break using setLayout(Item.LAYOUT_ NEWLINE_BEFORE) and setLayout(Item.LAYOUT_NEWLINE_ AFTER). In the first case, the item will be added on a new row. In the second case, a row break will occur immediately after the item that called the method. Note that for backward compatibility with MIDP 1.0, TextField, DateField, Gauge and ChoiceGroup items are always positioned with a row to themselves unless the Item.LAYOUT_2 directive has been set. Item MIDP 2.0 introduces new features into the Item class including: • support for the new layout algorithm with new directives defined as public static final int (see above) • the addCommand() method; an item can have commands associated with it • the setItemCommandListener() method • the getMinimumHeight(), getMinimumWidth(), getPre- ferredHeight()and getPreferredWidth() methods. It also introduces new public static final int appearance modes: • BUTTON indicates the item is to appear as a button • HYPERLINK indicates the item is to appear as a hyperlink • PLAIN indicates the item is to have a normal appearance. CustomItem This is a new class introduced in MIDP 2.0 that can be sub-classed to create new visual elements for use in Forms. StringItem MIDP 2.0 introduces a new constructor to the StringItem class that creates a StringItem with the indicated appearance mode: PLAIN, BUTTON,orHYPERLINK. public StringItem(String label,String text,int appearanceMode) 126 MIDP 2.0 AND THE JTWI ItemCommandListener A listener type introduced in MIDP 2.0 for receiving notification of commands that have been invoked on Item objects. Spacer A new class introduced in MIDP 2.0 representing a blank Item with a settable minimum size whose primary purpose is to position other items. Choice New features introduced in MIDP 2.0 to the Choice interface include: • static int POPUP • static int TEXT_WRAP_DEFAULT • static int TEXT_WRAP_OFF • static int TEXT_WRAP_ON • deleteAll() • getFitPolicy() • getFont() • setFitPolicy(int fitPolicy) • setFont(int elementNum, Font font). 3.3.6.2 Exploring the LCDUI: the KeyPad Example Rather than exploring the new features of the LCDUI API by API, we will instead discuss an example MIDlet that illustrates some of the features. For a more thorough exposition of the LCDUI APIs, the reader is referred to Sun’s MIDP 2.0 documentation. We will use as the example a simple numeric keypad. Screenshots of our KeyPad MIDlet running on the Series 60 and UIQ reference designs are shown in Figure 3.7. The KeyPad MIDlet consists of two classes: the KeyPad class extends MIDlet and provides the main UI in the guise of a Form instance; and the Button class extends CustomItem and models a simple button. The Button instances are appended to the Form to create our keypad. First, let’s consider the KeyPad class: import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.*; public class KeyPad extends MIDlet implements CommandListener { private Display display; private Form container; private Command exit; MIDP 2.0 127 Figure 3.7 The KeyPad MIDlet on Series 60 and UIQ. private Command clear; private TextField field; public KeyPad() { display = Display.getDisplay(this); container = new Form(""); clear = new Command("CLEAR",Command.SCREEN,1); exit = new Command("EXIT",Command.EXIT,1); container.addCommand(exit); container.addCommand(clear); container.setCommandListener(this); Button one = new Button(this, "1"); Button two = new Button(this, "2"); Button three = new Button(this, "3"); Button four = new Button(this, "4"); Button five = new Button(this, "5"); Button six = new Button(this, "6"); Button seven = new Button(this, "7"); Button eight = new Button(this, "8"); Button nine = new Button(this, "9"); Button zero = new Button(this, "0"); field = new TextField(null,null,32,TextField.UNEDITABLE); int bheight = one.getPrefContentHeight(-1); int bwidth = one.getPrefContentWidth(-1); 128 MIDP 2.0 AND THE JTWI container.append(new Spacer (container.getWidth(),bheight/2)); container.append(new Spacer (bwidth/2, bheight)); container.append(one); container.append(new Spacer (bwidth/2, bheight)); container.append(two); container.append(new Spacer (bwidth/2, bheight)); container.append(three); container.append(new Spacer (container.getWidth(),bheight/4)); container.append(new Spacer (bwidth/2, bheight)); container.append(four); container.append(new Spacer (bwidth/2, bheight)); container.append(five); container.append(new Spacer (bwidth/2, bheight)); container.append(six); container.append(new Spacer (container.getWidth(),bheight/4)); container.append(new Spacer (bwidth/2, bheight)); container.append(seven); container.append(new Spacer (bwidth/2, bheight)); container.append(eight); container.append(new Spacer (bwidth/2, bheight)); container.append(nine); container.append(new Spacer (bwidth/2, bheight)); container.append(zero); container.append(new Spacer (container.getWidth(),bheight/2)); container.append(field); } public void setString(String s) { String current = field.getString(); field.setString(current.concat(s)); } public void commandAction(Command c, Displayable d) { if(c == exit) { notifyDestroyed(); } else if(c == clear) { field.setString(""); } } public void startApp() { display.setCurrent(container); } public void pauseApp() { MIDP 2.0 129 } public void destroyApp(boolean unconditional) { } } The main work is done in the constructor. We create the Form,plus a couple of Command instances. We add the commands to the form and set the CommandListener. Then we create various instances of our Button and a TextField to display the output of the button presses. We append the Button instances to the Form, separated by instances of the Spacer class, plus the TextField instance. We implement a setString() callback method that is invoked by a Button instance, taking the button’s label as its parameter. Finally, we implement the commandAction() method mandated by the CommandListener interface, which our KeyPad class implements. Now let’s look at the Button class: import javax.microedition.lcdui.*; public class Button extends CustomItem{ private static final int HEIGHT = 20; private static final int WIDTH = 20; private static final int DELTA = 2; private String num; private KeyPad pad; public Button(KeyPad pad, String num){ super(""); this.pad = pad; this.num = num; } protected void paint(Graphics g, int w, int h){ g.setColor(0, 0, 0); g.fillRect(0, 0, WIDTH+DELTA, HEIGHT+DELTA); g.setColor(128, 128, 128); g.fillRect(0, 0, WIDTH-DELTA, HEIGHT-DELTA); int xOffset = WIDTH/3; int yOffset = 2*HEIGHT/3; g.setColor(255, 255, 255); g.drawString(num, xOffset, yOffset, Graphics.BASELINE | Graphics.LEFT); } protected int getPrefContentHeight(int width) { return getMinContentWidth(); } protected int getPrefContentWidth(int height) { return getMinContentHeight(); } protected int getMinContentHeight() { 130 MIDP 2.0 AND THE JTWI return HEIGHT; } protected int getMinContentWidth() { return WIDTH; } protected void pointerPressed(int x, int y) { pad.setString(num); } public void keyPressed(int keyCode){ int gameAction = getGameAction(keyCode); if (gameAction == Canvas.FIRE){ pad.setString(num); } } } The constructor takes as arguments the KeyPad instance, to facilitate a callback, and a String acting as the button label. The paint() method must be implemented to render the CustomItem. In the example code above we have produced a minimal button, leaving it as an exercise to the reader to add the embellishments. We must also implement the getPrefContentWidth(), getPrefContentHeight(), getMin- ContentWidth() and getMinContentHeight() methods inherited from CustomItem; here we have provided trivial implementations. An attractive feature of CustomItem is the optional support for pointer input, via the protected pointerPressed(), pointerDragged() and pointerReleased() methods. The Button class redefines the pointerPressed() method to provide support for touch screen user interfaces such as Symbian’s UIQ. Of course, we could have adopted a simpler approach to our keypad. Instead of providing a custom Button class extending CustomItem we could have simply used StringItem instances with appearanceMode set to Item.BUTTON: public StringItem (String label, String text, int appearanceMode) We would then add a Command to the StringItem to take appro- priate action when it is selected and implement an ItemCommandLis- tener on each StringItem instance, as shown below: public class KeyPad extends MIDlet implements CommandListener, ItemCommandListener{ public KeyPad() { StringItem button1 = new StringItem(null, “1”, Item.BUTTON); MIDP 2.0 131 button1.setDefaultCommand(new Command(“Select 1”, Command.Item, 1)); button1.setItemCommandListener(this); form.append(button1); } public void commandAction(Command command, Item item) { StringItem button = (StringItem)item; setString(button.getText()); } } We adopted the CustomItem approach for our keypad example for two reasons: it provides an opportunity to illustrate the use of CustomItem, and its inherent support for touch screens; and the par- ticular variant of StringItem shown above was subject to a defect on the original Nokia 6600 firmware release (but should be fixed in future upgrades). 3.3.7 The Game API 3.3.7.1 Introduction The MIDP 1.0 specification, though limited in many respects, proved a big hit with the gaming fraternity. The vast majority of MIDlets developed so far are games. As mentioned briefly in Chapter 2, the MIDP 2.0 specification extends support for games developers with the introduction of the javax.micro- edition.lcdui.game package. We will now discuss programming this API in more detail. The aim of the API is to facilitate richer gaming content by providing a set of APIs, targeted at games developers, that map directly to native functionality, taking advantage of the performance enhancements offered by native code and minimizing the amount of work required in pure Java code. The game package contains the following classes: • GameCanvas • LayerManager • Layer • Sprite • TiledLayer. In the next few sections we shall look at the functionality offered by these classes, illustrating some of the key concepts with sample code. [...]... javax.microedition.media.control Specifically, the Media API mandates support for tone generation and audio playback of WAV files Support for other audio formats is optional Symbian s MIDP 2. 0 Media API implementation, at the time of writing, does not provide support for additional optional audio formats However, licensee phones built on Symbian OS may provide support for additional audio formats, particularly... javax.microedition.midlet.*; javax.microedition.lcdui.*; javax.microedition.rms.*; java. io.*; class RMSWriter extends MIDlet implements CommandListener { private static final String IMAGE_NAME = "/image.png"; private static final int IMAGE_SIZE = 1 122 2; private Display display; private Form form; private Command exitCommand; private Command startCommand; private Command saveCommand; private ImageCanvas imageCanvas; private byte[]... phones However, Symbian OS devices like the Psion netBook and the Nokia 921 0 were already providing a PersonalJava Application Environment with AWT graphics, audio playback support and color screens MIDP 1.0 was not sufficiently attractive to present itself as an alternative Java runtime environment for Symbian OS phones It is interesting to note here that no Symbian OS phone has shipped without the MIDP. .. 1.0 Java functionality being complemented either directly by additional multimedia functionality or else by inclusion of a PersonalJava Application Environment Even the Nokia 7650, which provided one of the least feature-rich Java runtime environments among Symbian OS phones, extended the basic MIDP 1.0 specification with custom Nokia extension classes A sound package allowed playing of several audio... panned view, is listed below: import import import public javax.microedition.lcdui.*; javax.microedition.lcdui.game.*; java. io.*; class TiledLayerCanvas extends Canvas implements Runnable { private Image image; private int x; private int y; MIDP 2. 0 135 private TiledLayer layer; public TiledLayerCanvas(String imageName) throws ApplicationException { //create the image try { image = Image.createImage(imageName);... www .symbian. com/books The DemoRacer case study, discussed in Chapter 5, provides a further detailed study of programming the Game API, including using collision detection Figure 3.17 The LayerManagerDemo MIDlet MIDP 2. 0 145 3.3.8 The Media API As mentioned in Chapter 2, MIDP 2. 0 introduces support for audio playback and sound generation in two new packages: • javax.microedition.media • javax.microedition.media.control... blending to progressively render a semi-transparent red mask over a background image: import import import public javax.microedition.midlet.*; javax.microedition.lcdui.*; java. io.*; class AlphaCanvas extends Canvas implements Runnable { private Image backgroundImage; private int[] maskArray; private int imageWidth; private int imageHeight; private int x; private int y; private int maskHeight = 0; public AlphaCanvas(String... backgroundLayer = new TiledLayer (2, 1, backgroundImage, TILE_WIDTH, TILE_HEIGHT); backgroundLayer.setCell(0,0,1); backgroundLayer.setCell(1,0,1); layerManager = new LayerManager(); layerManager.append(sprite); layerManager.append(backgroundLayer); //set layer position relative to LayerManager origin // this is the default anyway sprite.setPosition(0, 0); 1 42 MIDP 2. 0 AND THE JTWI //this is the default anyway... byte[] data; public RMSWriter(){ data = loadImage(IMAGE_NAME, IMAGE_SIZE); display = Display.getDisplay(this); Image image = Image.createImage(data, 0, data.length); MIDP 2. 0 imageCanvas = new ImageCanvas(image); form = new Form("RMS Writing Demo"); exitCommand = new Command("Exit", Command.EXIT, 2) ; startCommand = new Command("Start", Command.SCREEN, 1); saveCommand = new Command("Save image", Command.SCREEN,... import javax.microedition.lcdui.*; import javax.microedition.lcdui.game.*; import java. io.*; public class SpriteCanvas extends Canvas implements Runnable { private static final int SPRITE_WIDTH = 140 ; private static final int SPRITE_HEIGHT = 140 ; private private private private Sprite plane; int spritePositionX; int spritePositionY; boolean running = false; public SpriteCanvas(String imageName) throws ApplicationException . code. 1 32 MIDP 2. 0 AND THE JTWI 3.3.7 .2 GameCanvas A basic game user interface class extending javax.microedition. lcdui.Canvas, GameCanvas provides an offscreen buffer as part of the implementation. final int appearance modes: • BUTTON indicates the item is to appear as a button • HYPERLINK indicates the item is to appear as a hyperlink • PLAIN indicates the item is to have a normal appearance. CustomItem This. and models a simple button. The Button instances are appended to the Form to create our keypad. First, let’s consider the KeyPad class: import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.*; public