Just An Application

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.

Advertisements

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.

Blog at WordPress.com.

%d bloggers like this: