Just An Application

March 27, 2011

“No MIDlet-<n> registration” ?

Filed under: Java, JME, Meta, MIDlets, MIDP, Push Registration — Tags: , , , , — Simon Lewis @ 9:36 am

This is another in the occasional series of meta or recursive posts prompted by the appearance of a specific query in the list of search terms used by people who have ended up here, despite the fact that I have not written about it.

In this case the query is the gnomic

No MIDlet-<n> registration

It looks as though it is probably an error message and it turns out that it is.

Like the subject of this post, it originates in the company formerly known as SUN‘s MIDP implementation.

If you do this at runtime

    PushRegistry.registerConnection("socket://:8888", "xper.midlet.Lamiel", "*")

but the only thing in the JAD and/or JAR manifest of your MIDlet suite is this

    MIDlet-1: UsefulMIDlet, UsefulMIDletIcon.png, xper.midlet.Colgrevance

and you are using the TCFKAS MIDP implementation then you will get a ClassNotFoundException with the message

    No MIDlet-<n> registration

even if the MIDlet suite JAR contains the class xper.midlet.Lamiel

Why ?

Because, as it says, in the documentation

The named MIDlet MUST be registered in the application descriptor or the JAR manifest with a MIDlet-<n> record.

Adding something like this

    MIDlet-2: PushableMIDlet, PushableMIDletIcon.png, xper.midlet.Lamiel

to the JAD and/or JAR manifest of the MIDlet suite in the example above would fix the problem.

The same problem, but not the same error message, occurs with static registration.

If the JAD and/or JAR manifest of the MIDlet suite only specifies these attributes

    MIDlet-1: UsefulMIDlet, UsefulMIDletIcon.png, xper.midlet.Colgrevance
    MIDlet-Push-1: socket://:8888, xper.midlet.Lamiel, *

then the MIDlet suite will not install.

As before, the second MIDlet needs to be registerd

    MIDlet-1: UsefulMIDlet, UsefulMIDletIcon.png, xper.midlet.Colgrevance
    MIDlet-2: PushableMIDlet, PushableMIDletIcon.png, xper.midlet.Lamiel
    MIDlet-Push-1: socket://:8888, xper.midlet.Lamiel, *

Note that the ordinals of the

    MIDlet-<n>

and

    MIDlet-Push-<n>

attributes do not have to match, they identify the attributes not the MIDlets.


Copyright (c) 2011 By Simon Lewis. All Rights Reserved.

March 18, 2010

MIDP 3.0 On Maemo 5: A TabbedPane And Some Lists … Again

Filed under: Java, JME, LCDUI, Maemo, MIDlets, MIDP, MIDP3, MIDP3LCDUI, Mobile Java, Qt — Tags: , , , , , , , — Simon Lewis @ 1:43 pm

It’s that MIDlet again. This time running on the Maemo5 emulator. The implementation code is identical to the Symbian version with vanilla Qt being used as the LCDUI back-end.





Copyright (c) 2010 By Simon Lewis. All Rights Reserved.

March 17, 2010

MIDP 3.0 On Symbian: A TabbedPane And Some Lists

Filed under: Java, JME, LCDUI, MIDP, MIDP3, MIDP3LCDUI, Nokia, Qt, Symbian — Tags: , , , , , , , — Simon Lewis @ 9:02 am

Here’s the SimpleTabbedPaneMIDlet again, this time running on the N97 emulator. The only difference between this and the Android version is that the LCDUI backend is implemented using vanilla Qt rather than Android widgets.




Copyright (c) 2010 By Simon Lewis. All Rights Reserved.

March 5, 2010

MIDP 3.0 On Android: Notifications

Filed under: Android, Java, JME, LCDUI, MIDP, MIDP3, MIDP3LCDUI — Tags: , , , , , , — Simon Lewis @ 12:04 pm

Notifications are another new feature in MIDP 3 for which there is some usefully equivalent functionality in Android, namely Notifications ! or more specifically

    android.app.Notification

and

    android.app.NotificationManager

Below is a very simplistic MIDlet which demonstrates the basic use of Notifications. Of course, in reality a MIDlet would actually be doing something which would cause it emit Notifications. In the case of the Missed Call Notification type that I am using in the example, it might be doing some actual telephony, although that is a bit unlikely since as far as I am aware neither JSR 253 nor 304 have ever been shipped. Anyway, here’s the MIDlet



