Developing Mobile Clients

03 August 2006
EdgeBuilder SDK

A mobile client is usually an application running on a smart phone or other mobile device that supports internet connectivity. There are a wide range of mobile devices on the market, and a number of programming environments for those devices. If non-mobile client access is also required, EdgeClick clients can also be web applications deployed within a web browser, or standalone PC applications.

Whichever mobile device and application programming environment you choose, the bottom line is a client must be able to send and receive HTTPS messages, as described in the following section.



The Message Protocol

In order to write your first service, you need to understand how clients interact with the EdgeClick Processor (ECP). The primary protocol used is HTTPS. HTTPS is ubiquitous and supported by any client environment. When clients want to communicate with the ECP, they construct a POST that contain name/value pairs. For example, when a client logins, it sends a POST with a Body that looks like this:

app_code=6&app_version=_test&username=EdgeClickAdmin&password=scoTest&CMD=9

Let's break it down:

After the ECP processes this command, it will send back a response to the client. The response could be name/value pairs or an entire XML document. For example, when the Shout application wants to download new messages it sends:

user_id: [2]
User-Agent: [Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.12) Gecko/20050915]
app_version: [_test_]
CMD: [407]
app_code: [6]
external_command: [false]

Again, app_code 6 represents the Shout service. CMD 407 opcode is defined as CMD_RETRIEVE_VOICE_LIST. After the Shout service deployed under the ECP consumes and processes the command, it returns:

<return><code>0</code><messages></messages></return>

The <return> body for CMD_RETRIEVE_VOICE_LIST consists of a return code via the <code> tag and any new Shout messages via the <messages> tag. In this case, the command was successful with a return code of zero and there were no new messages to retrieve. Part of writing a service is defining the commands a client will send and the return message body the ECP will generate.



Technology Choices

Development of the mobile client portion of an EdgeClick application is dependent upon the mobile device being used. EdgeClick applications have been successfully developed and deployed on mobile phones using four different development technologies:

The mobile client portion of an application typically concerns itself with Forms or other GUI presentations to collect or report information, and then communicates with the ECP as discussed above.

Certain functions common to all EdgeClick mobile clients are implemented in supplied libraries for common implementation languages, such as authentication and provisioning (including self-updating of new versions of the code), or currently can be reused from sample code.


Developing Windows Mobile .NET Clients

The EdgeClick .NET 2.0 API provides a set of C# classes and methods that allow a Windows Mobile or Windows Desktop application to authenticate and communicate with the EdgeClick processor, accessing the EdgeClick services. It is provided as a set of Microsoft .NET Compact Framework 2.0 assemblies for use on Windows Mobile phones and Microsoft .NET Framework 2.0 assemblies for use on Windows desktops and servers (win32).

It consists of five main pieces, each one a separate assembly:

The Account Manager

The Account Manager object (App.AccountMgr) is responsible for maintaining the account database, authenticating accounts and ensuring an authenticated account exists before an EdgeClick client application is allowed to execute..

The Account Manager will load and execute before your application executes and if an authenticated account does not exist, it will present the user with a form to create and authenticate an account with the EdgeClick Processor.

Although multiple accounts can be created an authenticated, only one can be active at one time. The Account List form allows the user to specify which is the current account, as well as add, modify, delete accounts. The current account's details are accessible via the AccountMgr.CurrentAccount property.

The Group Manager

The Group Manager object (App.GroupMgr) is responsible for maintaining the group and contact database, synchronizing that database with the server, management, and providing recipient lists.

Once initialized, it caches the entire list of groups and contacts in memory. When the group or contacts selection forms are called, members of the cache are marked as selected. To obtain the selected groups or contacts, use the GroupMgr.CheckedGroups and GroupMgr.CheckedContacts properties respectively.

The selected groups or contacts can be cleared without flushing the cache via the ClearCheckedContacts and ClearCheckedGroups methods.

Constructing an EdgeClick .NET client application

There are five basic requirements for creating an EdgeClick .NET client application:

  1. Referencing the EdgeClick API
  2. Inheriting the AccountManager so that the user will automatically be required to create an EdgeClick account and authenticate it before they can proceed to use your application
  3. Defining some required global values for your application, such as its name and version number
  4. Adding some optional EdgeClick menu items to your application's main menu, for handling EdgeClick-specific items such as accounts and groups.
  5. Sending commands that do the work of your application to the EdgeClick processor and parsing the results.

