Develop for Windows Mobile-based Smartphones Using the .NET Compact Framework

 

Andreas Sjöström, Christian Forsberg
businessanyplace.net

Applies to:
   Windows Mobile™-based Smartphones
   Windows Mobile 2003 Second Edition software for Smartphones
   Microsoft® Visual Studio® .NET 2003
   Microsoft .NET Compact Framework version 1.0

Summary: Learn how to develop and distribute applications for Windows Mobile-based Smartphones using Visual Studio .NET, the .NET Compact Framework, and the Smartphone 2003 SDK. (28 printed pages).

Download the sample code from the Microsoft Download center.

Contents

Introduction
Developing Phone Applications
User Interface Design
Application Data Storage
Using XML Web Services
Packaging for Distribution
Enterprise Application Scenarios
Conclusions

Introduction

The purpose of this article is to outline critical aspects of Windows Mobile-based Smartphones using the Microsoft® .NET Compact Framework. As a member of the .NET family, the .NET Compact Framework extends platform and developer knowledge to new devices and form factors. Developers knowledgeable in the .NET Framework and Microsoft® Visual Studio® .NET 2003 can now start building applications for phones.

In summary, this article provides information related to the following areas:

  • Developing Phone Applications — key aspects of Smartphone application development
  • User Interface Design — available controls and best practices for use
  • Application Data Storage — managing XML files and registry
  • Using XML Web services — consuming XML Web services
  • Packaging for Distribution — distributing Smartphone applications
  • Enterprise Application Scenarios — relevant scenarios where Smartphone applications provide value to businesses

More information can be found on the following pages:

Microsoft MSDN Mobility & Embedded Development Center

Microsoft .NET Compact Framework

Windows Mobile for Smartphone

Developing Phone Applications

Regardless of what platform you target when developing applications, there are a number of common design and development skills required. These skills include the ability to define and understand scenarios and use cases, construct and adhere to system architecture, systematically define and solve problems, and so on. From this aspect, developing applications for Smartphones is no different to developing for any other platform. Form factors have gotten smaller and the path from mainframes, servers, desktops, PDAs has now, through Windows Mobile for Smartphone, finally reached cell phone size. The Windows Mobile software for Smartphone has a software development platform sharing many characteristics with its larger siblings.

However, to successfully design and develop phone applications, not only do common development practices need to be established but also a set of Smartphone-specific aspects have to be considered to develop useful, easy-to-use and efficient phone applications:

  • The Smartphone is primarily designed to be a good phone and as such it is used in different settings and situations than many other devices. Applications need to be swift, stable and implement a high degree of fault tolerance. A clear strategy regarding exception handling needs to be defined and implemented across the entire application.
  • The screen real estate is even more valuable than on PDAs such as Pocket PCs. The smaller screen demands a clean and efficient user interface design.
  • The Smartphone does not have a touch screen. Both user interface and input mechanisms have to be designed with small hardware keys in mind. Application navigation needs to be predictive and intuitive requiring as few key strokes as possible. In fact, most phone applications should be designed to provide strong support for viewing of information primarily and require as little input as possible.
  • The inherent connectivity, including SMS and Internet standards support, of the Smartphone should be made a natural part of application design. XML Web services are implemented as a core element of the .NET Compact Framework and SMS features can be utilized from the platform itself by using Platform Invoke.
  • Windows Mobile software for Smartphone includes a number of built-in applications such as Contacts, Calendar, and Inbox and so on. Integrating application design where appropriate with these applications adds more combined value to the user.

These are key considerations to be addressed in application design and development for Windows Mobile software for Smartphone.

User Interface Design

If you come from the native (or unmanaged) development world, such as developing applications using Microsoft eMbedded Visual C++®, you will notice that managed code does many things for you. For example, when it comes to user interface design, the most obvious change is that you don't have to keep track of the ID number of controls and other user interface elements — you refer to them by name. You do not have to deal with pointers and cleaning up allocated memory.

If you are familiar with.NET Compact Framework development for Pocket PC, many things will be familiar to you. However, there are some significant differences when it comes to user interface design. Most important is probably the lack of a touch screen, and the consequences of that. Also, there is no SIP (Standard Input Panel), and a number of controls are obsolete on a Smartphone (see "More Controls" below for supported controls in the .NET Compact Framework on Smartphone 2003).

User Interface Basics

As an introduction, let's look at a familiar sample "Hello World" form:

Figure 1. Sample form

