Developing Widgets for Windows Mobile 6.5

4/7/2010

Microsoft

June 2009

Summary

Windows Mobile® widgets typically are single-purpose applications to display data obtained from the Internet. They are written using JavaScript and bring the wealth of experience of Web developers to the Windows Mobile platform. Since widgets are installed and run locally on the mobile device, they provide ease of use and a better Internet user experience than conventional Web applications.

Applies To

Windows Mobile 6.5

Introduction

Widgets and Windows Mobile 6.5

Developing Widgets

Creating the User Interface

Localizing Widgets

Using the Widget JavaScript Objects

Creating Widget Menus

Calling AJAX Code

Using Widget Persistence

Using Widget Security

Providing Widget Files

Creating the Manifest File

Creating the Deployment Package

Deploying the Widget

Best Practices

Conclusion

Introduction

Windows® phones offer a rich user experience and a wealth of features for device users on the move. Windows Mobile widgets are applications written using Web development techniques; they connect to Web services to obtain and display data. Widgets can deliver business data, weather information, news updates, traffic maps, and even slide shows of online photo albums. The flexibility of JavaScript and Web development techniques of dynamic markup and style sheets, coupled with the new widget objects mean that Web developers can produce rich applications with the appearance of native Windows Mobile applications.

Starting with Windows Mobile 6.5.3, developers can create Windows Mobile widgets using Visual Studio.

Widgets and Windows Mobile 6.5

A widget is similar in concept to a Gadget for Windows Vista®. HTML markup and cascading style sheets (CSS) provide the user interface, and the code is written in JavaScript. Gadgets brought the wealth of experience of Web developers to the Windows Vista platform, and widgets will do the same for mobile devices. Dynamic HTML (DHTML) is used for dynamic presentation of data to produce a rich interface, while the XMLHttpRequest control is used to load data from the Web. The entire application is scripted using JavaScript. Widgets are installed locally on the mobile device and, like Windows Vista® Gadgets, widgets run locally but can use data dynamically accessed from the cloud.

Windows® phones can access Web applications with Microsoft® Internet Explorer®; however, this can lead to increased network traffic since server-side changes result in page updates that have to be downloaded to the device. Web applications that use AJAX techniques minimize page updates, but still involve an initial download of the application files (scripts, HTML, and CSS). Widgets reduce network access compared to Web applications, because the scripts and style sheets are installed locally. Subsequently, the only network access performed by widgets is for data access. This means fewer network connections than for Web applications, and this is a key design feature for mobile devices that rely on phone networks that charge by packet transfer rates. Further, the widget API that JavaScript objects provide enables widget developers to provide menu and soft key integration, and local caching of data, which is unavailable to Web applications.

AJAX is a mature technology with a vibrant and experienced community of developers. Widgets bring this wealth of experience to the Windows Mobile platform.

Developing Widgets

Web application developers have a smooth transition to widget development because most of the development involves by using the same techniques. Widgets have specific requirements for deployment and localization, and details are given in this section.

Creating the User Interface

Widgets are full-screen applications, but since the user interface is provided through HTML, widgets can use HTML layout to accommodate the form factor of the phone. In addition, the developer can use the document body object to access the screen dimensions and orientation of the device. The widget API also provides notifications for the change in screen orientation (for example, if the device is rotated), and the developer can use this notification to alter the user interface.

Similar to AJAX application development, widget developers can respond to events from controls and other elements on the Web page. A particularly useful feature of Windows Mobile is the support for localization.

Localizing Widgets

Application resources are often specific to a locale. In particular, text should be localized to reflect the language and dialect of the user’s device. When designing an application, you should identify the resources that will be localized and create a separate file for each locale that is supported. For example, a widget that displays currency exchange rates and stock quotes should obtain this information from localized Web sites so that, for example, a user in the United States will see the value of the Dow Jones Index and a user in Great Britain will see the value of the FTSE index.