Referencing the EdgeClick API

Add references to the EdgeClick assemblies to your project:

 EdgeClick.Utility.dll
EdgeClick.Net.dll
EdgeClick.Accounts.dll
EdgeClick.Groups.dll [if your app utilizes groups/contacts]
System.Data.SQLite.dll [if your app needs an SQL database]

Add using references for the EdgeClick namespaces to your code:

 using EdgeClick;
using EdgeClick.Utility;
using EdgeClick.Net;
using EdgeClick.Accounts;
using EdgeClick.Groups;
using System.Data.SQLite;

Inherit the AccountManager

Your application's main form should inherit from EdgeClick.Accounts.AppMainForm:

 public partial class myMainForm : EdgeClick.Accounts.AppMainForm

This will result in loading the AccountManager before your application even starts. When the AccountManager loads it will try to load the current account from the Account database. If it fails it will then present the account edit form so the user can create a new account. If it succeeds, App.AccountMgr.CurrentAccount will contain the current validated account.

Once authenticated and the account is saved, control will be returned to your application's main form, allowing its load and show routines to be executed, etc.

Define application properties

In Program.cs, you must define a number of global application properties:

// Set the application index for your application
EdgeClick.App.ApplicationIndex = "0";

// Set the name of your application
EdgeClick.App.Name = "None";

// Set your application version
EdgeClick.App.Version = "1.0.0";

// Set your application's brand name (for the About screen)
EdgeClick.App.Brand = "EdgeClick";

// Set your application's marketing URL (for the About screen)
EdgeClick.App.URL = "www.edgeclickpark.com";

The EdgeClick Menu

It is recommended that all EdgeClick applications have an EdgeClick menu, that has the following entries:

Accounts...
Groups... [only if your app utilizes groups]
Contacts... [only if your app utilizes contacts]
------------
Switch to... [not implemented yet]
About
------------
Exit

Button click event handlers for most of these menu items are inherited from AppMainForm:

this.myAccountsMenu.Click += new System.EventHandler(accountMenu_Click); 
this.mySwitchToMenu.Click += new System.EventHandler(switchToMenu_Click);
this.myAboutMenu.Click += new System.EventHandler(aboutMenu_Click);
this.myExitMenu.Click += new System.EventHandler(exitMenu_Click);

You will to need to write button click event handlers for the Groups and Contacts menu items:

this.myGroupsMenu.Click += new System.EventHandler(this.groupMenu_Click);
this.myContactsMenu.Click += new System.EventHandler(this.contactsMenu_Click);


/// <summary>
/// Display the Groups form
/// </summary>
private void groupMenu_Click(object sender, EventArgs e)
{
frmGroups f = new frmGroups(false);
f.ShowDialog();
}

/// <summary>
/// Display the Contacts form
/// </summary>
private void contactsMenu_Click(object sender, EventArgs e)
{
frmContacts f = new frmContacts(false);
f.ShowDialog();
}

Sending Commands to the EdgeClick Processor

Create a CommandCodes class that defines the EdgeClick Processor command codes your application uses

 /// <summary>
/// Defines the EP command codes this application uses
///
</summary>
public static class CommandCodes
{
public static int CAN_CONNECT = 318;
}

Use App.SendCommandToEP to send a command to the EP. You will get an XmlNode returned, or an exception will be thrown if there is a problem, so always wrap it with a try/catch. Utilites.HandleError can be used to display an appropriate failure message to the user depending on the exception type returned by SendCommandToEP. Also, whenever doing network communication, use App.PleaseWait to put up a box telling the user what you are doing:

 App.PleaseWait.Show("Sending a test command to the EdgeClick Processor");

try
{
// Send a 318 - "Can Connect" diagnostic - command to the EP
XmlNode results = App.SendCommandToEP(CommandCodes.CAN_CONNECT);
}
catch (Exception ex)
{
App.PleaseWait.Hide();
Utilities.HandleError(ex);
return;
}

// Process the XML result

App.PleaseWait.Hide();

If you need to send additional values to the EdgeClick Processor with a command, first build an EdgeClick.Net.Http instance with the attribute/value pairs added via AddTuple and then call SendCommandToEP with the Http instance as an additional parameter:

 EdgeClick.Net.Http h = new EdgeClick.Net.Http();
h.AddTuple("targetMachine", "www.sco.com");

XmlNode results = App.SendCommandToEP(CommandCodes.CAN_CONNECT, h);

Parsing the XML results from an EP command

The XML returned by SendCommandToEP takes the form:

 <return>
<!-- you will always get a return code -->
<code>{return code}</code>

<!-- based on the code, you may receive a message section giving further -->
<!-- info about the code (ex: the type of exception) -->
<msg><![CDATA[{the_message}]]></msg>

<!-- if an error did not occur, you will receive a result section -->
<result>{the_XML_result_of_the_command}</result>
</return>

The App.EPcodes enum defines all the possible return codes,but in practice the code will always be 0 (App.EPcodes.SUCESS) or 10 (App.EPcodes.NEW_VERSION_AVAILABLE). All other return codes will result in an exception being thrown (see the "Error Handling" section below).

The following code is an example of one possible way to parse the following XML result from a SendCommandToEP call:

 <return>
<code>0</code>
<result>
<MonitoredSystem-array>
<MonitoredSystem>
<systemName>acme.foo.com</systemName>
<systemOSKind>Windows XP</systemOSKind>
</MonitoredSystem>
<MonitoredSystem>
<systemName>server.foo.com</systemName>
<systemOSKind>OpenServer 6</systemOSKind>
</MonitoredSystem>
</MonitoredSystem-array>
</result>
</return>

 // Grab the <MonitoredSystem> nodes (childnodes of the single FirstChild
// node <MonitoredSystem-array>
XmlNodeList nodes = results.FirstChild.ChildNodes;

// loop through each <MonitoredSystem>
foreach (XmlNode node in nodes)
{
// loop through the child nodes
foreach (XmlNode attribute in node.ChildNodes)
{
switch (attribute.Name)
{
case "systemName":
systemName = attribute.InnerText;
break;
case "systemOSKind":
systemOSKind = attribute.InnerText;
break;
default:
// should not get here, use to help debug the attibute names,
// sometimes they get munged by the EP
break;
}
}
}

Handling Errors

SendCommandToEP can throw one of six exceptions, three of which require special handling.

Version Control

As indicated in the "Handling Errors" section SendCommandToEP will throw an EdgeClickUnsupportedVersionException if the version number of the client is too old.

If the version number of the client is older than the current version, but not old enough to be unsupported, the code section of SendCommandToEP will be set to App.EPcodes.NEW_VERSION_AVAILABLE. It is up to you how to handle this code, but it is recommended that it is checked for and a message displayed when sending the first command to theEdgeClick Processor, and ignored afterwards:

 // Is there a new version available? If so, you might want to tell the
// user or you can ignore it.
code = results.SelectSingleNode("/return/code").InnerText;
if (code == App.EPcodes.NEW_VERSION_AVAILABLE)
{
App.PleaseWait.Hide();
MessageBox.Show("There is a new version available.",
"New Version",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation,
MessageBoxDefaultButton.Button1);
 }

Deploying an EdgeClick .NET client application

To deploy your application to a Windows Mobile smartphone, you need three addittional projects:

The sample application includes these projects so that you can see how they work together.

Note: These three projects must be defined within the same solution as your mobile application project. For example, the MIGs.sln solution includes 4 projects, MIGs (the mobile client), plus the three projects discussed below (CustomInstaller, MIGsSmartSab, and Setup). Your solution must be structured in the same way.

SmartDeviceCab project

