Colin Eberhardt's Technology Adventures

A Simple Multi-Page Windows Phone 7 PhoneGap Example

December 15th, 2011

This blog post shows how you can use PhoneGap to create Windows Phone 7 applications that are comprised of multiple, simple HTML pages, whilst meeting the Marketplace certification requirements.


Colin Eberhardt is a Scott Logic technical Evangelist and a Technical Architect for Visiblox, suppliers of high-performance WPF and Silverlight charts.

Readers of my blog will know that I have been working on, and writing about, the use of PhoneGap to create HTML5-based Windows Phone 7 applications. Along the way I have solved problems such as back-button support, tombstoning and suppressing browser pan and zoom. So far the applications I have discussed have all been single-page JavaScript applications, i.e. the WebBrowser control loads a single HTML page which links to the application JavaScript. All subsequent navigation involves updating the DOM dynamically rather than navigating to a new URL. However, I have had numerous questions to my previous blog posts from people who are using PhoneGap to create simple navigation-based applications. In this context PhoneGap is being used as a mechanism for packaging up a collection of relatively static HTML pages.

So why would you want to do this? This is a perfectly valid question! If you have static HTML based content why not simply put it on the web? There are a few reasons, one is to ensure that the content is always available, whether the phone is connected to a network or not. Another is monetization, the app-store model provides an easy way to charge for this content. Regardless of the pros and cons, based on the feedback my previous articles have received, people are very interested in using PhoneGap as a model for packaging static content.

In this blog post I will show how to solve the problems of back-button support and pan / zoom for a simple navigation-based HTML application. As an example, I have chosen a subject which I have a lot of interest in … sandwiches! I have previously blogged about SandwichFlow, an example application which showcased my metro-in-motion series, here I have transformed the sandwich recipe HTML into a collection of static HTML pages.

Packaging the HTML

My first PhoneGap blog post detailed how to get up-and-running with PhoneGap, if you have never used this framework before I would recommend that you read that first. Packaging my sandwich recipe content into an application was simply a matter of copying the files (HTML and CSS) into the ‘www’ directory, running the T4 template that auto-generates the GapSourceDictionary.xml, building and running. The resulting application is as follows:

PhoneGap does a great job of making it very easy to package HTML content into an application, loading the files into isolates storage etc … However, there are a few Windows Phone 7 specific concepts that have to be supported in order to ensure certification on submission to the marketplace.

Back-button Support

UPDATE: There are a few issues with the code below. See my more recent blogpost for an improved solution.

Correct back-button support is a mandatory requirement for marketplace certification. Hitting the back button should navigate back through the various screens of an application. Hitting the back-button on the first screen should terminate the application. The standard PhoneGap Visual Studio template does not support the back-button by default, this no-doubt reflects the fact that the other PhoneGap platforms (iPhone, Android, BlackBerry) do not share this same requirement, or lack a back-button altogether.

In my previous blog post on back-button support I described how a single-page JavaScript application can manage its own back-stack. This approach does not work for navingation-based HTML applications.

The WebBrowser control which PhoneGap uses to render its contents stores its navigation history in the same way that a desktop browser does. This history can be accessed via the JavaScript ‘history’ object. If the back-button is pressed after navigating to one of the packaged HTML pages, invoking history.go(-1) will cause the WebBrowser control to navigate backwards. All we need to do is to keep track of navigation events to determine whether to route the back-button too our HTML application or not.

The following utility class does just that:

/// <summary>
/// Handles the back-button for a PhoneGap application. When the back-button
/// is pressed, the browser history is navigated. If no history is present,
/// the application will exit.
/// </summary>
public class BackButtonHandler
{
  private int _browserHistoryLength = 0;
  private PGView _phoneGapView;
 
  public BackButtonHandler(PhoneApplicationPage page, PGView phoneGapView)
  {
    // subscribe to the hardware back-button
    page.BackKeyPress += Page_BackKeyPress;
 
    // handle navigation events
    phoneGapView.Browser.Navigated += Browser_Navigated;
 
    _phoneGapView = phoneGapView;
  }
 
  private void Browser_Navigated(object sender, NavigationEventArgs e)
  {
    if (e.NavigationMode == NavigationMode.New)
    {
      _browserHistoryLength++;
    }
  }
 
  private void Page_BackKeyPress(object sender, CancelEventArgs e)
  {
    if (_browserHistoryLength > 1)
    {
      _phoneGapView.Browser.InvokeScript("eval", "history.go(-1)");
      _browserHistoryLength -= 2;
      e.Cancel = true;
    }
  }
}

Note: I have had a number of requests from readers who do not have any C# / Silverlight experience, so are unsure how to use code snippets like the one above. In this blog post I have included the full sourcecode. Just grab the code and replace the contents of the ‘www’ directory with your own content, and you are good to go!

With the above code in place the application now supports the back-button

With this feature in place you should be able to successfully submit a PhoneGap based application to the Windows Phone 7 marketplace. The other bits of code that follow are all about improving the cosmetics.

Suppressing Pan and Zoom

Whilst the viewport metadata settings can be used to prevent scaling, the cosmetics of this feature are not terribly good with Windows Phone 7, the user can still ‘pinch’ your HTML page, however, it snaps back to its original scale when the manipulation ends. I previously published a simple class which can intercept manipulation events in order to suppress the pinch zoom behaviour.

This class can also ‘lock’ the browser windows entirely, supressing scroll as well as zoom. However, this is only appropriate for use on pages where you can be sure the content fits entirely within a single page. In order to ‘activate’ this behaviour we need to send a message from the HTML / JavaScript to the C# utility class. The ’about’ page of this application does just that. When it is loaded the following JavaScript is executed:

<script type="text/javascript" charset="utf-8">
  // ensure that this page does not scroll
  window.external.Notify("noScroll");
</script>

The utility class (described in the earlier blog post) is instantiated in code-behind, with the above Notify being used to ‘lock’ the page:

private WebBrowserHelper _browserHelper;
 
// Constructor
public MainPage()
{
  InitializeComponent();
 
  new BackButtonHandler(this, PGView);
  _browserHelper = new WebBrowserHelper(PGView.Browser);
 
  PGView.Browser.ScriptNotify += Browser_ScriptNotify;
  PGView.Browser.Navigated += Browser_Navigated;
}
 
private void Browser_Navigated(object sender, NavigationEventArgs e)
{
  // when we first navigate to a page, we assume that it can be scrolled
  _browserHelper.ScrollDisabled = false;
}
 
private void Browser_ScriptNotify(object sender, NotifyEventArgs e)
{
  // if a page notifies that it should not be scrollable, disable
  // scrolling.
  if (e.Value == "noScroll")
  {
    _browserHelper.ScrollDisabled = true;
  }
}

Again, the code above is included in the download at the end of this article. To ‘lock’ the scroll on any of your HTML pages, simply add the JavaScript ‘Notify’ above.

Splashscreen

One final cosmetic issue is the application startup. The application splashcreen is hidden automatically when your application starts up. This is fine for a native application, however a PhoneGap application isn’t quite ready at this point. After the native wrapper starts, the code is loaded into the WebBrwoser control and the HTML / JavaScript application starts. This results in a rather ugly white screen appearing for ~ 0.5 second when the application starts up.

The start screen duration is not configurable, however, there is a simple solution to this problem, when the application first starts, render the splashscreen as the application content, then hide this image when the PhoneGap application starts.

To do this, create an image and position it in front of the PhoneGap browser control:

<Grid x:Name="LayoutRoot" Background="Transparent">
 
  <my:PGView HorizontalAlignment="Stretch" 
                  Margin="0,0,0,0"  
                  Name="PGView" 
                  VerticalAlignment="Stretch"/>
 
  <Image Source="/SplashScreenImage.jpg"
          x:Name="splashImage">
    <Image.Resources>
      <Storyboard x:Name="fadeOut"
                  BeginTime="0:0:0.5"
                  Completed="fadeOut_Completed">
        <DoubleAnimation
                Storyboard.TargetName="splashImage"
                Storyboard.TargetProperty="Opacity"
                From="1.0" To="0.0" Duration="0:0:0.3"/>
      </Storyboard>
    </Image.Resources>
  </Image>
</Grid>

This image has a storyboard that fades-out the image.

This animation is triggered when the browser navigates to the first age of the application:

EventHandler<NavigationEventArgs> hideSplashScreen = null;
hideSplashScreen = (s, e ) =>
  {
    fadeOut.Begin();
    PGView.Browser.Navigated -= hideSplashScreen;
  };
PGView.Browser.Navigated += hideSplashScreen;

Finally, the Completed event handler removes the image altogether when the animation ends:

private void fadeOut_Completed(object sender, EventArgs e)
{
  splashImage.Visibility = Visibility.Collapsed;
}

Conclusions