The following code fragments show excerpts from two files, both called directoryUrls.js. The first file is the default file for the widget. The resource indicates that the https://mny.mobile.msn.com/en-us/default.aspx? Web site should be used for stock quotes. This file is stored in the scripts folder called js in the deployment file. The second code fragment is the localized resource for the en-UK locale (British English). In this case, the stock quotes are obtained from the https://mobile.uk.msn.com/device/mny/default.aspx? Web site. This file has the same name as the default resource, but it is within the localized script folder called en-UK/js. It is important to note that the src attribute of the <script> element in the HTML for the widget is not localized; the src attribute only references the default file in the js folder and Windows Mobile 6.5 will load the appropriate file.

// Default locale, js/directoryUrls.js
var MSN_OCID_PARAM = "ocid=widget_mny_1";
var DirectoryUrls = {
   MSNMoney: "https://mny.mobile.msn.com/en-us/default.aspx?" 
      + MSN_OCID_PARAM
}

// UK locale, en-UK/js/directoryUrls.js
var MSN_OCID_PARAM = "ocid=widget_mny_1";
var DirectoryUrls = {
   MSNMoney: "https://mobile.uk.msn.com/device/mny/default.aspx?" 
      + MSN_OCID_PARAM
}

At run time, Windows Mobile 6.5 checks the locale of the device (for example, en-US or en-UK), and if there is a folder with the name of this locale it will use the localized folder as the base folder for the script files. If the localized folder does not exist, Windows Mobile searches for a folder with the language name (for example, en).

If the device cannot find any localized files, it will load the default files. The widget code is contained in locale-neutral script files. To obtain the URL to use for stock quotes, this code accesses the DirectoryUrls.MSNMoney variable from the localized directoryUrls.js file loaded by Windows Mobile, where it gets a URL appropriate to the locale.

It is important that if you provide localized files you also provide default files. All the widget files can be localized. However, to minimize the size of the deployment package, it is better to localize individual items, as shown above, rather than simply providing a localized copy of each HTML and JavaScript file.

Using the Widget JavaScript Objects

A widget is a stand-alone, locally executed AJAX application, written in JavaScript. The widget can be as simple as a single HTML file with a <script> element or it can be composed of one or more JavaScript files. The HTML file can contain <object> elements and this also means that the widgets can display Flash files. The JavaScript code is subject to the widget security model.

Windows Mobile provides a JavaScript object called widget that gives access to some device system state information and to widget-specific features. The widget object provides some information through properties, and it can also be used to create a state object to provide access to other features. The widget manifest file is an XML file deployed with the widget. It is covered later in this article.

Property Description

authorEmail

The e-mail address of the widget author. This is the email attribute on the <author> element in the widget manifest file.

authorName

The name of the widget author. This is the value of the <author> element in the widget manifest file.

authorURL

The Web site address of the widget author. This is the href attribute on the <author> element in the widget manifest file.

currentIcon

The icon used by the widget. This is an object of type WidgetIcon.

description

The description string for the widget. This is the value of the <description> element in the widget manifest file.

Height

The height, in pixels, of the widget.

Identifier

The id attribute identifier for the widget. This is the uid attribute on the <widget> element in the widget manifest file.

Locale

The locale of the widget. This reflects the setting selected in the Regional Settings dialog box on the device.

Menu

The menu object for the widget. This is an object of type Menu.

Name

The user-friendly name of the widget. This is the value of the <name> element in the widget manifest file.

version

The version of the widget. This is the version attribute on the <widget> element in the widget manifest file.

width

The width, in pixels, of the widget.

The following code example shows how to use the widget properties.

<div id="divData"></div>
<script type="text/javascript">
divData.innerHTML = "The " + widget.name + " widget is localized to " 
   + widget.locale;
</script>

Further system information is obtained through the SystemState object. This object has the following properties.

Property Description

CradlePresent

A Boolean value indicating whether the device is cradled.

DisplayRotation

An integer value indicating whether the display is in portrait or landscape mode.

PhoneHomeService