This project creates the .cab file containing your application that CustomInstaller will install on the phone.

  1. Create a new Smart Device CAB Project:
    1. Select File-»New Project.
    2. At left, expand Other Project Types and highlight Setup and Deployment.
    3. Then, at right, highlight Smart Device CAB Project.
    4. Set the Solution drop-down box, at bottom, to Add to Solution.
    5. Select OK.

  2. In the Properties Window enter the appropriate values for Manufacturer, ProductName, etc.

  3. In Solution Explorer, right-click on the SmartDeviceCab project and select "Properties" to bring up the Properties Pages window. Change the output filename to something more appropriate to your application than the default SmartDeviceCab.cab.

  4. Right-click on the SmartDeviceCab project and select Add-»Project output. You want to add "Primary output" from your main project. If "Primary output" is not listed, make sure that you have highlighted (in the project drop-down list) the project in the solution that contains the application. For example, in the MIG.sln solution, that's the MIGs project. Once the project containing the mobile application is highlighted, then the list of project outputs should have "Primary output" listed.

  5. To prevent a copy of the common EdgeClick dlls from getting included with your application, expand the Detected Dependencies list and select the four EdgeClick.* dlls. In the Properties Window, change Exclude from false to true. Repeat for System.Data.SQLite.dll. These dlls are part of a separate cab file included in this development kit which gets installed into a common location on the phone so that all EdgeClick client applications share the same set of dlls and account database.

  6. To include a shortcut to your application in the Programs folder on the phone:
  7. Build the SmartDeviceCab project.

CustomInstaller project

This project will launch ActiveSync to install the common EdgeClick cab file and your application's cab file on the phone

  1. Copy the "CustomInstaller" project from the Sample application included with this DevKit to your solution's directory

  2. Add the project:
    Right-click on your solution name in the Solution Explorer, select Add-»Existing project, browse to your copy of CustomInstaller.

  3. Open the CustomInstaller.cs source file and find the reference to "Sample.ini" in the CustomInstaller_AfterInstall method. Change it to <your app>.ini.

  4. Copy Sample.ini from the sample application to your main project, rename it to <your app>.ini.

  5. Add it to your main project:
    Right-click on your main project name in the Solution Explorer, select Add-»Existing item, browse to your ini file.

  6. Click on your ini file in the Solution Explorer and in the properties window, change Build Action to "Content" and Copy to Output Directory to "Copy if newer".

  7. Edit the ini file, make changes apropos for your application. Note the ini file format is very strict and its easy to get the ActiveSync installer to fail with no obvious reason. Follow these rules:
  8. Build the CustomInstaller project.

Windows Setup project

This project creates a regular Windows Setup installer with a simple UI that will install on a Windows desktop and then install your application onto a connected Windows Mobile phone via ActiveSync.

  1. Create a new setup project:
    File-»New Project, Other Project Types, Setup and Deployment, Setup project (make sure the Solution field on the "New Project" dialog box is set to "Add to Solution")

  2. Select the Setup project and in the properties windows enter apprioriate values for properties like Manufacturer, ProductName, Version etc.

  3. Right-click on the Setup project in the Solution Explorer and select Add-»Project output. You want to add:
  4. Right-Click on the Setup project in the Solution Explorer and select View-»Custom Actions. Right-click on the Install action and select "Add Custom Action". Browse to the Application Folder and select "Primary output from CustomInstaller". Do the same for Uninstall.

  5. Build the Setup project.

Installing on a phone

To test your setup program, first connect a Windows Mobile smartphone to your system via ActiveSync, and if you haven't already, install the Microsoft .NET Compact Framework 2.0 and the EdgeClick .NET CF 2 runtime. Then right-click on the Setup project in the Solution Explorer and select "Install". If everything is working correctly, this should launch a Windows setup program that will first install the cab and ini files on your system and then launch ActiveSync to install your application on the phone.

 

Development guidelines

The following are some best-practices development guidelines.

Handling different screen sizes

Screens can be square (240x240) or non-square (320x240, 240x320). In order to make your application work well with different screen sizes, it is recommended that you design it with the square size. To enable your application to scale to the larger sizes, you can do one of three things depending on what your UI looks like:
  1. Create a panel that all other controls go inside. Anchor the panel to all for sides of the screen by changing its Anchor property: default is left and top, add bottom and right.
  2. If your UI has a list, or tab control anchor the list or tab control to all four sides of the screen.
  3. If your UI design will not fit on the square screen size, switch to the portrait size, create a panel just like first method. Then set the AutoScroll property of the panel to true. Now when viewed on the smaller square screen, a scroll bar will appear, allowing the user to access all the controls.

Be warned that paint routines are especially vulnerable to different screen sizes. Font sizes double in pixels in VGA mode (although they keep their name and size). All pixel addresses double also. This can be handled by using anchored objects and calculating offsets from them. The Graphics.MeasureText routine is also particularly helpful for calculations using relative font sizes.

