Question

Reading some articles, told me that soft keys varies between devices. Some says -6 or -21 for left soft key and -7 or -22 for right soft key. Given this situation, is there any good wrapper or function or best practice to handle it properly?

If not possible for ALL devices, what is the best way to support most devices? with minor or no hack at all?

Was it helpful?

Solution

To give you a feel for the scope of the problem have a look at this table of keycodes.

Omermuhammed's approach is a good one if you are able to vary the JAD content depending on the target handset, for example by looking at the user-agent header field in a download request from an on-handset web browser.

If you cannot identify the handset until the app has been delivered, you could look at something like this that basically determines the host handset at run time and sets the keycode mappings appropriately. Looks cumbersome to me though.

Lastly, if your application uses a subset of codes you may be able to get away with hard-coded lists - for some codes there are no or few collisions (LEFT is usually either -3 or -61, and those codes usually don't mean something else). Again, not an ideal approach.

Final suggested resources for you: wurfl or user agent strings, and the J2MEPolish devices database for device keycodes.

OTHER TIPS

The easiest way I found was to set it up in code with the recommended values based on ITU-T standard and override it with a jad parameter. So, for any given app, it will look for existance of the jad parameter at app startup time and set it, otherwise it will use the default values.

I have used these and similar techniques to write apps that can be rapidly ported, and this process is generally well known.

Have to disagree completely with Martin Clayton above, something similar to this method of identifying host handsets at runtime is absolutely the right way to deal with this problem. And including one standard class to do this for you is FAR less cumbersome than faffing around with multiple JADs/JARs IMO.

This is the method I have created, which uses key codes and key names. I wrote this code about 10 years ago and back then it supported most devices. (One exception I found, however, was some Sagem models which have the -6 and -7 key codes the other way round! But you could probably work around that using the key names again - but you may need to obtain the user agent too.)

    private static final int SOFT_BUTTON_KEY_CODE_UNDEFINED = -999;
    private static int LEFT_SOFT_BUTTON_KEY_CODE = SOFT_BUTTON_KEY_CODE_UNDEFINED;
    private static int RIGHT_SOFT_BUTTON_KEY_CODE = SOFT_BUTTON_KEY_CODE_UNDEFINED;

    private boolean isLeftSoftButton(int keyCode) {

        // Try the standard code
        if (keyCode == -6) {
            return true;
        }
        // Try the code we have already detected
        else if (keyCode == LEFT_SOFT_BUTTON_KEY_CODE && LEFT_SOFT_BUTTON_KEY_CODE != SOFT_BUTTON_KEY_CODE_UNDEFINED) {
            return true;
        }
        // If we haven't yet detected the code...
        else if (LEFT_SOFT_BUTTON_KEY_CODE == SOFT_BUTTON_KEY_CODE_UNDEFINED) {
            // try to detect it
            String keyName = getKeyName(keyCode).toUpperCase();
            if (keyName.equals("SOFT1") || keyName.equals("LEFT SELECTION KEY") || keyName.equals("LEFT SOFTKEY") || keyName.equals("LEFT SOFT KEY") || keyName.equals("SOFTKEY 1") || keyName.equals("-6")) {
                // It's the left soft button! So remember the code for next time...
                LEFT_SOFT_BUTTON_KEY_CODE = keyCode;
                // Return true
                return true;
            }
            else {
                // keyName didn't match, so return false
                return false;
            }
        }
        else {
            // keyCode didn't match
            return false;
        }

    }

    private boolean isRightSoftButton(int keyCode) {

        // Try the standard code
        if (keyCode == -7) {
            return true;
        }
        // Try the code we have already detected
        else if (keyCode == RIGHT_SOFT_BUTTON_KEY_CODE && RIGHT_SOFT_BUTTON_KEY_CODE != SOFT_BUTTON_KEY_CODE_UNDEFINED) {
            return true;
        }
        // If we haven't yet detected the code...
        else if (RIGHT_SOFT_BUTTON_KEY_CODE == SOFT_BUTTON_KEY_CODE_UNDEFINED) {
            // try to detect it
            String keyName = getKeyName(keyCode).toUpperCase();
            if (keyName.equals("SOFT2") || keyName.equals("RIGHT SELECTION KEY") || keyName.equals("RIGHT SOFTKEY") || keyName.equals("RIGHT SOFT KEY") || keyName.equals("SOFTKEY 4") || keyName.equals("SOFTKEY 2") || keyName.equals("-7")) {
                // It's the right soft button! So remember the code for next time...
                RIGHT_SOFT_BUTTON_KEY_CODE = keyCode;
                // Return true
                return true;
            }
            else {
                // keyName didn't match, so return false
                return false;
            }
        }
        else {
            // keyCode didn't match
            return false;
        }

    }

Updated code, based on http://www.iteye.com/topic/179073 ...

private static final int SOFT_BUTTON_KEY_CODE_UNDEFINED = -999;
private static int LEFT_SOFT_BUTTON_KEY_CODE = SOFT_BUTTON_KEY_CODE_UNDEFINED;
private static int RIGHT_SOFT_BUTTON_KEY_CODE = SOFT_BUTTON_KEY_CODE_UNDEFINED;

private boolean isLeftSoftButton(int keyCode) {

    // Try the standard codes
    //     standard   ||    Motorola    ||    Siemens    ||   Motorola 2   ||   Motorola 1
    if (keyCode == -6 || keyCode == -21 || keyCode == -1 || keyCode == -20 || keyCode == 21) {
        return true;
    }
    // Try the code we have already detected
    else if (keyCode == LEFT_SOFT_BUTTON_KEY_CODE && LEFT_SOFT_BUTTON_KEY_CODE != SOFT_BUTTON_KEY_CODE_UNDEFINED) {
        return true;
    }
    // If we haven't yet detected the code...
    else if (LEFT_SOFT_BUTTON_KEY_CODE == SOFT_BUTTON_KEY_CODE_UNDEFINED) {
        // try to detect it
        String keyName = getKeyName(keyCode).toUpperCase();
        if (keyName.equals("SOFT1") || keyName.equals("LEFT SELECTION KEY") || keyName.equals("LEFT SOFTKEY") || keyName.equals("LEFT SOFT KEY") || keyName.equals("SOFTKEY 1") || keyName.equals("-6")) {
            // It's the left soft button! So remember the code for next time...
            LEFT_SOFT_BUTTON_KEY_CODE = keyCode;
            // Return true
            return true;
        }
        else {
            // keyName didn't match, so return false
            return false;
        }
    }
    else {
        // keyCode didn't match
        return false;
    }

}

private boolean isRightSoftButton(int keyCode) {

    // Try the standard codes
    //     standard   ||    Motorola    ||    Siemens    ||   Motorola 1
    if (keyCode == -7 || keyCode == -22 || keyCode == -4 || keyCode == 22) {
        return true;
    }
    // Try the code we have already detected
    else if (keyCode == RIGHT_SOFT_BUTTON_KEY_CODE && RIGHT_SOFT_BUTTON_KEY_CODE != SOFT_BUTTON_KEY_CODE_UNDEFINED) {
        return true;
    }
    // If we haven't yet detected the code...
    else if (RIGHT_SOFT_BUTTON_KEY_CODE == SOFT_BUTTON_KEY_CODE_UNDEFINED) {
        // try to detect it
        String keyName = getKeyName(keyCode).toUpperCase();
        if (keyName.equals("SOFT2") || keyName.equals("RIGHT SELECTION KEY") || keyName.equals("RIGHT SOFTKEY") || keyName.equals("RIGHT SOFT KEY") || keyName.equals("SOFTKEY 4") || keyName.equals("SOFTKEY 2") || keyName.equals("-7")) {
            // It's the right soft button! So remember the code for next time...
            RIGHT_SOFT_BUTTON_KEY_CODE = keyCode;
            // Return true
            return true;
        }
        else {
            // keyName didn't match, so return false
            return false;
        }
    }
    else {
        // keyCode didn't match
        return false;
    }

}`

MIDP defines the following constant for the keys of a standard ITU-T keypad: KEY_NUM0, KEY_NUM1, KEY_NUM2, KEY_NUM3, KEY_NUM4, KEY_NUM5, KEY_NUM6, KEY_NUM7, KEY_NUM8, KEY_NUM9, KEY_POUND, and KEY_STAR. Applications should not rely on the presence of any additional key codes. In particular, upper- and lowercase or characters generated by pressing a key multiple times are not supported by low-level key events. A "name" assigned to the key can be queried using the getKeyName() method.

AFAIR the getKeyName method returned quite the same on most phones so it was quite reliable, but I haven't written anything in j2me since about 2 years ago, so my memory might play tricks.(you have been warned)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top