A Boolean value indicating whether the device is presently registered on its home network.

PhoneOperatorName

A string indicating the name of the device’s mobile operator.

PhoneRoaming

A Boolean value indicating whether the device is currently roaming.

PhoneSignalStrength

An integer indicating the phone signal strength, expressed as a percentage of full strength.

PowerBatteryState

An integer indicating the current state of the battery, such as whether the battery level is critically low or if the battery is charging.

PowerBatteryStrength

An integer indicating the current battery strength, expressed as a percentage of full strength.

The following code shows how to access information about the device.

<div id="divData"></div>
<script type="text/javascript">
var systemState = widget.createObject("SystemState");
divData.innerHTML = "The phone operator name is " 
   + systemState.PhoneOperatorName + " and the signal strength is " 
   + systemState.PhoneSignalStrength;
</script>

You can register an event that will be called when the property changes. To do this, you call the addEventListener method to add a handler function for the changed event on the SystemState property for which you want the notification. For example, using the objects declared in the previous code, you can specify that a function called cradled is called when the device is cradled.

var cradledState = systemState.CradlePresent;
cradledState.addEventListener("changed", cradled);

Most of the widget and SystemState properties are integer or strings, but some are new object types. For example, the widget.currentIcon property is an object of type WidgetIcon with the following properties.

Property Description

height

An integer giving the height of the icon.

src

A string with the URL to the icon file.

width

An integer giving the width of the icon.

The widget.menu is a Menu object and will be covered in the next section.

Creating Widget Menus

A widget can have a menu and it can also define the action of the device soft keys. These tasks are performed through the Menu object.

Beginning with the Windows Mobile 6.5.3 release, touchable tiles replace soft keys. For developers, the change from soft keys to touchable tiles is automatic starting with Windows Mobile 6.5.3. All of the following applies to touchable tiles and to soft keys.

Method Description

append(item)

Appends a MenuItem object to right soft key.

clear()

Clears the contents of the main menu.

createMenuItem(id)

Creates a MenuItem object with the specified integer ID.

getMenuItemById(id)

Returns the MenuItem object with the specified ID.

remove(item)

Removes the specified MenuItem object from the menu.

setSoftKey(item, id)

Assigns a MenuItem object to the soft key with the specified ID.

The soft keys can be assigned with either a single MenuItem object, or a menu made up of one or more MenuItem objects. By default, when the widget starts, the left soft key has the single MenuItem object called Exit (which closes the widget), and the right soft key has a menu that comprises just one MenuItem object that also exits the application. The following illustration shows the right menu displayed when the right soft key is clicked.

Dd721906.166ef41a-bfec-4c67-b03e-e589432bca5f(en-us,MSDN.10).jpg

The preceding illustration applies to widgets created prior to Windows Mobile 6.5.3.

The menu object has two properties, leftSoftKeyIndex and rightSoftKeyIndex that can be used to identify the soft key to assign a menu item using the setSoftKey method.

The following code creates a new menu item by calling createMenuItem. The numeric identifier passed to the method must be unique in this widget code. The menu item is then initialized with the display text and the click event handler function. The code then calls setSoftKey to assign the menu item to the left soft key.

function clickMeHandler() {
   alert("do something");
}   
var menu = widget.menu;
var menu1001 = menu.createMenuItem(1001);
menu1001.text = "Click Me";
menu1001.onSelect = clickMeHandler;
menu.setSoftKey(menu1001, menu.leftSoftKeyIndex);

The following illustration shows the results.

Dd721906.34fcf3ec-f003-4c6e-bd65-68341c0c4aea(en-us,MSDN.10).jpg

If you use the following line instead of the call to setSoftKey, the menu item will be appended to the right menu.

menu.append(menu1001);

The following illustration shows the results.

Dd721906.efaaaf2d-ae98-4eba-8489-0eb6fb533d83(en-us,MSDN.10).jpg