DateTime handling

Since an EdgeClick application can be run it disparate time zones from the EP, it is highly recommended that DateTimes are always stored and manipulated in Coordinated Universal Time (UTC), but displayed to the user in their local time, which will ensure that a stored DateTime always refers to the exact same moment in time, no matter from where in the world it is viewed. For example this will allow a timestamp associated with an event happening in BST does not look like it occurred 8 hours in the future when viewed by someone in PST:

Naming guidelines



Developing Java ME Mobile Clients

EdgeClick client applications can be developed using Java Micro Edition (often referred to as Java ME, and formerly referred to as J2ME), which is becoming increasingly popular and available on mobile devices of all kinds.

While its ubiquity is a positive trait, the promise of Java ME (write once, run everywhere) has yet to be fulfilled because of the plethora of implementations and the differences among them. Many developers find that Java ME does not have all the features that business applications typically require, and that the Java ME implementations cannot be relied upon to implement all features in a compatible manner. Complicating the picture further is the fragmentation caused by selective inclusion of various Java ME extensions by manufacturers and further customizations by the Operators and Carriers (i.e., the phone companies). Thus, it becomes difficult to depend on the features that will be available for Java ME applications across a wide range of devices.

But despite these difficulties, the Java ME platform can be used to develop very sophisticated mobile clients. It also allows access to the least expensive EdgeClick-capable client devices and provides the broadest market reach.

When to Use Java ME

Many newer Java ME devices come with large screens and full keypads, just like a full blown PDA. But at the same time the market continues to reward manufacturers who can make the smallest and slimmest phones, which necessarily have limited and cramped keypads and a visual display barely larger than a postage stamp. Even if these latter devices are packed with powerful processors and large amounts of memory and storage, user input remains difficult on the tiny keypad. Similarly, an application that needs to display many interelated visual elements at the same time will become less effective on a smaller display screen.

So, consider the input and output needs of the application and match them with the intended target devices. Even though it is usually recommended that you do your first Java ME projects on a capable and forgiving device, you may want to test very early using the most limited device that you have targeted, just to confirm that the user interface doesn't degenerate in unexpected ways.

If your application is targeted to a small number of devices, it is practical to exploit all the Java ME features, including extensions, available to you on those devices. However, if you are targeting a wide range of devices, you have to keep a watchful eye on what features really are (not should be) portable, taking into account that there are subtle differences between Java ME implementations. You should also expect that the fancier you make your Forms (with proportionally expanding Spacers for example), or the trickier you make your programming logic, the more likely you are to get unexpected results or bump against implementation bugs. Coding defensively and testing on numerous devices is imperative in this case.

Two standards connected with Java ME are: MIDP (Mobile Information Device Profile for cell phones), which specifies Java ME external interfaces; and CDLC, which is concerned with the underlying Java implementation.

A generic MIDP 2.0 environment without extensions will have the following limitations:

Most phones do have a mix of extensions, but they vary widely. Some of the more popular include:

Supported Java Mobile Clients

EdgeClick client applications are supported on all handsets supporting at a minimum:

In particular, there is no specific requirement for special extensions such as JSR 172 (XML and web services) or JSR 75 (FileConnection and PIM data). Since there may be as little as 8K of general purpose persistent storage on such devices, the EdgeBuilder libraries only store account information on the device. Group and contact information are downloaded if or as needed each time the application is run.

There are numerous IDE's and SDK's that are popularly used for Java ME development. The EdgeBuilder java libraries for Java ME are simple to use with all of them.

Requirements

Install the IDE or SDK of your choice. This document uses Sun's Wireless Toolkit (WTK) as an example, which is available from Sun:

http://java.sun.com/products/sjwtoolkit/index.html
The Getting Started Guide contains a tutorial for the NetBeans 5.0 IDE and for WTK.

For each Java ME project or workspace you create, install the jar file containing the EdgeClick classes into the directory for third party libraries (usually [dir]/lib) and optionally install the edge.properties in the top level of the resouce directory.

Overview

