Key Codes

When you use the MIDP Canvas class, you can listen for key-press events by implementing methods such as keyPressed and keyRepeated. The platform calls these methods with a “keycode” argument that tells you which key was pressed. The key code isn’t always useful since the key code values vary from device to device. For example, the pound key # has key code 35 on my Sagem my700x, but the same key might have a different key code value on another handset. The Canvas class provides the getGameAction method that allows you to identify which key the key code corresponds to for a number of familiar keys.

Unfortunately, there are some fairly standard keys that the Canvas game action constants won’t help you to identify, notably the left and right soft-keys. If you’d like to listen for soft-key events, it can be very tricky. Setting up your MIDlet to identify the key codes on a device-by-device basis is already a lot of work, and the difficulty is compounded by the fact that for a lot of devices the key code mapping is hard to find published anywhere. Sony Ericsson has posted a developer guide which lists the complete key-mapping chart (on page 36). Many others don’t.

Googling around the Internet, I couldn’t find a key mapping chart for my Sagem my700x. But there’s one way to find out!! Write a MIDlet that will check. :D

My “KeyCode” MIDlet (code below the fold) is a simple MIDlet that listens for key-press events and displays the corresponding key code on the screen. This exercise is a little like my earlier exercise to write a MIDlet that will tell me what optional APIs are available on the handset. One difference is that all of the information about the optional APIs (plus a bunch of other stuff about the handset’s capabilities) can be gathered automatically, without any input from the user. But for the key-mapping, I can’t think of any way of getting the information from the handset without having the user physically press the different keys and see which key codes are generated. That’s probably why MobileZoo doesn’t provide key-mapping information for the handsets in its database even though the key-mapping is useful for developers.

The result for the Sagem my700x? It had exactly the same key codes as the Sony Ericsson key-mapping except that the soft-keys were reversed: on the Sagem, the left soft-key is -7 and the right soft-key is -6. The WTK emulator has the same key-mapping as Sony Ericsson as well, which is probably not a coincidence. Still, since the soft-keys are among the keys that don’t have standard constants, it’s kind of annoying that those are precisely the ones that are less predictable…

Here’s the code for a simple MIDlet to get the key-mapping from your handset:

The MIDlet class KeyCode.java:

package net.frog_parrot.test;

import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

/**
* A simple MIDlet to display the Key Codes of the handset.
*/
public class KeyCode extends MIDlet {

public void startApp() {
KeyCodeCanvas kcc = new KeyCodeCanvas(this);
Display.getDisplay(this).setCurrent(kcc);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
}

public void quit() {
notifyDestroyed();
}

}

And here’s the corresponding Canvas class KeyCodeCanvas.java:

package net.frog_parrot.test;

import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

/**
* A canvas that displays the key code corresponding to the
* key pressed.
*/
public class KeyCodeCanvas extends Canvas {

private KeyCode myMIDlet;
private String myCurrentCode = “none”;
private boolean myPoundPressed = false;

/**
* just set a handle back to the MIDlet.
*/
public KeyCodeCanvas(KeyCode midlet) {
myMIDlet = midlet;
}

/**
* Paint the key code corresponding to the key
* that has been pressed.
*
* Note that this is far from optimized!!!
*/
public void paint(Graphics g) {
// get the size of the painting region:
int width = getWidth();
int hcenter = width / 2;
int height = getHeight();

// clear the screen by coloring everything white:
g.setColor(0xffffff);
g.fillRect(0, 0, width, height);

// write the instructions at the top in black:
g.setColor(0×000000);
Font font = g.getFont();
int fontHeight = font.getHeight();
g.drawString(“to exit”, hcenter, 0,
Graphics.TOP|Graphics.HCENTER);
g.drawString(“press # twice”, hcenter, fontHeight + 1,
Graphics.TOP|Graphics.HCENTER);

// Now draw the key code number:
g.drawString(myCurrentCode, hcenter, 2*(fontHeight + 1),
Graphics.TOP|Graphics.HCENTER);

}

/**
* Record the keycode.
*/
public void keyPressed(int keyCode) {
// check for the pound key, and if this is
// the second pound in a row, quit:
if(keyCode == Canvas.KEY_POUND) {
if(myPoundPressed) {
myMIDlet.quit();
return;
} else {
myPoundPressed = true;
}
} else {
myPoundPressed = false;
}
// Now set the key code:
myCurrentCode = (new Integer(keyCode)).toString();
// Now display it:
repaint();
}

}