This form was designed according to the Smartphone Interface Guidelines (included in the Smartphone 2003 SDK). When phrases like "should be" and "should have" are used in the remainder of this chapter, they indicate a reference to the design guidelines. If you cannot find the answer in the guidelines, the best way to know how to solve user interface design issues is always to look at other existing Smartphone applications.

As there should be one control on each row in a form, a Label control is added on the first row and a TextBox control on the second. Each control should have a height of 22 pixels, and the form should have a buffer space of 2 pixels at the top and bottom. An obvious control in a "Hello World" application is probably the Button control, but on a Smartphone no buttons are allowed. The solution is to use a MainMenu control that is accessed using the soft keys (two hardware buttons below the screen of the phone). The left menu item (left soft key) should not have any sub-items and this option should be the most common user task (in this sample "Send"). The right menu item (right soft key) usually holds a menu with sub-items, but could also be the second most common user task or could be blank.

The code for creating the controls on the form, according to good Smartphone design, looks like this (declarations omitted):

this.mnuBar = new System.Windows.Forms.MainMenu();
this.mitSend = new System.Windows.Forms.MenuItem();
this.mitMenu = new System.Windows.Forms.MenuItem();
this.mitExit = new System.Windows.Forms.MenuItem();
this.lblName = new System.Windows.Forms.Label();
this.txtName = new System.Windows.Forms.TextBox();
// mnuBar
this.mnuBar.MenuItems.Add(this.mitSend);
this.mnuBar.MenuItems.Add(this.mitMenu);
// mitSend
this.mitSend.Text = "Send";
this.mitSend.Click += new System.EventHandler(this.mitSend_Click);
// mitMenu
this.mitMenu.MenuItems.Add(this.mitExit);
this.mitMenu.Text = "Menu";
// mitExit
this.mitExit.Text = "Exit";
this.mitExit.Click += new System.EventHandler(this.mitExit_Click);
// lblName
this.lblName.Location = new System.Drawing.Point(3, 2);
this.lblName.Size = new System.Drawing.Size(165, 22);
this.lblName.Text = "Name:";
// txtName
this.txtName.Location = new System.Drawing.Point(4, 24);
this.txtName.Size = new System.Drawing.Size(164, 20);
this.txtName.Text = "Chris";
// MainForm
this.Controls.Add(this.lblName);
this.Controls.Add(this.txtName);
this.Menu = this.mnuBar;
this.Text = "Sample UI";
this.txtName.Size = new System.Drawing.Size(162, 22);

Note the naming of the controls as this helps readability of the code, and also note that the order in which the controls are added to the form is the order in which the controls will receive focus (also referred to as "tab order"). When the form is designed, you may need to modify the code generated by the designer to get the focus order right. Also, if you want the height of the TextBox to conform to the guidelines, the generated code has to be manually modified when form design is complete. You do this by editing the code generated by the forms designer (in the InitializeComponent method). An example is the height of the "Name" TextBox (changed from a generated default of 25 to 22):

The two event handlers that are declared for the menu items "Send" and "Exit" look like this:

private void mitSend_Click(object sender, System.EventArgs e)
{
  MessageBox.Show("Hello " + txtName.Text + "!", this.Text,
    MessageBoxButtons.OK, MessageBoxIcon.Asterisk,
    MessageBoxDefaultButton.Button1);
}
private void mitExit_Click(object sender, System.EventArgs e)
{
  this.Close();
}

The "Exit" menu item (on the menu of the right soft key) closes the main form and so also the application. The "Send" menu item (left soft key) shows a message box that looks like this:

Figure 2. Message box

A message box should have a maximum of two options (no Yes/No/Cancel), and the selected icon control the headline ("Info") and the background.

More Controls

When using the .NET Compact Framework on a Smartphone 2003, the following controls are available:

  • Label
  • TextBox
  • MainMenu
  • CheckBox
  • PictureBox
  • Panel
  • ComboBox
  • ListView
  • TreeView
  • HScrollBar
  • VScrollBar
  • Timer
  • ProgressBar
  • ImageList

The first three were included in the sample above, but let us put some more controls to work. After adding a number of controls, this is what the form looks like:

Figure 3 More controls

The previous Label and TextBox was added to a Panel control. Panels should always cover the whole form, and beside the Panel a VScrollBar (vertical scrollbar) was added. In the panel a number of Labels and TextBoxes were added as well as a CheckBox and a ComboBox. The CheckBox is fairly obvious, but the ComboBox (also referred to as "item picker") can not be pulled down as you may be used to. Instead, there are two ways of making a selection: (1) you can use the left and right arrow keys to step through the different options, and (2) you can press the action key to get a new screen were you can select one of the options:

Figure 4. ComboBox selection in full screen

The purpose of adding the other controls to a Panel and to add a VScrollBar was to show how to make a form scrollable. This is one way to handle adding more controls to a form than can fit in one screen.

The way to accomplish this is to create the Panel large enough to hold all other controls, and the VScrollBar should have the same height as the working area of the screen (normally 180, but can be retrieved dynamically with Screen.PrimaryScreen.WorkingArea.Height). The VScrollBar should have a Maximum value of the number of fields that does not fit in the first screen. With fields we mean a combination of a Label and another control (TextBox, CheckBox, and so on). If the standard 22 points are used per control, this means that we can fit 4 fields (8 controls) on the screen at one time. So, if we have 6 fields (12 controls) the Maximum property of the VScrollBar should be set to 2. With all this set up, each input control (not the Labels) should have their GotFocus event set to the following code:

private void ctl_GotFocus(object sender, System.EventArgs e)
{
  if (((Control)sender).Top > Screen.PrimaryScreen.WorkingArea.Height - pnlForm.Top)
    vsbForm.Value++;
  if (((Control)sender).Top < -pnlForm.Top)
    vsbForm.Value--;
}

And this is the code to scroll the Panel according to the VScrollBar Value.

private void vsbForm_ValueChanged(object sender, System.EventArgs e)
{
  pnlForm.Top = -vsbForm.Value * 44; // Height of one label and other control
}

That is all you need to make your form scrollable.

Another way of handling more controls than can fit in one screen is to use a tabbed dialog. We use this term as it is a familiar concept to most Windows users. On a Smartphone, however, there is no tab control, so a full-screen ListView control could be used as a replacement. However, we should be able to act on numeric key presses and the ListView currently does not raise any events for that. Therefore, a control called SelectionList was used (thanks and original credit goes to Robert Levy from Smartphone Thoughts) for the tab selection list. The result is this typical Options screen:

Figure 5. Options screen (tab selection)

The SelectionList control can handle more options than can fit a single screen. It just adds a recommended "More…" option as the last choice (for key "9") and displays more options on a new (logical) screen.

The implementation of the SelectionList control is very straightforward and the actual painting of the options is done using Graphics.FillRectangle and Graphics.DrawString and a standard technique known as double buffering (drawing to an off-screen bitmap and then Graphics.DrawImage to screen when done). Check out the sample code for more details on this very usable control.

When a tab is selected with the action key or one of the numeric keys, the options are shown on a separate full screen:

Figure 6. General options sample (tab)

Note that each tab has a "Cancel" option as the right menu item (soft key), but it should not appear in the tab selection screen.

The above Options form was actually implemented using a single form. The reason for this was to show a solution that will have better performance than to have separate forms for the selection screen and for each tab, but with more complex code as the trade-off. In short, the selection screen is the SelectionList control and each tab is a Panel control that is hidden or shown according to the current selection. The code to open and close tabs looks like this:

private void selList_ItemSelected(object sender, ItemSelectedEventArgs e)
{
  switch (selList.SelectedIndex)
  {
    case 0:
      this.Text = "General";
      pnlTab1.Visible = true;
      pnlTab2.Visible = false;
      pnlTab3.Visible = false;
      selList.Visible = false;
      mnuBar.MenuItems.Add(mitCancel);
      currentTab = 0;
      break;
    case 1:
      this.Text = "More";
      pnlTab1.Visible = false;
      pnlTab2.Visible = true;
      pnlTab3.Visible = false;
      selList.Visible = false;
      mnuBar.MenuItems.Add(mitCancel);
      currentTab = 1;
      break;
    case 2:
      this.Text = "Even More";
      pnlTab1.Visible = false;
      pnlTab2.Visible = false;
      pnlTab3.Visible = true;
      selList.Visible = false;
      mnuBar.MenuItems.Add(mitCancel);
      currentTab = 2;
      break;
  }
}
private void CloseTab()
{
  if (currentTab > -1)
  {
    this.Text = "Options";
    pnlTab1.Visible = false;
    pnlTab2.Visible = false;
    pnlTab3.Visible = false;
    selList.Visible = true;
    mnuBar.MenuItems.Remove(mitCancel);
    selList.Focus();
    currentTab = -1;
  }
  else
    this.Close();
}
private void mitDone_Click(object sender, System.EventArgs e)
{
  // Save
  switch (currentTab)
  {
    case 0:
      // Save General settings
      break;
    case 1:
      // Save More settings
      break;
    case 2:
      // Save Even More settings
      break;
  }
  this.CloseTab();
}
private void mitCancel_Click(object sender, System.EventArgs e)
{
  this.CloseTab();
}

Note that the caption of the form changes for each tab, and that the "Cancel" menu item is added when a tab is active and removed in the selection screen.

Form Navigation

An important part of any application is form navigation, and also the way that information is transferred between forms. When a subform is shown, the code could look like this:

Cursor.Current = Cursors.WaitCursor;
SubForm subForm = new SubForm(this);
subForm.ShowDialog();

Note that the current form is passed as a parameter to the constructor of the options form. In the constructor, the parent form is saved with this code:

private Form parentForm;
public SubForm(Form parentForm)
{
  InitializeComponent();
  this.parentForm = parentForm;
}

This enables us to do a number of important things. First, we can hide the parent form while the options form is active. This will prevent our application from having more than one window active in a task switching utility. Normally, we hide the parent form as soon as we are done initializing the form, and that is usually at the end of the form's Load event:

private void SubForm_Load(object sender, System.EventArgs e)
{
  // Control initialization
  // ...

  parentForm.Hide();
  Cursor.Current = Cursors.Default;
}

And upon closing the form, the Closing event takes care of showing the parent form again:

private void SubForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
  parentForm.Show();
}

Platform Invoke

The way to reach functionality that is not available in the managed (.NET Compact Framework) environment is a mechanism called Platform Invoke, or P/Invoke for short. Using P/Invoke, you can call native functions like Windows APIs. An example where this is very useful is when you want to conform to the user interface guidelines and allow certain TextBox controls to default to accept numbers instead of characters. In the above sample, the last TextBox on the main form is set to numbers input mode:

Figure 7. TextBox with numbers input mode

This is accomplished with the following code (in the form's Load event):

txtEvenMore.Focus();
EditModeHandler.SetNumbersMode();

Note that the TextBox control needs to have the focus to set the numbers input mode. The implementation of the SetNumbersMode looks like this (somewhat simplified):

public static int SetNumbersMode()
{
  int hWnd = GetFocus();
  return SendMessage(hWnd, EM_SETINPUTMODE, 0, EIM_NUMBERS);
}

// API declarations
private const uint EM_SETINPUTMODE = 0x00DE;
private const uint EIM_NUMBERS = 2;

[DllImport("coredll.dll")]
private static extern int SendMessage(int hWnd, uint wMsg, uint wParam, uint lParam);

[DllImport("coredll.dll")]
private static extern int GetFocus();

The declarations for the Windows APIs (SendMessage and GetFocus) can be found in the include file WINUSER.H, and the definitions of the constants (EM_SETINPUTMODE and EIM_NUMBERS) can be found in the file WINUSERM.H (include the mobile extensions to winuser.h). Both these files are included with the Smartphone 2003 SDK.

Note   Getting the HWND of a window and sending Windows messages directly is not a supported feature of the .NET Compact Framework 1.0. Although it works in the current version, this does not guarantee it will work the same say in the future, so you should carefully consider if you really need to use this advanced functionality.

This was a very simple but useful example of how native code can be called. Even if P/Invoke has some limitations, there are many advanced things that can be achieved using this technique.

Conclusion

Even with the small number of user interface elements (controls), it is possible to build efficient user interfaces. Make use of the extensive user interface guidelines included in the help files for the Smartphone 2003 SDK. Make sure to check out how other Smartphone applications — particularly those that are already on the phone — solve user interface issues. If you miss out on some managed functionality that you know was possible from native code, you can try some P/Invoking.

Application Data Storage

Despite the connectivity built into the Smartphone platform, it is important to include application data storage in application design and development. Wireless bandwidth is not free, and it is more efficient from a performance perspective to get locally stored data than data residing in a remote server infrastructure.

Application data is typically about two things: settings and application preferences that the user expects the application to keep even after it is terminated, and transactional or reference data brought from a remote server or entered by the user. Microsoft SQL Server™ 2000 for Windows CE Edition (SQL Server CE) is a popular choice for application data storage on Pocket PCs and other Windows CE devices. Other options have to be used in Smartphone applications since SQL Server CE is not available for the platform. Persisting data to the registry is not generally recommended because flushing the registry to permanent store is quite resource intensive. For Smartphone applications, using local XML files is a common alternative.

Storing Data Using XML

XML support in the .NET Compact Framework is implemented primarily in the System.Xml and System.Data namespaces. There are two fundamental approaches to storing data in XML. First, you can leverage the XmlDocument, XmlTextReader and XmlTextWriter classes. Alternatively, you can leverage the XML-driven ADO.NET-based DataSet. The following sample stores data in a local XML file using an ADO.NET approach.

ISBN Anyplace Sample Walkthrough

ISBN Anyplace is a sample application that lets the user retrieve the Barnes & Noble price of any book given its unique ISBN number. The application persists the data that it receives so that the user can access it more quickly later. The application is powered by an external XML Web service which we will look more carefully at a later stage.

The main form consists of:

  • A TextBox in which the user can enter an ISBN number
  • A ListView which is populated by the responses from the XML Web service
  • Menu controls that allow the user to submit the request, clear the list, and exit the application

To make ISBN Anyplace more complete, you could consider adding code that removes data when it reaches a certain age, and even user interface enhancements that would indicate what data is persisted and what data is just retrieved from the most recent XML Web service call.

The main form looks like this:

Figure 8. Enter ISBN number

Once the user has submitted the request, the ListView is populated:

Figure 9. ISBN numbers entered

The data, ISBN and price, is stored in a local XML file in the application directory. The user can exit the application and restart it, and still have access to the information gathered.

Let's take a look at what goes on behind the scenes.

ISBN Anyplace Sample Code

The sample code project consists of:

  • The main form for user interface, MainForm.cs
  • An ApplicationData class for code handling the local XML file
  • An XML Schema (XSD) file which holds the DataSet schema

The following code executes when the application is launched:

private void MainForm_Load(object sender, System.EventArgs e)
{
  // Populate listview
  PopulateListview();

  txtBookISBN.Focus();
EditModeHandler.SetNumbersMode();
}

The EditModeHandler.SetNumbersMode method is used to format the TextBox to easily accept numeric input (for details, see "Platform Invoke" in the "User Interface Design" section above).

The PopulateListview is a private method of the MainForm. It is called when the ListView should be populated. Watch out for the following:

  • The ApplicationData class is instantiated.
  • The ApplicationData.GetAll method returns a dataset which holds data from the local XML file.
  • The listview is cleared.
  • Instead of using a foreach loop, a simple for loop going backward in the DataRows in order to get the items listed in the right order.

And here is the code:

private void PopulateListview()
{
  // Get application data
  ApplicationData applicationData = new ApplicationData();

  // Get Dataset from ApplicationData class
  DataSet ds = new DataSet();
  ds = applicationData.GetAll();

  // Clear listview
  lvwBook.Items.Clear();

  // Loop through rows backwards. The last value appears first.
  for(int i = ds.Tables["ApplicationData"].Rows.Count-1; i >= 0; i--)
  {
    DataRow dr = ds.Tables["ApplicationData"].Rows[i];
    
    // New item
    ListViewItem book = new ListViewItem(dr["key"].ToString());

    // Assign ISBN and Price
    book.SubItems.Add(dr["value"].ToString());

    // Add the item to the listview
    lvwBook.Items.Add(book);
  }
}

The ApplicationData class has primarily three methods:

  • ApplicationData.GetAll returns all items as a DataSet.
  • ApplicationData.ClearAll deletes the local XML file.
  • ApplicationData.New adds an item to the local XML file.

The following code is found in the GetAll method:

public DataSet GetAll()
{
  // Initiate new dataset
  DataSet ds = new DataSet();

  // Read schema and xml
  ds.ReadXmlSchema(xsdApplicationData);

  // Return the dataset regardless if ReadXml throws an exception or not
  // There is no dataset the first time the application runs
  try
  {
    ds.ReadXml(xmlApplicationData);
  }
  catch {}

  // Return dataset
  return ds;
}

Note that the exception handling catches the exception, but won't address it in any particular way. The reason is that an exception is typically thrown the first time the application executes, or just after the XML file has been deleted and there is no local XML file to be opened. In that case, I just want the application to proceed; the XML file will be created later on in the rest of the application process. The following code executes when adding a new item:

public void New(string dataKey, string dataValue)
{
  // Add data to local XML file
  // Initiate dataset
  DataSet ds = new DataSet();
  ds.ReadXmlSchema(xsdApplicationData);
  
  // Try reading applicationdata xml file.
  // If exception is thrown there's a problem reading the file (e.g. it does not exist),
  // then move on to create a new.
  try
  {
    ds.ReadXml(xmlApplicationData);
  }
  catch {}

  // New row
  DataRow dr = ds.Tables["ApplicationData"].NewRow();

  // Set datarow properties
  dr["key"] =  dataKey;
  dr["value"] =  dataValue;

  // Add row to dataset
  ds.Tables["ApplicationData"].Rows.Add(dr);

  // Save data
  ds.AcceptChanges();
  ds.WriteXml(xmlApplicationData);
}

The xsdApplicationData and xmlApplicationData constants are declared and set in the ApplicationData class like this:

private const string xsdApplicationData = @"\Storage\Program Files\ISBNAnyplace\ApplicationData.xsd";
private const string xmlApplicationData = @"\Storage\Program Files\ISBNAnyplace\ISDNAnyplace.xml";

You can Platform Invoke the Windows CE API SHGetSpecialFolderLocation with CSIDL_APPDATA (26) as parameter to retrieve the application data path.

RAM is erased when a Smartphone is switched off. This means that application data has to be put in the \Storage folder. The \Storage folder is persisted to flash memory. For more information, see "Storing Data" in the Smartphone Guide found in the Smartphone 2003 SDK.

The ClearAll method consists of just one line of code:

public void ClearAll()
{
  // Delete XML file
  System.IO.File.Delete(xmlApplicationData);
}

ClearAll simply deletes the physical XML file stored in the Smartphone.

Conclusion

As you can see, the inherent XML support in the .NET Compact Framework provides a solid foundation for application data storage. The amount of code required is minimal, and using a systematic approach to modeling the XML structures, a Smartphone application can persist any kind of data without using a relational database engine.

Using XML Web Services

The sample project ISBN Anyplace uses an XML Web service to retrieve the price of a book based on its ISBN number. This XML Web service is one of many demo services provided by XMethods.com. The purpose of including XML Web service paragraphs in a Smartphone 2003 article is to illustrate that since the .NET Compact Framework is built into the platform and since XML Web services support is inherent in the .NET Compact Framework, the process and functionality is identical to that of full .NET Framework-based applications and .NET Compact Framework-based applications running on Pocket PCs.

Initializing the XML Web Service

The process of setting up the use of an XML Web service in a Smartphone 2003 application is very easy and straightforward. In order to use an XML Web service, you need to add the Web reference to your project. A Web reference enables a project to consume an XML Web service. When you add a Web reference to your project, Visual Studio .NET automatically generates a proxy class with methods that serve as proxies for each exposed method of the XML Web service. The proxy class is hidden from view in the Solution Explorer by default. Your application uses an automatically generated class to access XML Web services, and not one you would modify with your own code.

To add a Web reference to a project:

  1. In Solution Explorer, select the project that will consume the XML Web service.
  2. On the Project menu, select Add Web Reference.
  3. Enter the URL for the XML Web service you wish to consume, and then click Go.
  4. In the Web reference name field, enter a name that you will use in your code to access the selected XML Web service programmatically.
  5. Click Add Reference to create a reference to the XML Web service in your application.

The new reference will appear in the Solution Explorer under the Web References node for the selected project.

The proxy class that Visual Studio .NET generates when you add a Web reference also includes methods for accessing the Web service synchronously or asynchronously. For more information about synchronous and asynchronous XML Web service access, read the article Consuming XML Web Services with the Microsoft .NET Compact Framework.

ISBN Anyplace Sample Code

The code in ISBN Anyplace that accesses the Barnes & Noble XML Web service is found in the Click event of the Send menu item. As the XML Web service is already added as a Web reference, all that is needed is a simple class initialization using the already-mentioned proxy class.

private void mitSend_Click(object sender, System.EventArgs e)
{
  // Call Barnes & Noble XML Web service
  // The XML Web service returns a book's price based on its ISBN
  // WSDL is located at: https://www.xmethods.net/sd/2001/BNQuoteService.wsdl  

  Cursor.Current = Cursors.WaitCursor;

  // ApplicationData class
  ApplicationData applicationData = new ApplicationData();

  try
  {
    // Initialize Web service
    net.xmethods.www.BNQuoteService bn = new
      ISBNAnyplace.net.xmethods.www.BNQuoteService();

    // Call Web service
    float price = bn.getPrice(txtBookISBN.Text);

    // Store ISBN and price to XML file
    applicationData.New(txtBookISBN.Text, price.ToString());

    // Populate listview
    PopulateListview();
  }

  catch(Exception ex)
  {
    Cursor.Current = Cursors.Default;
    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK,
      MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1);
  }
  finally
  {
    txtBookISBN.Text = "";
  }

  Cursor.Current = Cursors.Default;
}

In one line of code, the external XML Web service is called and its response is caught. In essence, this sample code shows that using XML Web services in Smartphone application is very straightforward and efficient from a coding perspective.

Packaging for Distribution

When the application is built, tested, and documented, the time has come to deploy it. Now the application is to be made available to the users, and when we talk about Smartphones, the standard PC/CD installation may not do the trick. First, because the user may not even have a PC with ActiveSync installed, and second, because the installation should be possible from anywhere.

Packaging

You can use Visual Studio .NET 2003 to create cabinet (.cab) files for installation. To do this, load and build the project using the "Release" configuration. Choose Build/Build Cab File to generate the batch file that you will use to create the cabinet files. The batch file is called BuildCAB.bat, and is located in <project path>/obj/Release. The batch file includes support for x86 and ARMV4 processors.

To build the cabinet files, you need to make some manual changes to the batch file. You need to replace the cabwiz.exe command to point to the CabwizSP.exe instead (in a default installation it can be found in C:\Program Files\Windows CE Tools\wce420\SMARTPHONE 2003\Tools). You need to copy vsd_setup.dll from C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\wce400\x96 to C:\Program Files\Microsoft Visual Studio .NET 2003\CompactFrameworkSDK\v1.0.5000\Windows CE\Smartphone\wce400\x86 (for a real device, a copy has to be done with the same file for the ARMV4 processor/folders). When these changes are made and the batch file is run, the cabinet files are generated in a folder beneath the project folder (<project path>/cab/Release). The suffix of each file indicates which processor it targets. This is the Smartphone installation, and if this file is copied to a device and selected (for example, by using a shortcut) the application will be installed.