The MenuItem object has a text property that gives the display text and an enabled property that determines whether the menu item can be clicked. The MenuItem object also has a read-only property called id that is assigned by the Menu.createMenuItem function. The click event handler function for a menu item is passed the id of the menu item, so you can write generic handler functions that handle more than one menu item. The MenuItem also has an append and a remove method to add child menu items.

Using the clear, append, remove and setSoftKey methods on the Menu object, and the append and remove methods on the MenuItem object, you can build up complex multilevel menus. When a menu item has child items, the menu item's click handler opens the child menu rather than calling the handler you specify.

Calling AJAX Code

The widget code can use the XMLHttpRequest object to access data asynchronously from the Internet, and can then use the XML DOM to parse the returned data. The following is a simple form to request a stock symbol and display the symbol value on the page.

<div id="divQuote">Quote</div>
<form>
   Stock symbol (eg US:MSFT) <input type="text" id="iSymb" />
</form>

The onClick function is a handler for a menu item click to obtain a stock quote.

function onClick() {
  var xmlhttp = null;
  if (window.XMLHttpRequest) {
      xmlhttp = new XMLHttpRequest();
  }
  if (xmlhttp) {
     createRequest(xmlhttp, document.getElementById("iSymb").value);
  }
}

This function creates an XMLHttpRequest object and then calls a function called createRequest passing the object and the symbol name.

function createRequest(xmlhttp, symb) {
   var url = "https://blu.services.stub.msn.com/"   
      + "StockQuotes.aspx?symbols=" + symb;
   xmlhttp.open("GET", url);
   xmlhttp.onreadystatechange = function() {
       if (xmlhttp.readyState == 4) {
           harvestResults(xmlhttp);
           delete xmlhttp;
       }
   };
   xmlhttp.send();
}

The call to the XMLHttpRequest.open method creates an asynchronous request to the MSN stock quote service passing the stock symbol. The actual request is made when the send method is called. The onreadystatechange event is raised when the request returns. The stock quote service returns an XML document with one or more stock quotes, and this data is parsed by the harvestResults function.

function harvestResults(xmlhttp) {
  if (xmlhttp.status == 200) {
     var xmldoc = xmlhttp.responseXML;
     if (xmldoc) {
        var quoteList = xmldoc.getElementsByTagName("ticker");
        if (quoteList != null && quoteList.length > 0) {
           divQuote.innerText = quoteList[0].getAttribute("name") 
              + " $" + quoteList[0].getAttribute("last");
        }
     }
  }
}

The responseXML property returns the data as an XML Document Object Model (DOM) object. The remainder of the code uses the DOM to obtain the first <ticker> element, and from this obtains the full name of the company and the last value of the stock.

A widget running this code enables the user to request individual stock quotes, and the widget will display the code onscreen.

Using Widget Persistence

Widget security denies access to common Windows Mobile persistence mechanisms (for example, the file system and Microsoft SQL Server® Compact Edition databases). Persisting information between runs of a widget is a useful feature, so the widget API provides a persistence mechanism that enables storage of simple string information. The data persistence is isolated so that a widget can only read the data that it has stored. However, it is important to point out that the storage mechanism does not encrypt the data, so another non-widget application (native or managed code) could have access to the data.

To store data, a widget calls the setPreferenceForKey method on the widget object.

var symbol = document.getElementById("iSymb").value;
widget.setPreferenceForKey(symbol, "SYMBOL");

The previous code stores the last stock symbol requested. The code can read the value with the preferenceForKey method.

var symbol = widget.preferenceForKey("SYMBOL");

The values stored with this mechanism persist until the next time that the widget runs, and it will be available after a reset. The mechanism should be used for relatively small values since there is a limit of 4000 bytes per key.

Using Widget Security

Security is vital in every application, but it has an increased significance in code that can be installed over a network and whose functionality depends on data from the Internet. Windows Mobile widgets run under Internet Explorer and are subject to the Internet Explorer Sandbox. This means that the widget cannot access personal data on the device, so information like contacts, the e-mail message store, the registry, and the file system are not accessible to widgets. Furthermore, by default, network access is denied to the widget unless the widget manifest file requests this privilege through the <access> element in the manifest file.