As usual, you can download the MIDlet onto your handset from my mobile game page.

About these ads

16 comments so far

  1. Brandon on

    It’s a useful article.
    Thank for your valuable information.

  2. carolhamer on

    Thanks, glad it was helpful!!! :D

  3. aman on

    thanks,its simply superb.

  4. jhodgski on

    Cheers – useful bit of code.

    For anyone else that might find it useful to detect the keyName, add the following code (in the obvious places):

    String myCurrentName;
    myCurrentName = getKeyName(keyCode);
    g.drawString(myCurrentName, hcenter, 3*(fontHeight + 1), Graphics.TOP|Graphics.HCENTER);

  5. Ivan on

    Very interesting article. I want to detect key presses in order to select immediately some operations from the Options, i.e. pressing key #1 would choose the operation #1 in the options menu. Using method getGameAction(int keyCode) we receive an integer for every key press. Is it normal to have the following results:
    1 -> 9
    2 -> 0
    3 -> 10
    4 -> 0
    5 -> 0
    6 -> 0
    7 -> 11
    8 -> 0
    9 -> 12
    0 -> 0
    * -> 0
    # -> 0

    Is it normal to receive back these numbers as game actions?

  6. jhodgski on

    If you want to detect number 0-9 button presses, for reliability on various devices you should be using keyCode (as the API specifies the associated values) not gameActions which are related to soft button and FIRE button, etc. presses.

  7. carolhamer on

    jhodgski — thanks for answering Ivan’s question.

  8. Mr. D on

    There are only the .jad files on the download page. Would you upload the .jar files please? Thanks in advance

  9. carolhamer on

    Are you sure? I’ve double-checked, and the jar files are there. It’s possible that the problem is that I’m using a relative path to them rather than an absolute path (URL in the jad).

    Anyone else having a problem with this?

  10. lynx on

    The jars are up, yes. But for usability you should either make, two links (one for the jad, one for the jar) or put them both in .zip file.

    You have one dl-link but two files atm. how should that work?

  11. vishal on

    Useful stuff !

    have been trying to get the softkey on WTK2.5.1 Generic/MediaControlSkin working when i use the fullscreen=”true” more in J2ME polish .. no luck :(
    any pointers ?
    i have added a cutom device with all the capabilities of mediacontrolskin + the soft key mapping… but to no avail.
    (i used the midlet above to confirm the key mapping as well)

    anyone with a solution ?

    thanks

  12. carolhamer on

    Vishal — did you look at my post about J2ME Polish?

    I got the softkeys to work (on a device that didn’t have key codes by default) by adding “hasCommandKeyEvents” to the the “features” element of the device.

  13. thesis on

    i think i have the same problem with mr. d!
    Here’s the error:
    com.sun.kvem.midletsuite.InvalidJadException: Reason = 36
    Error in opening jar file: KeyCode.jar

  14. Glen Thomas on

    Carol, where are the execuable JAR files for the games and other MIDlets on your game download page? The links are only for the Java Application Descriptor (JAD) files.

  15. carolhamer on

    Hi Glen — I just added links to the jar files, and I’m really sorry it took me so long to get around to doing it.

    thesis — I’m not sure what reason 36 might be, but if you’re running it on the WTK emulator, you can download the jar file to your local machine and from there run the jar file in the emulator.

  16. Ryan on

    Tip: To get soft keys to work add this to the KeyCodeCanvas constructor:

    setFullScreenMode(true);

    This makes every key on the nokia 6300 work (except the generic exit application red button). Without this you can’t even detect the d-pad selection key.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: