MIDlet-States für Anfänger

[german]Bei der recherche nach den MIDlet-States erstellte ich folgendes Programm. Vielleicht ist es für Andere ((Kommentare willkommen)) hilfreich. Außerdem fand ich folgende Dinge heraus:

  • Nokia 6300 (Symbian Series 40) kennt keinen pausierten Status für MIDlets
  • SonyEricsson K800i kann MIDlets pausieren (aus dem MIDlet und auch aus dem Telefon)
  • Wenn das K800i das MIDlet in den Hintergrund packt, werden weder pauseApp() noch startApp() aufgerufen – das Midlet läuft also vollständig im Hintergrund.
  • K800i kann nur dann wirklich pausieren, wenn man in der pauseApp() das currentDisplay auf null setzt (display.setCurrent(null);). Ein einfaches Aufrufen von notifyPaused() funktioniert nicht.
  • Suns Wireless Toolkit reagiert auf pauseApp() und notifyPaused() gleichermaßen.

[/german]
[english]While exploring the MIDlet-States i created the following program. Maybe it is useful ((Comments welcome *hint*)) for others. In writing the program the following peculiarities were found:

  • Nokia 6300 (Symbian Series 40) apparently does not know a paused-state
  • SonyEricsson K800i can pause MIDlets (either from the MIDlet itself or by the phone’s request)
  • If the telephone sets the midlet to paused state neither pauseApp() nor startApp() are called. Therefore the MIDlet runs the same way as if it was not paused.
  • K800i can only pause the MIDlet if you set the current display to null inside pauseApp() (display.setCurrent(null);). Simply calling notifyPaused won’t do the trick.
  • Suns Wireless Toolkit reacts to pauseApp() and notifyPaused().

[/english]

Download

Source-Files and compiled MIDlet as a zip-file (4KB)

StateChanges.java

import java.util.Timer;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

/**
 * DEMO-Midlet to try State-Changes initiated by AMS and User-interaction
 * Feel free to use and modify this.
 * @author http://amenthes.de
 * @link http://amenthes.de/
 * This is free code. Use, Change and redistribute it to your liking.
 */
public class StateChanges extends MIDlet implements CommandListener {
	// all my commands
	public static final Command PAUSEAPP = new Command("pauseApp",Command.SCREEN,40);
	public static final Command NOTIFYPAUSE = new Command("notifyPause",Command.SCREEN,40);
	public static final Command DESTROYAPP = new Command("destroyApp",Command.EXIT,40);
	public static final Command NOTIFYDESTROYED = new Command("notifyDestroyed",Command.EXIT,40);
	public static final Command STARTAPP = new Command("startApp",Command.ITEM,40);
	public static final Command RESUMEREQUEST = new Command("resumeRequest",Command.ITEM,40);

	// other stuff
	private Display display;
	private TextBox tb = new TextBox("State-Changes","",2000,TextField.ANY);
	private Timer timer = new Timer();

	protected static StateChanges sc = null;

	public StateChanges() {
		sc = this;
		display = Display.getDisplay(this);
		tb.addCommand(PAUSEAPP);
		tb.addCommand(NOTIFYPAUSE);
		tb.addCommand(DESTROYAPP);
		tb.addCommand(NOTIFYDESTROYED);
		tb.addCommand(STARTAPP);
		tb.addCommand(RESUMEREQUEST);
		tb.setCommandListener(this);
	}

	/*
	 * destroyApp, pauseApp and startApp are the abstract methods of MIDlet.
	 * They are called by your device (cellphone, for example). You can also
	 * call them in your application (as we do here with the commands)
	 *
	 * These functions should _prepare_ the state-change.
	 */
	protected void destroyApp(boolean unconditional) throws MIDletStateChangeException {
		addLine("destroyApp(" + unconditional + ") was called");
	}
	protected void pauseApp() {
		addLine("pauseApp was called");
		timer.schedule(new ResumeTask(this), 5000);
		display.setCurrent(null);
	}
	protected void startApp() throws MIDletStateChangeException {
		display.setCurrent(tb);
		addLine("startApp was called");
	}

	/*
	 * As you can see we prepare the state-change before actually notifying the AMS.
	 * you will see a difference in behaviour when calling the different
	 */
	public void commandAction(Command c, Displayable d) {
		if (c == PAUSEAPP) {
			pauseApp();
			notifyPaused();
		} else if (c == NOTIFYPAUSE) {
			notifyPaused();
		} else if (c == DESTROYAPP) {
			try{destroyApp(false);} catch (MIDletStateChangeException unhandled) {}
			notifyDestroyed();
		} else if (c == NOTIFYDESTROYED) {
			notifyDestroyed();
		} else if (c == STARTAPP) {
			try { startApp(); } catch (MIDletStateChangeException unhandled) {}
		} else if (c == RESUMEREQUEST) {
			resumeRequest();
		}
	}

	/**
	 * This function will give you output in two forms: on your Console (if you are running an emulator) and on the device's screen.
	 * @param line What text should be displayed?
	 */
	private void addLine(String line) {
		System.out.println(line);
		String current = tb.getString();
		tb.setString(current + "\n" + line);
	}
}

ResumeTask.java

import java.util.TimerTask;
import javax.microedition.midlet.MIDlet;

public class ResumeTask extends TimerTask {
	private MIDlet midlet;
	public ResumeTask(MIDlet parentMidlet) {
		super();
		midlet = parentMidlet;
	}
	public void run() {
		midlet.resumeRequest();
	}
}

3 Responses to “MIDlet-States für Anfänger”

  1. Franz says:

    Laut Wikipedia gibts kein “Symbian Series 40”, sondern nur “Nokia Series 40”, welches nur von Nokia ohne Symbian entwickelt wird

  2. Tatsache! Das war mir nicht bewusst. Ich habe die entsprechende Stelle geändert.

    Danke für den Hinweis

Leave a Reply


Author

Claudius Coenen is a tech-enthusiast. He's writing on all kinds of topics, including programming, technology, gadgets and media.

This site features his occasional articles, findings, documentations.

Categories

Connect

RSS Recent Bookmarks

Legal