<access network="true" />

Internet Explorer security policy is maintained. Data maintained by Internet Explorer, like cookies, the cache, and the history list are isolated to each widget and the history and the cache are cleared every time the widget starts.

Special exceptions are made to relax the sandbox, but these still maintain widget security. Although the widget cannot access files in general, it may access files in the home folder and the folder beneath it using the src attribute of relevant HTML elements (for example, <img> for image files). The security sandbox enables navigation through some special protocols like mailto:, sms:, callto:, and tele:, but in these special cases the navigation is delegated to the device process responsible, and the user will be able to cancel any action being taken.

The device is protected from installing rogue code. First, users will only be able to install a widget from the Internet through Microsoft Windows Marketplace for Mobile and can therefore authenticate the source of the code. Second, the user is notified during the installation process and approval is requested, so when the user installs a widget he will get a page displaying information from the widget manifest describing the widget and the page will request permission to install the code. Furthermore, some security checks are made before the widget runs. For example, if the widget manifest indicates that the widget requires network access, the device displays a warning dialog box indicating that network access could incur call plan costs. The user gets the option to continue running the widget or to exit.

Providing Widget Files

Widgets must contain one HTML file for the user interface. This start file is named in the widget manifest using the <content> element. The start file can contain style elements and scripting to support the widget functionality, but typically the start file references separate CSS files and scripts through the <style> and <script> elements. Widgets support localization of resources and code, and Windows Mobile loads the localized files if they are present. All of these additional files are provided within the widget folder. The following table summarizes the types of files within a widget folder.

File Type Mandatory Description

<widget>.html

Yes

The start file for the project. <widget> is the name of the widget as given by the widget manifest file.

config.xml

Yes

An XML file containing the metadata for the widget.

*.ico, *.png, *.jpg

Yes, at least one

The icon to be used for the widget in the Start menu of the mobile device. The icon file is mentioned in the widget manifest file. Windows® phones that run only support .ico files, while Windows® phones that run files support all three formats.

*.js

No, but preferred

JavaScript files containing the code for the widget.

*.css

No, but preferred

Style sheets for the widget.

Resource files: .jpg, .png, and more

No

Additional resources.

Creating the Manifest File

Each widget must have a manifest file. This is an XML file called config.xml containing a root element called <widget>. The manifest file contains information about the widget including data that may be localized, so the manifest may be within the localization folders. However, even if you use localized versions of the manifest file, it is prudent to place a default copy of the manifest file in the root of the widget folder to be used as the default if the device has a locale that is not handled. The <widget> element in the manifest file must have the name of the start file; other elements are optional but recommended. The following is a minimal manifest file.

<?xml version="1.0" encoding="utf-8" ?>
<widget xmlns="https://www.w3.org/ns/widgets" version="1.0">
   <content src="StartUp.htm" type="text/html" />
</widget>

This manifest indicates that the start file is called StartUp.htm. If the device Regional Settings are set to English (United States), the locale is en-US, so when the device runs the widget, it first looks for a file called StartUp.htm in the en-US folder. If the folder does not exist, or the file is not in that folder, the device looks for a file called StartUp.htm in the en folder and if that file does not exist, the device loads StartUp.htm from the root folder.

Another localized file is the icon file. Windows® phones that run  devices can only use .ico files, while other phones can also use .png and .jpg files.

The following table lists the elements that can be used in the <widget> element.

Element Description

<access>

This element indicates the network requirements of the widget. If the network attribute has a value of true, the widget must have permission from the user for network access before the widget is run.

<author>

This element contains information about the author of the widget. The optional attributes are: href, a URL to the author’s site; email, the author’s e-mail address; and img, a graphic associated with the author.

<content>

This element is required. The src attribute gives the path to the start file.

<description>

This element describes the widget; the description is displayed during installation of the widget.