The EdgeClick Java ME 0.9 API provides a set of classes and methods that allow a MIDP2.0 application to authenticate and communicate with the EdgeClick processor, accessing the EdgeClick services. The application can optionally take advantage of classes that allow downloading and selecting between individual subscribers, contacts and defined groups for an account.

The choice to use Form-based or Canvas-based UI building blocks is certainly dependent on the desired look of the application. It is also heavily influenced by portability concerns and overall memory footprint. The EdgeClick libraries use Forms and Items, as well as a small number of MIDP2.0 CustomItems. However, EdgeClick applications are not restricted in any way from using Canvas-based Displayables.

Similarly, the prefered methodology for managing numerous screens and navigating between them varies from project to project. The EdgeClick libraries do not impose any constraints on the application in this regard. A simple View interface is provided as well as support for a push/pop navigation stack, which the application may use if desired (for example shout uses these exclusively). This is the mechanism used to pass control to and from the AccountMgr and GroupMgr Views, but other than that, the application is free to use any desired mechanism.

The Account Manager

The Account Manager object (AccountMgr) is responsible for maintaining the account database (a flat database spread among several RecordStores) and authenticating accounts. Typically, before sending commands to the EdgeProcesor, the application will either obtain an existing authenticated account from the Account Manager, or it will transfer control to the Account Manager to carry out the necessary authentication steps, including presenting input screens to the user.

Although multiple accounts can be created an authenticated, only one can be active at one time. The Main AccountMgr View allows the user to specify which is the current account, as well as add, modify, delete accounts.

The Group Manager

The Group Manager object (App.GroupMgr) is responsible for downloading the group and contactinformation from the EdgeProcessor and managing recipient lists.

When the group or contacts selection forms are called, members of the cache are marked as selected.

The selected groups or contacts can be cleared via the clearCheckedContacts and clearCheckedGroups methods.

Constructing an EdgeClick Java ME client application

The core class to initiate the application is the App class. It provides a modified version of the MIDlet lifecycle with callouts to the MidPControlable interface:

midletInit (MIDlet m)
midletDestroyed (MIDlet m)
midletPaused (MIDlet m)
midletRestarted (MIDlet m)

and the following methods

register (MidpControllable mc)
deregister (MidpControllable mc)

The latter allow any object in the application which implements the MidpControlable interface to receive notification of lifecycle events. For example, a media playing object could become temporarily inactive while a user handles an incoming phone call. It would register itself sometime before playing the media and implement its housekeeping task in the midletPaused() method. Similarly, an object can register itself and implement the midletDestroyed() method to release any resources when the application exits.

Start by creating a subclass of the App class. In the Meter client sample code, the com.sco.edgeclick.client.MeterDemo class extends App and is the class that is launched by the handset's Java ME implementation.

To properly set the application in motion, your instance of the App class must ensure that by the time the midletInit() methods of all the registered MidpControlables have been called, one of them has installed (i.e. setCurrent()) a Java ME Displayable (usually a Form or Canvas) with appropriate event callback listeners.

One way to do this is to have the subclass override the midletInit() method and install the first Displayable there. his is how it is done in the MeterDemo with a call to:

   pushView (new MeterMain());  // setCurrent() in MeterMain.redisplay()

Alternatively, the first Displayable could be set up in another object which implements the midletInit() method. In this case, the main application would simply register the object in its constructor:

   register (new MyMainMenu()); // setCurrent() in MyMainMenu.midletInit()

To provide some basic customization of the EdgeClick views when they are displayed, your startup code should also assign values to App.appName and the default LogoLine icon Image. These are particularly helpful to the Account and Group manager views to provide a consistent look for the user. See HelloEC.java for a simple example of how to set these values.

Sending Commands to the EdgeClick Processor

In Java ME, several precautions must be taken when communicating with the ECP. In particular, a standard MIDP2.0 http connection initiated by the Connector class must be run in a separate thread from the UI event thread. On many devices, the Java management software will briefly take control of the screen away from your application to query the user whether the networking operation is permitted. Often it is preferable to have your own screen regarding the networking operation be visible before the system permission screen partially or completely covers it.

The EdgeClick Http class assists with these tasks. The get() and post() methods create a separate thread to carry out the communication with the ECP. They also take into account whether a system permission screen is imminent and pause briefly to ensure that it will not be displayed ahead of a new application screen (if any).

