This article will describe the tools and processes I used to quickly develop something for a J2ME-enabled phone. There are many great tutorials out there, but I wanted to focus on rapid IDE-based development. The article documents the building of a little app using Sun's Java Studio Mobility.
I commute to my office every day. I definitely don't work nine to five - I often have to stay in late, but from time to time I can also come in later than usual, so I need a schedule to plan the travel on a daily basis. I don't like to carry around the schedule sheet with me, in fact I lose it frequently, so I wanted to have the schedule on something that's always with me. That's my mobile phone, a Nokia 6600, J2ME/MIDP 2.0-enabled Symbian OS-based device.
I could have created a WAP or HTML page with the schedules, but just to connect to the GPRS network, and to navigate to the page would take too much time, and it'd cost me money as I don't have a flat rate for the GPRS service. So I got a reasonably small goal that allows me to play with the J2ME environment, and to get a feel for the frameworks and tools.
When checking out the platform, I have found tools which I would use on a proper development project, for example a set of Ant tasks and tools for the J2ME platform, and some Eclipse plugins, but for this small application I just wanted to find a quick and full-featured IDE. An IDE allows me to focus on the application logic and the using the frameworks, instead of configuring descriptors, build processes, downloading and configuring separate libraries, and packaging the MIDlet.
There are a couple of IDEs targeted for J2ME development, for example Borland's JBuilder Mobile Studio, but I've selected Sun's own Mobility IDE because it was a smaller package (70 MB compared to the 603 MB Borland download), and had a 60 day evaulation period, where JBuilder has a 30 day trial.
Download the Mobility 6 2004Q3 Early Access build from here:
Other than a JDK to run the IDE, you don't really need anything else. The required SDKs, and even the API docs are installed and available within the IDE.
I've still downloaded separately the two relevant API docs, basically to make sure that I have the latest available version.
CDLC, MIDP 2.0 API docs:
It's definitely not a goal of this article to present the architecture and the capabilities of the J2ME platform. I used various sources to get a grasp on the technology:
The Sun J2ME site, on http://java.sun.com/j2me , where the specifications and reference implementations are hosted. For J2ME development, the CLDC API and the MIDP API should be studied.
Also on the Sun J2ME site, there are specific "Learning Paths" for J2ME, walking through the relevant APIs.
I've skimmed through a book called " J2ME The Complete Reference". The book certainly aims to be a complete reference. Maybe even too complete, as it wastes a large number of pages explaining everything from J2SE, J2EE, and even has several pages about radio technology.
Essentially the CLDC (Connected Limited Device Configuration) API must be understood as this defines the language and basic framework elements for our Midlet application.
This is how SUN defines it:
“The Connected Limited Device Configuration (CLDC) defines the base set of application programming interfaces and a virtual machine for resource-constrained devices like mobile phones, pagers, and mainstream personal digital assistants. When coupled with a profile such as the Mobile Information Device Profile (MIDP), it provides a solid Java platform for developing applications to run on devices with limited memory, processing power, and graphical capabilities”.
For the User Interface of the application, we need to understand the Mobile Information Device Profile (MIDP) API.
The SUN definition is:
“The Mobile Information Device Profile (MIDP) is a key element of the Java 2 Platform, Mobile Edition (J2ME). When combined with the Connected Limited Device Configuration (CLDC), MIDP provides a standard Java runtime environment for today's most popular mobile information devices, such as cell phones and mainstream personal digital assistants (PDAs).”
Once I had a basic understanding of these APIs, I jumped into the implementation.
After launching the Mobility IDE, we're greeted with a familiar interface. The IDE is based on NetBeans (version 3.6) foundations.
I did have some previous experience with NetBeans, so I had no trouble starting up the project. First I've created a folder in the filesystem (manually, outside NetBeans), and then I've mounted the filesystem in the left-hand section of the IDE. This folder will contain the project's files.
Then I've used the "New" Wizard in the File menu, where the MIDP folder contained the "Midlet suite" item, which contains all the basic project elements, like a MIDlet (which displays a simple string for testing), and the JAD/Manifest files.
If you open the MIDP class in the editor, the "Launch" button is enabled in the toolbar, and the MIDlet is running in a phone emulator right away. For some reason they went with an extremely ugly skin for the emulator.
Now that we have a project we can compile, build, and deploy in the emulator environment, let's design and implement the Midlet suite.
I have three main classes, representing a Model/View/Controller design.
I have the MIDlet class itself, which contains a main Canvas to draw the view.
The MIDlet's control events will invoke methods on a Controller class.
The Controller assembles and returns a Display Model object which has everything that's required for the view to draw the screen.
The MIDlet view class has the responsibility to draw the UI elements on the screen. There are two main options to draw the mobile screens. The first option is to work with a form-driven display, basically to assemble forms from standard fields. The layout mechanisms are not fully configurable - it's pretty much up to the device specific MIDP implementation to decide on the layout. The other alternative is to get a Canvas from the MIDlet, and then custom-draw the elements on it.
I wanted to make an application which I can demonstrate to non-technical people as well, so I planned to use graphical elements on the screen, and I wanted to control the layout process as much as possible. This pretty much means that I had to go with the Canvas-based custom-drawn screen.
This is the layout I came up with:
The left side of the screen contains a set of graphical icons representing the direction of the trip, and two other elements which define the schedule of my bus: the season and the part of the week (working week or weekend).
The right side displays the current time, and the next two buses leaving from the selected direction, If the bus leaves before a configured time period (it takes me 35 minutes to get from my workplace to the bus station for example), then the time is highlighted in red.
Below these screen elements, there's a menu which allows the change of direction, season, etc.
Because of the simplicity of the application, the controller also contains the very simple "business logic" of the application, and holds the references to the arrays containing various schedules as well, instead of just focusing on the Controller logic.
I wanted to make sure that for testing I don't have to launch the emulator and use the UI controls, so I made sure that the class is easy to test. I don't have any reference to any J2ME specific package in this class, so I can test this code in a normal Java environment, and also I can reuse it in a non-J2ME environment, for example in a J2EE webapp. There are J2ME-specific unit testing tools, but going with a straight Java class seemed to be the best solution.
I've used JUnit to test the functionality of the application. I've created test methods for every functional element in it, and I've used the built-in JUnit runner in the IDE to execute them. I'm pretty fond of the test runner in Eclipse, I prefer the nice visual feedback of the green "success" bar instead of the simple text output of NetBeans/Java Studio, so I actually did most of the Controller development in Eclipse instead.
The Model class is just a simple JavaBean. It contains accessors to attributes, which will be displayed on the screen. It contains the formatted time, schedule information, and the location of the active icons on the screen.
After getting the application done, I've just taken the JAR file generated from the IDE during a build, and I've sent it to my mobile through my laptop's infrared port. Initially it failed to install, with an "Invalid version" error message. I did know that my mobile supports MIDP 2.0, which was selected in the MIDP Project Configuration window of the IDE, so I switched from the CLDC 1.1 option to CLDC 1.0, and the application installed and worked flawlessly.
I had no problems reinstalling and removing the application from the phone, everything worked just fine. The only annoyance I've noticed is that startup time was very slow, sometimes I clicked twice on the icon because I thought that I've failed to launch it. I guess even if the application is small, it takes a certain amount of time to launch the VM, on this 100 MHz machine.
Altogether it took me about a day to read up some of the documents, install the environment, and to develop the application. Most of the time was spent on actually figuring out the logic, and to enter all the bus schedules. For every J2ME question I had, I was able to quickly locate the relevant documentation using the API docs and Google. It was not a frustrating experience, although it took me a while to get used to the limited subset of the standard Java API which is available in CLDC and MIDP. For a professional project, there are a lot of additional aspects, like device-specific APIs, Bluetooth, network support, but it was certainly fun to implement this little J2ME project.