Hopefully this blog post will help people who are new to WP7 and wish to release PhoneGap applications comprised of multiple HTML pages.

You can download the sourcecode: HTML5SandwichFlow.zip

Regards, Colin E.

Handling the back-stack in Windows Phone 7 PhoneGap applications

November 28th, 2011

Recently I have been researching the use of PhoneGap for creating HTML5 Windows Phone 7 applications. I have written an introductory post on the subject and also managed to have a HTML5-based application accepted into the marketplace.

The Windows Phone 7 execution model has a few unique features (when compared to Android and iOS) that need to be considered when developing HTML5 applications. The first one, tombstoning, is something I dealt with in an earlier blogpost. In this post I want to look at how to handle the back-button and the application back-stack.

With Windows Phone 7, as the user navigates from one page to the next, the latest page is added to the top of a stack (the back-stack). The back-button is used to navigate back through the pages within your application by pulling them from the top of this stack. When the back stack holds a single page, i.e. the initial entry point into your application, pressing the back-button should exit the application.

So, how do you support this with a HTML5 / PhoneGap application? The PhoneGap APIs expose the back-button as a JavaScript event. If you subscribe to this event, your JavaScript code is notified each time the user hits the back button. Also, if the JavaScript event is subscribed to, the ‘native’ (C#) event is cancelled, which means application back-stack remains unchanged and your PhoneGap application does not exit.

In order to emulate the back-stack functionality in a PhoneGap application you need to subscribe to the PhoneGap backbutton when back-navigation is possible within your application, and unsubscribe when it is not. This means that when the user hits the back-button at the entry-point of your application, the application is terminated as expected.

A JavaScript Back-Stack

In order to handle the PhoenGap backbutton event, I felt the easiest approach would be to structure my JavaScript application so that it more closely resembles a Windows Phone 7 application. I have already discussed in my blog post on tombstoning how this task was made easier by using KnockoutJS to structure my code using the Model-View-ViewModel (MVVM) pattern.

In this blog I’ll add further structure to the code, starting with an ApplicationViewModel. This view model contains a stack of view-models, with the one that is at the top of the stack, exposed via the currentViewModel observable property, being the one which is rendered on screen. The ApplicationViewModel also exposes functions for adding to and removing items from this stack:

function ApplicationViewModel() {
 
  var that = this;
 
  this.viewModelBackStack = ko.observableArray();
 
  this.backButtonRequired = ko.dependentObservable(function () {    
    return this.viewModelBackStack().length > 1;
  }, this);
 
  this.currentViewModel = ko.dependentObservable(function () {
    return this.viewModelBackStack()[this.viewModelBackStack().length-1];
  }, this);
 
  this.navigateTo = function (viewModel) {
    this.viewModelBackStack.push(viewModel);
  }
 
  this.back = function () {
    this.viewModelBackStack.pop();
   }
}

The currentViewModel is implemented as a dependent-observable, a really neat KnockoutJS feature where you create a new observable property based on one or more observable properties of a view model. In this case, KnockoutJS does some magic behind the scenes to deduce that
currentViewModel depends upon the viewModelBackStack observable array. Each time the array is modified, bindings that depend on currentViewModel are also updated. That’s pretty neat!

The UI code needs to be modified so that the view relating to the currentViewModel is rendered and bound to its respective view model. This is simply a matter of subscribing to changes in this observable property in our code:

// create the view model
application = new ApplicationViewModel();
 
application.currentViewModel.subscribe(function (viewModel) {
  if (viewModel !== undefined) {
    $("#app").empty();
    $("#" + viewModel.template).tmpl("").appendTo("#app");
    ko.applyBindings(viewModel);
  }
});
 
application.navigateTo(new TwitterSearchViewModel());

For the above code to work, each view model must expose a template property which identified the HTML template which is their corresponding view. The above code creates a view instance and appends it to the #app element.

The templates for the two view-models within this application are shown below:

<script type=text/x-jquery-tmpl" charset="utf-8" id="twitterSearchView">
  <div>
    <form data-bind="submit: search">
        <input data-bind="value: searchTerm, valueUpdate: 'afterkeydown'" />
        <button type="submit" data-bind="enable: searchTerm().length > 0 && isSearching() == false">Go</button>  
    </form>
    <ul data-bind="template: {name: 'tweetView', foreach: tweets}"> </ul>
  </div>
</script>
 
<script type="text/x-jquery-tmpl" charset="utf-8" id="tweetView">
  <li class="tweet"
    data-bind="click: select">
    <div class="thumbnailColumn">
      <img data-bind="attr: { src: thumbnail }" class="thumbnail"/>
    </div>
    <div class="detailsColumn">
      <div class="author" data-bind="text: author"/> 
      <div class="text" data-bind="text: text"/> 
      <div class="time" data-bind="text: time"/> 
    </div>
  </li>
</script>
 
<script type="text/x-jquery-tmpl" charset="utf-8" id="tweetDetailView">
  <div class="tweet">
    <div class="thumbnailColumn">
      <img data-bind="attr: { src: thumbnail }" class="thumbnail"/>
    </div>
    <div class="detailsColumn">
      <div class="author" data-bind="text: author"/> 
      <div class="text" data-bind="text: text"/> 
      <div class="time" data-bind="text: time"/> 
    </div>
  </div>
</script>
 
<h1 id="welcomeMsg">Twitter Search</h1>   
<div id="app" />

When a tweet is clicked on, the select function is invoked via the Knockout binding. This simply pushes a TweetViewModel instance onto the application stack:

this.select = function () {
  application.navigateTo(this);
};

Handling the Back-Button

The above code navigates to the given view model, this will cause the currentViewModel dependent observable to notify that a change has occurred and the view that relates to this view model will be rendered. The next step is to wire up the back-button.

The ApplicationViewModel has a boolean backButtonRequired dependent observable that indicates whether the JavaScript code needs to handle the back-button. This is true whenever there is more than one item in the back-stack:

this.backButtonRequired = ko.dependentObservable(function () {    
  return this.viewModelBackStack().length > 1;
}, this);

When the application is initially created, we handle changes to the observable as follows:

application.backButtonRequired.subscribe(function (backButtonRequired) {
  if (backButtonRequired) {
    document.addEventListener("backbutton", onBackButton, false);
  } else {
    document.removeEventListener("backbutton", onBackButton, false);
  }
});
 
function onBackButton() {
  application.back();
}

And that’s it! When the JavaScript back-stack has more than one item, the PhoneGap backbutton event is handled and the back function invoked on our application, popping the top item from the stack, with the view updating accordingly. When our JavaScript back-stack has a single item, we no longer handle the PhoneGap backbutton event, this results in the Silverlight container handling the back-button. The Silverlight application back-stack always has a single page, so our application will exit.

This technique for handling the back-stack is simple and elegant, this example has just two simple pages, however this same pattern should scale well for more complex HTML5 applications.

You can download the full sourcecode here: PhoneGapBackStack.zip

Regards, Colin E.

Suppressing Zoom and Scroll interactions in the Windows Phone 7 WebBrowser Control

November 17th, 2011

This blog post describes a simple helper class that can be used to supress scrolling and pinch zoom of the Windows Phone 7 WebBrowser control.


Colin Eberhardt is a Scott Logic technical Evangelist and a Technical Architect for Visiblox, suppliers of high-performance WPF and Silverlight charts.

Developers of Windows Phone 7 application have the full power of IE9 at their disposal in the shape of the WebBrowser control. This control allows you to render both local and remote HTML and JavaScript content within your Silverlight applications. You will find this control used to great effect in RSS readers and Twitter applications such as Rowi, where websites are viewed from within the application rather than by launching the full-blown IE. The WebBrowser control is also used as the host / container for HTML5 based applications, such as Property Finder, the PhoneGap-based application I developed recently.

One problem them people frequently hit against with the WebBrowser control is managing the manipulation events. For example, if you place a WebBrowser control within a Pivot control, how can you pass the horizontal swipe gesture form the WebBrowser to the Pivot?

With HTML5 applications you have a certain amount of control over the browser’s pan and zoom behaviour via the viewport metadata HTML element:

<meta name="viewport" content="user-scalable=no" />

Adding the above meta-tag to a HTML page will prohibit the user from zooming via the pinch gesture. However, it does this in a rather clumsy way – the user can still pinch the page, but when they release, it snaps back to its original scale.

Whilst this might be OK in some contexts, for a HTML5 application where intention is to replicate the feel of a native application as closely as possible, this is just not good enough. Another little browser quirk that has a similar effect is the scroll behaviour. Even if a page fits entirely within the area occupied by the WebBrowser control, they can still scroll the content. Again, it simply snaps back to its original location.

The Solution

I initially thought that there would be no way for me to control the behaviour of the WebBrowser control, it is after-all a very thin .NET wrapper around a native control. However, I stumbled across some StackOveflow answers from quetzalcoatl who had done some digging around in the .NET wrapper and had identified an interesting control called the PanZoomContainer.

If you inspect the visual tree of the WebBrowser control you will find that it is assembled as follows:

\-WebBrowser
  \-Border
    \-Border
      \-PanZoomContainer
        \-Grid
          \-Border (*)
            \-ContentPresenter
              \-TileHost

(visual tree dump generated via the oh-so-useful Linq to VisualTree utility!)

The visual tree is quite simple, composed of a few grids and borders. The significant parts are the TileHost, which is the native IE9 component, and the PanZoomContainer. The TileHost does not handle the mouse manipulation events, these are instead handled by the PanZoomContainer, where they are then translated into gestures (i.e. pinch-zoom) with the result fed back to the TileHost.

What this means is that we can intercept the manipulation events as they bubble up to the PanZoomContainer, cancelling them before they are turned into gestures.

The utility class which I have written handles the events on the Border indicated above. When events are received various conditions are checked to identify pan or scroll interactions, with the events being cancelled accordingly.

The complete class is given below:

using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using LinqToVisualTree;
using Microsoft.Phone.Controls;
 
/// <summary>
/// Suppresses pinch zoom and optionally scrolling of the WebBrowser control
/// </summary>
public class WebBrowserHelper
{
  private WebBrowser _browser;
 
  /// <summary>
  /// Gets or sets whether to suppress the scrolling of
  /// the WebBrowser control;
  /// </summary>
  public bool ScrollDisabled { get; set; }
 
  public WebBrowserHelper(WebBrowser browser)
  {
    _browser = browser;
    browser.Loaded += new RoutedEventHandler(browser_Loaded);
  }
 
  private void browser_Loaded(object sender, RoutedEventArgs e)
  {
    var border = _browser.Descendants<Border>().Last() as Border;
 
    border.ManipulationDelta += Border_ManipulationDelta;
    border.ManipulationCompleted += Border_ManipulationCompleted;
  }
 
  private void Border_ManipulationCompleted(object sender,
                                            ManipulationCompletedEventArgs e)
  {
    // suppress zoom
    if (e.FinalVelocities.ExpansionVelocity.X != 0.0 ||
        e.FinalVelocities.ExpansionVelocity.Y != 0.0)
      e.Handled = true;
  }
 
  private void Border_ManipulationDelta(object sender,
                                        ManipulationDeltaEventArgs e)
  {
    // suppress zoom
    if (e.DeltaManipulation.Scale.X != 0.0 ||
        e.DeltaManipulation.Scale.Y != 0.0)
      e.Handled = true;
 
    // optionally suppress scrolling
    if (ScrollDisabled)
    {
      if (e.DeltaManipulation.Translation.X != 0.0 ||
        e.DeltaManipulation.Translation.Y != 0.0)
        e.Handled = true;
    }
  }
}

Within Property Finder, my HTML5 application, as the user navigates from one page to the next, the JavaScript code notifies the Silverlight container whether the current page should have scrolling disabled, setting the ScrollDisabled property of the above helper class accordingly.

I hope other people find this simple utility class useful. To use it, just cut and paste the code given above. Note, it uses Linq to VisualTree to navigate the WebBrowser visual tree, so you will need to go and grab that also.

Regards, Colin E.

Property Finder – the first HTML5-based Windows Phone 7 Application

November 7th, 2011

Last week I submitted Property Finder, a simple application that searches for properties based in the UK, to the Windows Phone 7 Marketplace. I was happy to receive confirmation that this application had been certified and published just two days later.

You can download the application from the marketplace now.

You can also watch a video of Property Finder on YouTube.

Property Finder isn’t your regular Silverlight-based application, it is written with HTML5 / JavaScript. It was made possible by the following technologies and APIs:

  • PhoneGap – a framework that hosts JavaScript / HTML code within a native wrapper. This wrapper allows you to write cross-platform mobile applications which can be distributed within the Windows, Apple and Android marketplaces.
  • KnockoutJS – An MVVM framework. The structuring that this framework imposes makes it much easier to handle tombstoning and persistence.
  • Nestoria APIs – A property search API which provides a JSON interface.
  • jQuery – everyone’s favourite JavaScript UI framework.
  • jQuery-JSONP – A very small library that provides a much better JSONP implementation than the one provided by jQuery.

I have already written a couple of blog posts about PhoneGap / Windows Phone 7, including one which introduces the basic concepts, and a second one which tackles the problem of tombstoning. I plan to write a few more blog posts about how Property Finder was implemented, covering topics such as back-stack handling and how to disable the WebBrowser control’s pinch / scroll behaviours.

Why HTML5?

So why did I go to all this bother of implementing this application using HTML5? Why not write it in Silverlight instead?

There is one simple answer to that question – HTML5 is cross-platform. The code I have written for this application will work eqally well on a desktop browser, or within a browser-control on other mobile phoen devices (Android, iPhone, …). If you look at the current smartphone market-share, Android has suddenly leaped into the lead with WP7 a long way behind. Fortunately for WP7 developers, Gartner predicts a promising future, with a significant market-share by 2015. Also, recent analysis predicts WP7 will make a lot of impact in the enterprise.

However, whether these predictions are right or wrong, the one thing you can be sure of is that the future smartphone market will not be dominated by a single OS. Now and in the future, if you want to make your applications available to smartphone users in general, rather than the users of a specific smartphone model, you have to either write your application multiple times, once for each OS, or use a cross-platform technology.

Will the user-experience suffer?

This is a big question. Developing WP7 applications with Silverlight makes it easy to create the authentic Metro theme, however, most of the libraries for creating HTML5-mobile UIs focus on immitating the iPhone look and feel.

The easy option when creating a cross-platform HTML5 mobile application is to use the same UI across each platform. Whilst I can imagine Android users being happy with the iPhone look that jQuery Mobile presents, I have a feeling that WP7 users would reject it. I wanted to see how close I could get to something which looks authentic. Opinions so far seem to indicate that I have come close …

But perhaps not close enough …

The phrase “the user’s dog is barking” was new to me, but I think describes Property Finder quite well!

With the use of KnockoutJS the presentation (View) is separate from the logic (ViewModel), which means that it should be possible to change the view for Property Finder to make it look like an iOS application, with minimal effort. This is something I plan to do in the near future, releasing it on iTunes for Apple devices shortly.

Regarding productivity, once I got into the swing of JavaScipt / Knockout development, I found that I was quite productive. Most of the development work takes place within the browser, in my case, using FireFox and Firebug. Whilst the developer tooling is not great, the process itself is quite rapid; you can edit your code and have it up and running within your browser in less than a seconds!

Loose ends

Property Finder shows a lot of promise, however, it is not quite ready for putting in front of end users yet. There are a couple of technical issues that still need to be resolved before this application, and HTML5-based WP7 applications in general, are ready for prime-time:

The IE9 gray-boxes

If you download the application, or watch the video closely, you will notice that every time you click on a button, and image or the app-bar, a small gray rectangular overlay is render. This totally spoils the illusion I am trying to create! I have asked on the Microsoft Windows Phone Blog, asked on StackOverflow and raised an issue against PhoneGap, but to no avail.

If someone from Microsoft is reading this, please address this issue! It will seriously hamper the use of HTML5 for web-applications on Windows Phone 7. (And after you have fixed that, please add CSS 3D transforms, and transitions – thanks!)

Device capabilities

Before submitting my application to the marketplace I was careful to detail its capabilities, listing it as requiring:

Network access, Web browser, geolocation

However, one of the first people to download the application informed me that the ‘my location’ button was not working. On checking my listing on the marketplace I discovered the following list of application capabilities:

data services, movement and directional sensor, microphone, music and video library, owner identity, camera, contacts, camera, compass

All kinds of phone features that I was not using, minus geolocation, which I was! So what is going on here?

When your application is submitted to the marketplace, static code analysis is used to determine the phone capabilities used. Because my application includes the PhoneGap assembly, which provides JavaScript APIs for camera, compass, contacts etc … my application was listed as using these phone features, even though my application doesn’t actually use them!

So why is geolocation not listed? This is because PhoneGap does not supply a geolocation API, instead I am using the HTML5 geolocation APIs which are supported by the WebBrowser control directly. It appears that the tools the marketplace team use to detect application capabilities does not ‘understand’ that a WebBrowser control can use the phones geolocation capabilities.

I am sure these issues can be resolved … I’ll keep you posted!

Conclusions

I am happy to see that my first attempt at a HTML5-based WP7 application was accepted by the Windows Marketplace. I am sure that HTML5 will play a significant part in the future of mobile application development and it is re-assuring that Windows Phone 7 can be a part of it.

More blog posts and technical details to follow …

Regards, Colin E.