import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Notification;
import javax.microedition.lcdui.NotificationListener;
import javax.microedition.lcdui.NotificationType;

import javax.microedition.midlet.MIDlet;

public final class SimpleNotificationMIDlet
                   extends
                       MIDlet
                   implements
                       NotificationListener,
                       Runnable
{
    public void destroyApp(boolean ignore)
    {
    }
	
    public void startApp()
    {
        primaryDisplay = Display.getDisplays(0)[0];
        new Thread(this).start();
    }
	
    //
	
    public void notificationDismissed(Notification theNotification)
    {
        primaryDisplay.setCurrent(new Alert("Notification Dismissed", null, null, AlertType.INFO));
    }
	
    public void notificationSelected(Notification theNotification)
    {
        primaryDisplay.setCurrent(new Alert("Notification Selected", null, null, AlertType.INFO));
    }
	
    public void notificationTimeout(Notification theNotification)
    {
        primaryDisplay.setCurrent(new Alert("Notification Timeout", null, null, AlertType.INFO));
    }
	
    public void run()
    {
        try
        {
            missedCall("+44 1234567890");
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
	
    private void missedCall(String theCaller)
    {
        Notification n = new Notification(NotificationType.CALL);
		
        n.setListener(this);
        n.setLabel("Missed call from " + theCaller);
        n.post(true, 60000);
    }
	
    //
	
    private Display	primaryDisplay;
}


Here’s the Notification immediately after it has been posted. For a couple of seconds it takes over the entire status bar.

Here’s the Notification once the status bar re-appears. For the misleadingly named Call NotificationType, which is actually the Missed Call NotificationType, I am using the generic Missed Call icon as shipped with Android.

Here’s the expanded view which is shown when the status bar is pulled down

And that’s it really. At this point the user can either click on the Notification or ignore it, and a MIDlet can either update the Notification or remove it.

In the example MIDlet, if you select the Notification in the expanded view, this happens

If you hit the clear button in the expanded view, this happens

If you just sit and wait then eventually this happens.

There is one feature of Android Notifications which is not demonstrated above, and that is the ability to associate a number with a Notification, in which case you get this

There is no API for doing this in MIDP 3, but the specification does explicitly permit an implementation to group together Notifications of the same type. so in theory a single Android Notification could be used to represent a number of MIDP 3 Notifications, with the number of Notifications being displayed in the icon, as above.

In practice there is no way for the implementation to know the intended semantics of any single MIDP 3 Notification and consequently whether it would be appropriate to group it with other Notifications of ostensibly the same type, or whether doing so is simply going to end-up badly confusing the user. There is also an issue with how to handle the display of a group of MIDP 3 Notifications in the expanded view of a single Android Notification. Although the view is customizable this is done using something RemoteViews which have fairly circumscribed functionality.


Copyright (c) 2010 By Simon Lewis. All Rights Reserved.

March 1, 2010

MIDP 3.0 On Android: A TabbedPane And Some Lists

Filed under: Android, Java, JME, LCDUI, MIDP, MIDP3 — Tags: , , , , , , — Simon Lewis @ 11:59 am

I first wrote about running MIDlets on Android a bit over two years ago (see here). At that point there was one fairly fundamental obstacle to running MIDlets on Android which I didn’t mention at the time, which was the presence in Android of stubbed out versions of some javax.lcdui classes. As there were also no publicly available functioning ClassLoaders the only way to get a MIDlet using LCDUI to run was to modify it at the source level to use a shadow version of LCDUI. That is what I did, but it is also why I didn’t do anything more.

Since then the mysterious javax.lcdui class stubs have disappeared and publicly available ClassLoaders have appeared. Although these implementation level obstacles have been removed, there are still some impedance mismatches between MIDP and Android. At a high-level there are differences in the provisioning, security, and application models. At a very low-level there is the use of Dex and Dalvik. At an intermediate level there is, for example, the contrast between the use of static resources to build Android application UIs and the more or less dynamic construction of UI elements using LCDUI.

Having said that, if you have a 99.9% pure Java MIDP 3 implementation, which happily I do, it is possible to get MIDP 3 MIDlets running on Android 2.1, albeit with a judicious amount of hacking,

This is a very simple MIDlet which uses the new MIDP 3 TabbedPane


import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.TabbedPane;

import javax.microedition.midlet.MIDlet;

public final class SimpleTabbedPaneMIDlet
                   extends
                       MIDlet
                   implements
                       CommandListener
{
    public void destroyApp(boolean ignore)
    {
    }
	
    public void startApp()
    {
        List exclusive = new List(
                                 "Exclusive", 
                                 Choice.EXCLUSIVE, 
                                 new String[] { "One", "Two", "Three", "Four", "Five" }, 
                                 null);
        List implicit   = new List(
                                  "Implicit",  
                                  Choice.IMPLICIT,  
                                  new String[] { "Foo", "Bar", "Baz" }, 
                                  null);
        List multiple  = new List(
                                  "Multiple",  
                                  Choice.MULTIPLE,  
                                  new String[] { "Up", "Down", "Left", "Right" }, 
                                  null);
		
       exclusive.setCommandListener(this);
       implicit.setCommandListener(this);
       multiple.setCommandListener(this);
		
       TabbedPane tp = new TabbedPane("TabbedPane", true, false);
		
       tp.addTab(exclusive, null);
       tp.addTab(implicit, null);
       tp.addTab(multiple, null);
       Display.getDisplays(0)[0].setCurrent(tp);
    }
	
    //
	
    public void commandAction(Command theCommand, Displayable theDisplayable)
    {
        System.out.println("SimpleTabbedPaneMIDlet.commandAction(" + theCommand + ", " + theDisplayable + ")" );
    }
}


and this is what it looks like running on the emulator.



This MIDlet illustrates quite nicely the difference between constructing a UI in Android and in MIDP. At first glance it looks as though the class

       android.widget.TabHost

is a straight correlate of

    javax.microedition.lcdui.TabbedPane

However, if you simply construct an instance of TabHost programatically using the one arg constructor, and then and start trying to add tabs to it, it doesn’t work. You get some helpful exceptions, and once you’ve worked out how to fix those, a very unhelpful NullPointerException, at which point there is nothing for it except to resort to the source code of TabHost.

It turns out that it is possible to create a functioning instance of TabHost programatically, see above, but the expectation is that it will actually be created by inflating it from a layout resource, which is fair enough, it is certainly a lot easier to do it that way.


Copyright (c) 2010 By Simon Lewis. All Rights Reserved.

December 17, 2009

What’s New In MIDP 3.0: Redux – &rest

Filed under: Java, JME, MIDP, MIDP3 — Tags: , , , — Simon Lewis @ 12:51 pm

And that is it. Those are the only substantive changes that have been made since the proposed final draft that I have managed to find.

I did consider producing a post detailing the changes corresponding to each of my original posts but that would simply result in a string of posts saying

Changes Since Proposed Final Draft

None

Issues

As before

and I am not feeling sufficiently Samuel Beckett like for that kind of thing at the moment.

All the other issues I have raised are apparently not really issues after all, or they are still there. I guess we’ll just have to wait and see.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

What’s New In MIDP 3.0: Redux – Security For MIDP Applications

Filed under: Java, JME, MIDP, MIDP Security, MIDP3, MIDP3Issues — Tags: , , , , , — Simon Lewis @ 12:35 pm

Changes Since Proposed Final Draft

The Security For MIDP Applications chapter, now only available as chapter six of the PDF version of the documentation, has acquired an entirely new section entitled Combined usage of MIDP 2.0 and MIDP 3.0 security models

This states that a MIDP 3.0 MIDlet Suite can use both the new

  • MIDlet-Permission-<n>, and
  • MIDlet-Permission-Opt-<n>

attributes, and the legacy MIDP 2.0

  • MIDlet-Permissions, and
  • MIDlet-Permissions-Opt

attributes.

Similarly a LIBlet can use the use

  • LIBlet-Permission-<n>, and
  • LIBlet-Permission-Opt-<n>

attributes, and the newly defined

  • LIBlet-Permissions
  • LIBlet-Permissions-Opt

attributes.

This addition is presumably motivated by the fact that currently the vast majority of auxiliary MIDP compliant JME JSRs have not been updated to define fine-grained permissions for use with MIDP 3.0.

Issues

Underspecification

The new section says nothing more than that the attributes can all be used together. As such the feature is a tad underspecified. There are a number of possible use cases which need to be addressed. For example

  1. Can a MIDP 3.0 MIDlet Suite use only the legacy attributes ?

  2. Can a MIDP 3.0 MIDlet Suite use named permissions to request fine-grained permissions ?

Runtime Named Permission Checking

Although a MIDP 3.0 MIDlet Suite can now request named permissions, as the specification stands, at runtime, a MIDlet contained in such a MIDlet Suite has no way of checking the named permissions since it cannot use the deprecated MIDlet.checkPermission(String) method. The specification still
states that

For MIDP 3.0 applications, calling checkPermission throws an exception.

Legacy MIDlet Suites Can Use Either Pair Of Attributes But Not Both

The section entitled Security for MIDP 2.x MIDlet Suites, which is now only available as Section 9.2.2 of the PDF version of the documentation has not been changed.

It still states that

  • If there exists one or more instances of the MIDlet-Permission-<n> or MIDlet-Permission-Opt-<n> attribute in the JAD or JAR Manifest, then the Permission classes associated with these attribute values MUST be used, and any instances of MIDlet-Permissions or MIDlet-Permissions-Opt MUST be ignored.

  • If there exists no instances of MIDlet-Permission-<n> or MIDlet-Permission-Opt-<n> attribute in JAD or JAR Manifest, then the following MIDP 2.0 specific attributes MUST be processed when they appear in the JAD or JAR Manifest :

    • MIDlet-Permissions — attribute contains a list of one or more permissions. Multiple permissions are separated by a comma (Unicode U+002C). Leading and trailing whitespace (Unicode U+0020) and tabs (Unicode U+0009) are ignored. The permissions are critical to the function of the MIDlet suite and it will not operate correctly without them.
    • MIDlet-Permissions-Opt — attribute contains a list of one or more permissions. Multiple permissions are separated by a comma (Unicode U+002C). Leading and trailing whitespace (Unicode U+0020) and tabs (Unicode U+0009) are ignored. The permissions are not critical to the function of the MIDlet suite and it will operate correctly without them.

The motivation for defining this functionality was never entirely obvious. As it stands a MIDP 2.x MIDlet Suite can continue to use named permissions in which case it can also use any MIDP compliant auxiliary JME JSR, or use fine-grained permissions in which case it can only use those MIDP compliant auxiliary JME JSRs which have defined fine-grained permissions. Currently, it is diffcult to see why any developer would make the second choice

Given that an implementation now has to support a hybrid fine-grained/named permission model for MIDP 3.0 MIDlet Suites it is unclear why it cannot support it for MIDP 2.x MIDlet Suites as well. Either that or not allow them to use the MIDP 3.0 permissions in the first place.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

December 16, 2009

What’s New In MIDP 3.0: Redux – LCDUI – Notification

Filed under: Java, JME, MIDP, MIDP3, MIDP3Issues, MIDP3LCDUI, Mobile Java — Tags: , , , , , , — Simon Lewis @ 10:28 pm

Original Post

Changes Since Proposed Final Draft

Removing the NotificationListener via the Notification.setListener(NotificationListener) method no longer removes the Notification as well.

This eliminates the inconsistency between its behaviour and the documentation describing the Notification life-cycle which I noted in the original post.

Issues

The other minor issues noted in my original post still exist.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

What’s New In MIDP 3.0: Redux – LCDUI – Fonts

Filed under: Java, JME, MIDP, MIDP3, MIDP3Issues, MIDP3LCDUI — Tags: , , , , , , — Simon Lewis @ 5:07 pm

Original Post

Changes Since Proposed Final Draft

Font.FONT_IDLE_TEXT and Font.FONT_IDLE_HIGHLIGHTED_TEXT

Links fixed to point at the right versions of the static getFont method, i.e.,

    Font.getFont(int)

Font.createFont(InputStream)

Scope of the Font created is now limited to the MIDlet that created it.

Implementations MUST insure that the availability and use of fonts created using createFont method is limited to the execution environment of a [sic] MIDlet that instantiated the font.

Changed from MIDlet Suite.

Font.getFont(String,int,int), Font.getFont(int,int,int) AndFont.deriveFont(int,int)

Documentation for all three methods has been updated to explicitly specify that the constant STYLE_UNDERLINED is supported in their respective style arguments.

The specification of the static method Font.getStyle(String) however, has not been updated to match. Possibly it does not need to be. Who knows ?

Font.hashCode()

Font now has a hashCode, which of course it should since it over-rides the equals method.

Unfortunately how the hash code should be computed is apparently a secret, since all the specification says is

the hashcode is computed from the font face name, style, pixelSize, ascent and descent

Issues

None apart from the secret hash code algorithm and that only affects implementors.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

What’s New In MIDP 3.0: Redux – LCDUI – Command Layout

Filed under: Java, JME, LCDUI, MIDP, MIDP3, MIDP3Issues, MIDP3LCDUI — Tags: , , , , , , — Simon Lewis @ 10:49 am

Original Post

Changes Since Proposed Final Draft

javax.microedition.lcdui.Display

The following has been added to the end of the Exact Placement of Commands section
of the Display class documentation.

On each callback of CommandLayoutPolicy.onCommandLayout(Displayable), implementation MUST first disassociate Command and Menu
with their respective previous placements. At the beginning of each callback of CommandLayoutPolicy.onCommandLayout(Displayable) method,
Displayable.getCommand(int) or Displayable.getMenu(int) will return null for every placement.

As I said in my original post

  1. The specification does not contain an explicit definition of the state of a Display’s placements when the onLayout(Displayable)[sic] method is called, that is, whether Commands and/or Menus previously placed on the current Display by the Displayable are still present or whether all Commands and/or Menus must be explicitly placed each time the method is called. This makes implementing the method perhaps more interesting than it ought to be.

Well now it does. Every time you layout a Displayable’s Commands you start with a clean slate.

javax.microedition.lcdui.Displayable

The setCommand(Command,int) method no longer throws an IllegalArgumentException when the placement

is associated with a placement that does not support commands

possibly because it is actually not possible for a placement not to support Commands.

It is hard to be sure because the Item.setCommand(Command,int) method will apparently still throw an IllegalArgumentException when the placement

is associated with a placement that does not support commands

The CommandLayoutPolicy Example

The CommandLayoutPolicy now looks like this. Actually it doesn’t because I have re-formatted it. In Chrome, Firefox and Safari the formatting is all over the place, as it is in the PDF version.


class MyCanvas extends Canvas implements CommandLayoutPolicy {
    MyCanvas() {
        setCommandLayoutPolicy(this);
    }

    void sort(Command[] commands, int[] positions) {
        // sort the commands in the correct order depending on the positions available.
        // Implementation can use Display's getCommandPreferredPlacements to get the recommended 
        // placement for each Command.
    }
 
    public void onCommandLayout(Displayable displayable) {
        Display display = displayable.getCurrentDisplay();
      
        final int border = Display.SOFTKEY_BOTTOM;
     
        int[] positions = display.getExactPlacementPositions(border);
     
        int numOfPositions = positions.length;
           
        Command[] cmd = displayable.getCommands();
     
        sort(cmd, positions);
     
        if (cmd.length <= numOfPositions) {
            for (int i = 0; i < cmd.length; ++i) {
                displayable.setCommand(cmd[i], positions[i]);
            }
        } else {
            for (int i = 0; i < numOfPositions ; ++i) {
                displayable.setCommand(cmd[i], positions[i]);
            }
       
            int[] menuSupportedPlmts = display.getMenuSupportedPlacements();
            if( menuSupportedPlmts != null ) {
                Menu options = new Menu("More", null, null);
                // first add the remaining commands in the Menu
                for (int i = numOfPositions; i < cmd.length; ++i) {
                    options.append(cmd[i]);
                }
                // Get the first preferred placement of Menu
                int menuPlmt = menuSupportedPlmts[0];
                // check if this placement already occupied by Command
                if( displayable.getCommand(menuPlmt) != null ) {
                    //add the existing Command in Menu, otherwise the existing
                    // Command will be removed from the Displayable according to
                    //setMenu() method
                    //
                    options.append(displayable.getCommand(menuPlmt));
                }
                displayable.setMenu(options, menuPlmt);                    
            }
        }    
    }
 }

This is an improvement on the previous version which was flat-out broken. Note that it still doesn’t check the return value of the call to Display.getExactPlacementPositions(int).

Issues

The changes above are the only ones that I have found. Of the original issues I raised they address two if you are being charitable.

  1. What is the state of the Displayable with respect to Command layout when the CommandLayoutPolicy.onCommandLayout(Displayable) method is invoked ? It is a clean slate

  2. Can there be placements which do not support Commands ? Probably not.

Everything else is still up for grabs. Developers, assuming there are going to be any, are going to have to try it and see what happens, and then hope it happens the same way everywhere, which is the past has not been a guaranteed recipe for success.

Possibly if somebody had attempted to write a real-world example for the specification the Command layout feature itself would have been better specified. The example provided effectively does no more than provide the existing default behaviour.


Copyright (c) 2009 By Simon Lewis. All Rights Reserved.

Older Posts »

Create a free website or blog at WordPress.com.