On completion, the EdgeClick Http object calls httpDone(), a callback method of the HttpListener interface to notify that the operation has completed, or terminated due to an error. The application must supply an HttpListener to receive this notification and must be aware that it is running in a separate thread and use thread synchronization to ensure data integrity.

The GuiCmdCallback class can assist in synchronizing multiple threads using the implicit thread safety of the MIDP2.0 event model. Using Display.callSerially() this class schedules the delivery of a Command to a CommandListener in the UI event thread. This can also assist in localizing event handling code in the program.

    public void commandAction(Command c, Displayable s) {

	// send request to ECP

	if (c == downloadCommand) {

	    launchEcpRequest (dlDoneCommand);
	}

	// check response

	else if (c == dlDoneCommand) {
	    String error = checkResponse (http_);
	    if (error == null) { // success

		// parse returned data from ECP, etc.

	    }
	    else {
		errorAbort ("Network Download Failed\n\n" + error);
	    }
	}

	else if (e == exitCommand) {
	    // exit here
	}
    }


    private void launchEcpRequest (Command callbackCmd) {
	pleaseWait = App.getApp().getPleaseWait();
	plsWaitMsg = "Retrieving customer orders";
	http_.clear();	// if reusing this http_
	pleaseWait.show (plsWaitMsg, http_, myMainScreen);
	httpCallback = new GuiCmdCallback(display, this, callbackCmd, myMainScreen);
	
	http_.addTuple ("CMD", CUSTOMER_ORDERS);
	// http_.addTuple(...) for command arguments as necessary

	http_.post (this, App.currentAccount.ecpUrl());
	// new Http worker thread launched.  See httpDone() below.
    }


    private String checkResponse (Http edgep) {

	String err = null;
	String response = edgep.getResponse();
	int ecpCode = HttpUtil.getEcpCode (response);

	switch (ecpCode) {
	case Http.CODE_NEW_VERSION_AVAILABLE:
	    // flag here existence of new App version.
	    // No less successful than next case, so fall through ...
	case Http.CODE_SUCCESS:
	    // err stays null for success
	    break;

	case Http.NO_RESULT_CODE:
	    // ECP always sends a result code, so we know it's an IO failure.
	    err = "Connection Error: " + edgep.getIoErr();
	    break;

	case Http.CODE_UNSUPPORTED_VERSION:
	    err = "This version is no longer supported. Please download the newest version.";
	    break;

	case MY_APP_RETURN_CODE:
	    // specific EdgeClick Processor return code for this app
	    break;

	default:
	    err = "Unexpected error: " +
		HttpUtil.getEcpMsg (response) +
		" (Code:" + ecpCode + ')';
	    break;
	}
	return err;
    }


    // in Http worker thread

    public void httpDone() {

	pleaseWait.hide();

	// This is a good place to check if we can recover and reissue
	// the http request using the saved tuple strings.  An expired
	// sessionId is an example of a recoverable error.

	if (!http_.interrupted()) {
	    if (HttpUtil.authExpired (http_.getResponse())) {
		if (AccountView.getInstance().reAuthenticate (viewform)) {
		    pleaseWait.show (plsWaitMsg, http_, myMainScreen);
		    http_.post (this, App.currentAccount.ecpUrl());  // try again
		    return;
		}
	    }
	}

	httpCallback.run();
	// logic resumes at dlDoneCommand, in UI thread
    }

Java ME networking and the Switchboard

Java ME mobile phones may operate under numerous networking restrictions that are rarely encountered when working with more powerful devices:

The first two can often be overcome by using code signing to augment the trust level of the MIDlet on the phone. The latter two cannot. Obtaining a well known (and expensive) SSL certificate is a reasonable solution to provide HTTPS access from your mobile Java application to the ECP. But that is not practical in the case where the ECP provides services for multiple virtual hosts (like community.edgeclickpark.com). he cost of a separate certificate per virtual host is significant. Chunking is also a problem on the server side in the context of apache and Java servlets.

The end result is that, unless you know that all your target Java ME devices are not bound by these restrictions, you need them to be able to reach your EP from a URL of the form:

https://some.server.com/servlet_identifying_path

where :