<icon>

This element gives the name of the file to be used for the widget icon in the Start menu. The src attribute gives the name of the file.

<name>

This element gives a user-friendly name of the widget. This name is displayed in the Start menu and in the Remove Programs page.

Some of the manifest values can be accessed by the widget code using properties of the widget object.

Creating the Deployment Package

A design goal of Windows Mobile widgets is to provide a single download deployment package. The package is a standard zip file with the extension changed from .zip to .widget. You can use any name for this file, but best practice is to use the name of the widget. If you do not provide the name of the widget in the manifest file, the widget installer uses the name of the deployment file as the name of the widget on the device.

Within the zip file are all the files that the widget needs to run: Web pages, icon graphics files, style sheets, JavaScript files, and other resources. These files are stored in the zip file using the same folder structure as will be used by the widget, that is, if your widget uses localization, the zip file contains the locale folders containing the localized files and folders as explained earlier.

Deploying the Widget

The current version of Windows Mobile widgets supports two deployment modes: Marketplace and sideload deployment. Marketplace is an online application store intended to be a one-stop shop for purchasing Windows Mobile applications.

Developers can use sidelong deployment from the desktop development workstation. To do this, the developer copies the widget deployment file to the device and then runs the widget file on the device. This deployment method works out of the box for the emulator image, but for actual devices the developer must add the following registry keys to the registry of the device.

[HKEY_CLASSES_ROOT\riapp]
    "EditFlags"=dword:00010000
[HKEY_CLASSES_ROOT\riapp\Shell\Open\Command]
    @="wmwidgetinstaller.exe %1"

Without these keys, the Windows® phone does not recognize that there is a file association with the .widget file.

The widget installer extracts the files from the widget file and puts them in a location below \Program Files. Then the installer adds the widget icon to the device Start menu and provides uninstall information so that the widget can be removed through the Remove Programs application. After the widget is installed, the widget files are accessible through a subfolder under the \Program Files\Widgets\User folder. This means that when you develop your application, you only need to deploy the .widget file one time, and when you change files you can copy them directly from the development workstation to the device using Windows Explorer.

Best Practices

The SystemState object enables you to poll for the system values and take appropriate actions; it also enables you to register an event handler that is called when a specific value changes. You can use these values to monitor the battery life and the presence of a network and change the behavior of your code accordingly. For example, if your widget updates the display with information from the Internet, you may choose to disable this update when there is no network present. The widget object has two properties called onshow and onhide that you can assign to functions that will be called when the widget is shown or hidden, and you may choose to disable all network access when the widget is hidden and resume the access when the widget is shown.

The rationale behind the "asynchronous" term in AJAX is that network calls take time, and so network calls can be made asynchronously to the user interface code. It is frustrating for users to wait while the user interface updates, especially when the widget first starts. You can mitigate for this network latency by caching important values using the persistence APIs; when the widget starts up, you can display these cached values. At the same time, your code can be performing the asynchronous request, and when the request completes you can use the new data to update the user interface.

Cached values can also be used to limit the amount of network calls that are made by checking the cache for key data values and only reading them from the network if such values are not in the cache. This is particularly useful for cell phone networks where the user is charged for each packet sent and received. Similarly, you can cache user input so that the cached values are used on subsequent runs of the widget, rather than requesting the user for them.

You can use style sheets and DHTML to produce a rich user interface, and in addition, you can use the widget API to create menus and assign menus to the soft keys so that a widget can have a native appearance on the phone.

Conclusion

Windows Mobile 6.5 brings widget development to the mobile device. With the rich features of Web development and fast application development of JavaScript, widgets offer a compelling new way to produce rich applications with the appearance and behavior of native Windows Mobile applications.

Additional Information

The following explains the packaging of widgets, a description of the contents of the package and widget metadata.

Widgets 1.0: Packaging and Configuration, W3C Working Draft 22 December 2008.

The following lists the W3C requirements for the Widget standard:

Widgets 1.0: Requirements.