However, if you take the generated cabinet file and install it on a device, you will notice that the application name is identical to the project name used in Visual Studio .NET. Also, the company name is set to "My Company" which might not be what you wish for. To customize the creation of the cabinet files you have to look in the folder with the batch file (at <project path>/obj/Release). There you will find the setup information file (.inf) used to create the cabinet files. In that file, there are entries for the application and company name used. Here's a sample extract from such a file (excluded sections marked with periods):

[Version]
Signature="$Windows NT$"
Provider="CompanyName"
CESignature="$Windows CE$"

[CEStrings]
AppName="SampleUI"
InstallDir=%CE1%\%AppName%
.
.
[SourceDisksFiles]
SampleUI.exe=1
.
.
[Files.Common]
SampleUI.exe,,,0
.
.
[Shortcuts]
Sample User Interface,0,SampleUI.exe,%CE11%

The name of the project to generate this file was "ProjectName" and in the generated file, the Provider value in the Version section was changed from "My Company" to "CompanyName". Also, note the first value in the Shortcuts section is the name of the shortcut generated, and this should probably be something more readable than the project name. This was just a very brief introduction, as .inf files are a large topic (for more info, see the Visual Studio .NET help file index topic "inf files for device projects").

When updates are made to the .inf file, you can generate a new set of cabinet files by running the batch file (BuildCab.bat) found in the same folder as the .inf file.

Distribution

The easiest way to distribute you application over the air (OTA) is by publishing the cabinet file on a Web page. With the cabinet file created above (here renamed to sampleui.cab), a simple Web page can be created with the following HTML source:

<html>
  <head>
    <title>Download</title>
  </head>
  <body>
    <h2>Download Sample</h2>
    This is where you download the application, just select the
    link to the <a href="sampleui.cab">sampleui.cab</a> file!
  </body>
</html>

When this page is loaded in the Smartphone browser it looks like this:

Figure 10. Download page in Internet Explorer

When the link is selected, a confirmation is needed:

Figure 11. Confirm download

And when the download is confirmed, the following sequence of screens is shown:

Figure 12. Download screens

On a real device and if the cabinet files has not been signed, you will also get a screen where you get a prompt to confirm the installation. And that is pretty much all there is to it.

The application is now installed on the Smartphone and can be uninstalled by choosing Settings and then Remove Programs.

The link to the cabinet file could also be distributed in an e-mail or SMS (Short Message Service) message. Other ways to distribute your application include:

  • Sending the cabinet file as attachment to an e-mail message
  • Setting up a Storage Card that runs the installation package when the card is inserted
  • Using a desktop ActiveSync installation package that include the cabinet file