In the default EdgeBuilder setup, the WTK is used in http mode. This eliminates the SSL certificate problem. And since the WTK is not prone to use chunked encoding when the size of the request is modest (approx <2K bytes), direct connection is sufficient for most demo program purposes.

However, when using actual phones, going through an operator/carrier's network, and using HTTPS, it is necessary to use a relay program that satisfies the needs of the incoming request from the cell phone (recognized SSL certificate) and the needs of the target ECP (chunking removed). That is the purpose of the Switchboard program. It presents a quality SSL certificate to please the mobile devices, converts chunked requests to fixed length requests, and relays to an arbitrary number of ECPs (real or virtual).

The Switchboard needs to see a URL in a particular format to perform its relay function. If the ECP is expecting a URL of the form:

https://ecp.svr.com:8443/eps-xx/epsmob

Then to reach it through a Switchboard program running on server swbd.svr.com on port 443, you would use as a URL on the Java ME device:

https://swbd.svr.com/epsmidp/ecp.svr.com:8443/eps-xx/epsmob

Sample Java ME Client Application

A sample Java mobile client, MeterJavaClient, is included in the EdgeBuilder doc/samples directory. It is a small-scale example, that does not handle the complexity of many different UI forms or of account management, version provisioning, multimedia capture, or other more challenging aspects of mobile programming. Nevertheless it gives a tangible example of the mobile side of the client-ECP interface, and it gives a starting point for future work.

See the Processors - Meter Application section below for a functional description of this sample

Changes to the Java ME Client API since Beta1

The View functionality in AccountMgr has been split out into a separate AccountListView class so that applications that don't need the default GUI screens can be made smaller.

   AccountMgr.getView() -> AccountListView.getView()

A new HttpUtil class provides methods to efficiently extract the EdgeClick Processor return code and associated "msg" string from the XML response.

A few new classes have been added to align the C# and Java usage more closely. In addition, one major change has been made to the Http class. It no longer discards its internal tuple buffers after each request. This facilitates resubmitting the request after a recoverable error is encountered (see sample code in guide). he Http.clear() method must be called prior to reusing the object for a new request.

Some AccountMgr methods have been made non-static.

   AccountMgr.currentAccountSet() ->  compile error, use
   App.accountMgr.currentAccountSet()

There is now a PleaseWait interface and DefaultPleaseWait implementation to present during network requests.

An Account class has been created for manipulating account information directly from the java application code. Account information that used to be retrieved from special methods in the App class must now use the associated Account class information.

   App.getCurrentAccountid() -> App.currentAccount.serverAccountId
   App.getCurrentServerUrl() -> App.currentAccount.ecpUrl()
   App.getCurrentSessionId() -> App.currentAccount.sessionId
   App.getCurrentLogin()     -> App.currentAccount.login


Developing Web-based and PC-based Clients

Whether you even need web-based or PC-based clients depends upon the requirements of your application.

For some applications, such as in-the-field data colletion and reporting, the mobile device is necessary and no other type of fixed-location client can replace it.

For other applications, such as those dealing with human resources issues within a company, only a certain percentage of employees will have EdgeClick-enabled phones, and some means must be provided to allow the rest of the employee base to use the application.

Here there are two general ways to proceed.

One is to write a new application, probably web-based so that people can access it from a browser on any kind of laptop or desktop machine no matter what operating system it is running. Here the modern technology of choice is AJAX (Asynchronous JavaScript And XML), and several successful EdgeClick application clients have been written in this fashion.

The other is to take the application code written for the mobile device, and adapt it to run natively on the laptop or desktop. This is not trivial to do with any of the mobile development technologies, but the best chance is with Compact .NET C# applications (adapt to run under the native .NET Framework on Windows XP Pro or Windows 2003 Server systems; this has been successfully done with some EdgeClick applications) or with SuperWaba (adapt the Java-ish code to run under Java Standard Edition on almost any operating system). By comparison, Java ME and HB++ are much more difficult to move over.

Issues involved in such code transplanting range include retargeting the build environment and replacing or changing library dependencies. Moreover, often design changes in the application itself are needed, especially around UI design. UIs developed for the small real estate and different OSes of mobile devices are often completely unsuitable for conventional monitor-sized interfaces.

© Copyright 2006 The SCO Group, Inc. All Rights Reserved.