Here is a picture from the Smartphone 2003 SDK help file that gives a good overview of the different options:

Figure 13. Application distribution options

In a real-world scenario, the best solution is often a combination of different deployment options. Due to bandwidth restrictions, you could have the first-time installation made from a storage card, and then updates could be distributed over the air (OTA).

Signing

Although not necessary when using the emulator to develop Smartphone applications, application signing is definitely something you will need to do once you are deploying to real devices. However, it is possible to create a development certificate by running the command line spdps /device /create in the Smartphone SDK tools folder (in a default installation it is in C:\Program Files\Windows CE Tools\wce420\SMARTPHONE 2003\Tools). If you already have a certificate, use the command spdps /device and pick a certificate from the personal store for privileged application signing.

The security model for Smartphone applications is based on certificates. A device can be configured by the device manager (usually the network operator) to allow only signed applications to run. Whether an application can run or not depends on:

  • If the device has a one- or two-tiered security model
  • The current security mode of the device: Open, Locked, or Prompt
  • How the application was signed: with a privileged certificate, unprivileged certificate, or not at all

One-tiered devices give access to all APIs for applications that are allowed to run. On two-tiered devices, there are APIs that cannot be access unless the application was signed with a privileged certificate.

If the device has an Open security mode, all applications can run, signed and unsigned. If the mode is Locked, only signed applications run on the device. If the mode is Prompt, all signed applications run without a prompt, and the user is prompted to reject or accept all unsigned applications.

For more info, see the Visual Studio .NET help file "Security in Managed Code" section (look for index topic "Managed Code" and subtopic "Security").

Conclusion

This was a first look at the tools you need to use to distribute your managed Smartphone applications. There are several options, and to choose the best solution for your application distribution, you need to evaluate the options carefully.

Enterprise Application Scenarios

A rapidly increasing number of companies have deployed mobile applications in their businesses during 2002 and onwards. The Pocket PC platform, especially including the .NET Compact Framework, has made many mobile workers more efficient realizing cost reductions and revenue increases. As with mobile application development in general, scenarios in which Smartphones are and will be used the most include the following:

  • Sales service
  • Field service
  • Logistics
  • Transportation
  • Decision support

There are number of available technologies and solutions for supporting mobile workers in enterprise scenarios. Laptops, Tablet PCs, Pocket PCs and simpler cell phones have been the only available options for some time. Smartphone 2003 has the .NET Compact Framework integrated into the ROM so a new platform is available for application designers and developers. The new platform's strong solution aspects are its form factor (size), its built-in phone capabilities, its high degree of connectivity (including SMS and Internet), and when viewing information is more important than entering data.

A Smartphone 2003 solution implemented in an enterprise scenario extends information systems and processes to wherever the mobile work happens to be. A mobile and connected application has the ability to increase the efficiency of the process by eliminating manual process steps and reducing number of times data has to be managed by human beings. Information quality increases as a result of less double handling of paper forms and fewer errors are introduced in the mass of data. All these benefits lead to increased efficiency (cost reductions) and customer satisfaction (revenue).

In a field service scenario, the field technician can quickly get new work orders on the road. Out in the field, the field technician can view detailed work order information and when the work is complete easily fill out most of the work order details, leaving details to back office staff to fill out. A typical field service scenario looks like this:

Figure 14. Typical Field Service scenario

The process steps "Perform work" and "Report work" are where a Smartphone application would most likely provide appropriate support. As more Smartphones include built-in cameras, the field technician can even report work by including on-site images for follow-up or remote assistance.

In a decision support scenario, managers and executives can efficiently view and monitor vital business events and high level and up-to-date financial summaries. Since the Smartphone has both SMS and Internet capabilities, the phone can be awakened by an incoming SMS and made automatically to retrieve critical information from company IT infrastructure. The driving theme in decision support solutions is bringing just the right information to the level of management in order to speed up decision making. Smartphone applications can bring many of these solutions into the hands of many different types of companies.

Conclusions

This article was intended to provide information vital to developing phone applications, designing proper user interfaces, planning for application data storage, using and leveraging XML Web services, packaging applications for distribution and learning about key enterprise scenarios suited for Smartphone application development.

The key aspect throughout this article has been how to best use Visual Studio .NET and the .NET Compact Framework support in Smartphone 2003. The new platform is poised for success in both consumer markets and enterprise markets. Combined with appealing design, phone functionality, Internet connectivity and .NET Compact Framework support, the stage is set for you to start realizing your ideas.