How to Create HTML5 Apps on Windows Phone with PhoneGap

Share this article

We will first see in this article what the added values of PhoneGap for HTML5 applications are. We’ll then discover how to create our very first project where we will retrieve the accelerometer’s values from our JavaScript code. At last, we will review a complete HTML5 gaming sample almost ported as-is to PhoneGap to use the accelerometer available on the Windows Phones.

  1. Introduction
  2. PhoneGap: a framework filling the gap
  3. Let’s create our first PhoneGap project
  4. Getting the accelerometer’s values from JavaScript
  5. Review of a complete sample with the HTML5 Platformer game
  • Forcing the landscape orientation
  • Handling various resolutions
  • Loading the levels with calls to the file system instead of using XHR
  • Modification of the gameplay to use the accelerometer
  • Screenshots of the result and FPS on some phones
  • Complete Visual Studio Solution to download
  • Conclusion
  • Introduction

    The Mango update for Windows Phone came with the support of HTML5 thanks to the embedded IE9 browser. As the desktop version, the mobile version of IE9 delivers hardware acceleration through the GPU of your Windows Phone. Thus, combined with JavaScript, IE9 can now serve as a base of interesting user’s experiences usually reserved to “native code”. HTML5 logoThe Pros of using HTML5 as a development platform is a relative promise to easily re-use parts of the code on others compatibles platforms like Android or iOS. HTML5 has then driven a lot of interests from the mobiles developers’ ecosystem during the last months. However, even if the HTML5/CSS3/SVG & JavaScript specifications have greatly evolved during the last months, they still lack some major features to build mobile applications. Indeed, a phone or a tablet exposes specific capabilities like: GPS, accelerometer, camera, sending SMS, accessing contacts, etc. To have access to these capabilities from the JavaScript code, the W3C has been working now for a while on what we call “Device APIs” or DAP. Unfortunately, we can consider that no implementation currently exists of those specifications as this document seems to confirm: Standards for Web Applications on Mobile: November 2011 current state and roadmap . Mozilla has started an interesting work by more or less forking those specifications via what they call Web APIs to support their Boot To Gecko project. This is then a good news as a form of implementation seems to start with an on-going discussions with the W3C. However, even if things start to move slowly, we will probably have to wait for several years before having a stable official W3C specification implemented widely on all platforms. So the question is: what should we do in the meantime? Can HTML5 really address those scenarios?

    PhoneGap: a framework filling the gap

    Illustration of how PhoneGap worksWhile waiting on real standardized specifications, we don’t have the choice: we need to create some bridges between JavaScript and the native code of the targeted platform to have access to its capabilities. The idea is then the following one: taking the native languages of each platform (C#, Objective-C and Java) and creating a framework with these languages that will expose interfaces to the JavaScript developer. This is exactly what PhoneGap is doing. Let’s take the Windows Phone case which is the main topic of this article. A Windows Phone’s PhoneGap project is simply a Silverlight application hosting the WebBrowser control (and thus IE9) as well as a Silverlight Assembly written in C# which does the job to access to the accelerometer, GPS, contacts, camera and so on. In this way, as a JavaScript developer, you will use a DLL named WP7GapClassLib.dll (the PhoneGap core runtime) without even knowing it via the usage of the code embedded in the phonegap-1.3.0.js file. This DLL contains some C# code which does calls to the Silverlight runtime available on the phone. As the runtime has access to all the capabilities of the phone, the JavaScript will do also. The JavaScript library will then act as a gateway between both worlds. Moreover, the good point of using this library is that your code will most of the time works as-is on the PhoneGap versions of Android or iOS. PhoneGap offers then an interesting form of portability. Please note by the way that the PhoneGap support for Windows Phone is now totally complete since the recent 1.3.0 version: Windows Phone support for PhoneGap At last, PhoneGap offers also another interesting service. It embeds your .js, .css, .html, .png resources inside its projects to package it as a classical application. In summary, you can use PhoneGap to package your HTML5 application for the various applications’ stores. This is for instance the case of the SujiQ Windows Phone application built using this approach.

    Let’s create our first PhoneGap project

    Prerequisites

    Here are the very first steps you need to follow:
    1. Download the Windows Phone SDK: Windows Phone SDK
    2. Download the last version of Phone (1.3.0 today) on their site: http://phonegap.com/
    3. Unzip the downloaded file
    4. Copy the PhoneGapStarter.zip and PhoneGapCustom.zip files into DocumentsVisual Studio 2010TemplatesProjectTemplates

    File->New project

    Once the previous steps are done, you will be able to create your first PhoneGap project. Start Visual Studio 2010, select the “Visual C#” templates and filter them via the “Gap” keyword. You should then see a new type of project named PhoneGapStarter: PhoneGap Starter Name your project “MyFirstPhoneGapProject”. Once done, you will find the files I was talking about before in the Solution Explorer: solution explorer You just now have to insert your HTML5 application into the “www” directory. Here are several tips I’d like to share with you about this default project template: – never ever touch thephonegap-1.3.0.js file if you’d like to keep a portable code on other versions of PhoneGap – all files you will add inside the “www” directory must be set as “Content” in the properties window – instead of the WP7GapClassLib.dll binary file, you can add a reference to the WP7GapClassLib.csproj C# project available in the “Windows Phoneframework” directory of the downloaded PhoneGap archive. It will help you debugging or discovering the native code of the PhoneGap library if needed. Ok, let’s now start by doing something normally impossible by default with IE9 Mango: accessing to the accelerometer’s values from JavaScript.

    Getting the accelerometer’s values from JavaScript

    We’re going to see here how to get the values sent back by the accelerometer (of the emulator or the real device) in a very simple way. Open the index.html page and change its default body by this one:
    <body>
    
        <h1>Accelerometer sample</h1>
    
        <div id="valueX"></div>
    
       <div id="valueY"></div>
    
        <div id="valueZ"></div>
    
    </body>
    We will simply use 3 <div> tags to display the current X, Y & Z values of the accelerometer. Next step is to change the last default <script> block to this one:
    <script type="text/javascript">
    
        document.addEventListener("deviceready", onDeviceReady, false);
     
        // variable to output the current x, y & z values of the accelerometer
    
        var valueX;
    
        var valueY;
    
        var valueZ;
     
        // when PhoneGap tells us everything is ready, start watching the accelerometer
    
        function onDeviceReady() {
    
            valueX = document.getElementById("valueX");
    
            valueY = document.getElementById("valueY");
    
            valueZ = document.getElementById("valueZ");
    
            startWatch();
    
    }
     
            // start monitoring the state of the accelerometer
    
        function startWatch() {
    
            var options = { frequency: 500 };
    
            navigator.accelerometer.watchAcceleration(onSuccess, onError, options);
    
        }
     
        // if the z-axis has moved outside of our sensitivity threshold, move the aardvark's head in the appropriate direction
    
        function onSuccess(acceleration) {
    
            valueX.innerHTML = "X: " + acceleration.x;
    
            valueY.innerHTML = "Y: " + acceleration.y;
    
            valueZ.innerHTML = "Z: " + acceleration.z;
    
        }
     
        function onError() {
    
            alert('onError!');
    
        }
    
    </script>
    Well the code is relatively self-explicit I think. The very first thing to note is that you need to wait for the deviceready event raised by PhoneGap to be sure to be in a stable state. You then need to subscribe to this event. In our case, we will be call-backed into the OnDeviceReady() function. This function is getting the references to the 3 <div> tags and then asks to be notified by any changes done inside the accelerometer every 500ms with the startWatch() function. The notifications will be sent to the onSuccess() function that will have access to the acceleration object containing the x, y & z values. You’ll find the complete documentation on the PhoneGap site: PhoneGap Documentation – API Reference – Accelerometer. This is all you need to do on the JavaScript side. However, to make it works, you need to specify in the project’s properties that you want to request access to the device’s sensor. The capabilities needed for the proper execution of our application are listed inside the WMAppManifest.xml file available in the Properties directory. By default, since 1.3.0, PhoneGap is listing the strict minimum capabilities:
    <Capabilities>
    
        <Capability Name="ID_CAP_IDENTITY_DEVICE" />
    
        <Capability Name="ID_CAP_IDENTITY_USER" />
    
        <Capability Name="ID_CAP_LOCATION" />
    
        <Capability Name="ID_CAP_NETWORKING" />
    
        <Capability Name="ID_CAP_WEBBROWSERCOMPONENT" />
    
    </Capabilities>
    It’s then up to you to add the capabilities you need for your PhoneGap application. In our case, we need to add this line:
    <Capability Name="ID_CAP_SENSORS" />
    To be allowed to access to the accelerometer, you’ll find the complete list of all available capabilities here: Application Manifest File for Windows Phone Ok, we’re logically ready to test that inside the emulator as a first phase. Press on the magical “F5” key and let’s have a look to the result: emulator By moving the virtual phone in the emulator on the right, you should see the values of the accelerometer updated. Congratulations! You can download the complete source code of this first solution here: https://david.blob.core.windows.net/html5/MyFirstPhoneGapProject.zip

    Issues with phones using French locale

    If you’re testing the very same code on your phone configured to use a French locale (as mine for instance!), you will have the feeling that the application doesn’t work at all … which is indeed the case. I’ve spent some time debugging the code and I’ve discovered that the following exception was raised inside phonegap-1.3.0.js: “Error in success callback: Accelerometer = Syntax error” After dumping the values, I’ve seen that the error was due to a tentative of de-serialization of the following bad formatted JSON string: “{“x”:0,00472,”y”:-0,19879,”z”:-0,98115}” whereas the proper EN-US is the following one: “{“x”:0.00472,”y”:-0.19879,”z”:-0.98115}” Yes, we’re using a comma in France as a numeric separator. 2 solutions to solve this problem: 1 – The lazy one: switch your phone into EN-US (I know, this is not a solution!) 2 – Fix the problem that comes from the C# code. For that, replace the following code from the Accelometer.cs file of the WP7GalClassLib library:
    /// <summary>
    
    /// Formats current coordinates into JSON format
    
    /// </summary>
    
    /// <returns>Coordinates in JSON format</returns>
    
    private string GetCurrentAccelerationFormatted()
    
    {
    
        string resultCoordinates = String.Format(""x":{0},"y":{1},"z":{2}",
    
    accelerometer.CurrentValue.Acceleration.X.ToString("0.00000"),
    
    accelerometer.CurrentValue.Acceleration.Y.ToString("0.00000"),
    
    accelerometer.CurrentValue.Acceleration.Z.ToString("0.00000"));
    
        resultCoordinates = "{" + resultCoordinates + "}";
    
        return resultCoordinates;
    
    }
    By this one:
    private string GetCurrentAccelerationFormatted()
    
    {
    
        string resultCoordinates = String.Format(""x":{0},"y":{1},"z":{2}",
    
            accelerometer.CurrentValue.Acceleration.X.ToString("0.00000", CultureInfo.InvariantCulture),
    
            accelerometer.CurrentValue.Acceleration.Y.ToString("0.00000", CultureInfo.InvariantCulture),
    
            accelerometer.CurrentValue.Acceleration.Z.ToString("0.00000", CultureInfo.InvariantCulture));
    
        resultCoordinates = "{" + resultCoordinates + "}";
    
        return resultCoordinates;
    
    }
    And the sample will now work with all locales. I’ve filed a bug on this topic here: https://issues.apache.org/jira/browse/CB-141 suggesting the same solution that will normally be shipped with the next version (2.0.0). By the way, you’re maybe wondering how I’ve managed to debug the JavaScript part of my PhoneGap project? Well, you can simply use the wonderful jsConsole project. If you want to know more about that, please read one of my colleague’s article: jsConsole Remote Debugging in IE9 on Windows Phone Mango

    Review of a complete sample with the HTML5 Platformer game

    Let’s now review a more complex sample. My idea was to start from the game I’ve written before. It’s exposed in this article: HTML5 Platformer: the complete port of the XNA game to <canvas> with EaselJS . I wanted to see what I should do to make it works on the phone. First step is to simply copy/paste the different .js, .png, .css files into the “www” directory and to mark them as “Content”. Here are the others steps to follow.

    Forcing the landscape orientation

    The game has to be played in landscape mode. I’ve then forced this orientation. I’ve also remove the information bar on the side (the System Tray). For that, you need to open the MainPage.xaml
    file and change these properties:
    SupportedOrientations="Landscape" Orientation="Landscape" shell:SystemTray.IsVisible="False"

    Handling various resolutions

    As my main goal was to build a game that could run on the highest number of devices, I need to handle a lot of different resolutions. For that, I’ve slightly modified the initial code of the Platformer you can download in the other article. The game is now capable on running at any resolution by applying a rescale ratio on the images and sprites to draw. Everything is being redrawn based on a specific ratio that came from the Windows Phone (800×480) which is the 100% ratio. You can test this version in your desktop browser here: HTML5 Platformer ReScale and try to dynamically resize the browser window. Moreover, if your screen resolution has a 16/9 aspect ratio, press the F11 key to play in fullscreen! The experience in this mode is really cool as you can see in this screenshot: fullscreen screenshot We’re letting the browser taking care of the anti-aliasing during this scaling operation. Based on the browser you’ll use, you will notice also that the performance could vary a lot related to the size of the window you’ll have. On my machine, IE9/IE10 seems relatively indifferent to the fullscreen mode or small resolutions by maintaining a stable 60 fps framerate.

    Loading the levels with calls to the file system instead of using XHR

    In the initial code, the .TXT files linked to the each level were stored on the web server and downloaded via XmlHttpRequest calls. As we’re now running everything client-side in offline mode, XHR local calls are not very appropriated. I’ve then replaced the initial code of the PlatformerGame.prototype.LoadNextLevel function by this one:
    PlatformerGame.prototype.LoadNextLevel = function () {
    
        this.levelIndex = (this.levelIndex + 1) % numberOfLevels;
     
        // Searching where we are currently hosted
    
        var nextFileName = "app/www/assets/levels/" + this.levelIndex + ".txt";
    
        try {
    
            var instance = this;
    
            window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, fail);
     
            function gotFS(fileSystem) {
    
                fileSystem.root.getFile(nextFileName, null, gotFileEntry, fail);
    
            }
     
            function gotFileEntry(fileEntry) {
    
                fileEntry.file(gotFile, fail);
    
            }
     
            function gotFile(file) {
    
                readAsText(file);
    
            }
     
            function readAsText(file) {
    
                var reader = new FileReader();
    
                reader.onloadend = function (evt) {
     
    instance.LoadThisTextLevel(evt.target.result.replace(/[nrt]/g, ''));
    
                };
    
                reader.readAsText(file);
    
            }
     
            function fail(evt) {
    
                console.log(evt.target.error.code);
    
            }
    
        }
    
        catch (e) {
    
            console.log("Error loading level: " + e.message);
    
            // Probably an access denied if you try to run from the file:// context
    
            // Loading the hard coded error level to have at least something to play with
    
            this.LoadThisTextLevel(hardcodedErrorTextLevel);
    
        }
    
    };
    I’ve just re-used the code available in the PhoneGap documentation: FileReader . As you can see, you have a full access to the Windows Phone file system from JavaScript with PhoneGap. Cool tip: to help you debugging what’s really stored in the Isolated Storage of the phone or not, you should have a look to this awesome tool: IsoStoreSpy written by Samuel Blanchard.

    Modification of the gameplay to use the accelerometer

    Well, last part is just to mix all parts of this article to obtain the final result. For that, I’ve added the following code into the constructor of the Player object in the Player.js file:
    var options = { frequency: 500 };
    
    var that = this;
     
    navigator.accelerometer.watchAcceleration(
    
          function (accelerometer) { that.moveDirectionAccel(accelerometer); },
    
          function () { console.log("Error with accelerometer"); },
    
          options);
    Here is the function that will be call-backed during the accelerometer variations:
    Player.prototype.moveDirectionAccel = function(acceleration) {
    
        var accelValue = -acceleration.y;
     
        // Move the player with accelerometer
    
        if (Math.abs(accelValue) > 0.15) {
    
             // set our movement speed
    
             this.direction = Math.clamp(accelValue * this.AccelerometerScale, -1, 1);
    
        }
    
        else {
    
            this.direction = 0;
    
        }
    
    };
    I’ve also added an handler on the onmousedown event on the canvas to jump when the user tap on the screen.

    Screenshots of the result and FPS on some phones

    First, let’s review the result within the Windows Phone emulator: review the emulator We have a framerate varying from 54 to 60 fps on my machine. On a real device, the framerate differs logically between models. Let’s take the first game level. On the LG E900, the framerate is around 22 fps. On the HTC Radar, it’s around 31 fps. On the Nokia Lumia 800, it’s around 42 fps. framerates The gameplay could then be not very convincing in most cases. Indeed, I’m using a fullscreen canvas to draw the whole game. This is not a very good idea for the mobile limited power CPU, even if the Nokia seems powerful enough to handle this approach. A better methodology could be to cut the screen stage into various little canvas that will then be moved by modifying the CSS properties on them. This is what has been done for the HTML5 version of Angry Birds for instance. Some JS gaming frameworks start to think about handling this complexity for you. The idea would then be to code the game once with high level APIs and the framework could switch between a full frame canvas or various little canvas moved via CSS based on the performance. Well, you’ll get it: the HTML5 gaming experience on mobile is currently just at its beginning. But its future looks very promising!

    Complete Visual Studio Solution to download

    You’ll find the complete source code of the HTML5 Platformer for PhoneGap here: HTML5GapPlatformer.zip

    Other useful resources

    Conclusion

    PhoneGap offers interesting perspectives to help you writing applications on the phone. It lets you using your existing skills in JavaScript, HTML and CSS. PhoneGap won’t necessary cover all the scenarios currently available with the native development stack (Silverlight or XNA). But this could be something to have a look to if you’d like to capitalize on the HTML skills of one of your team. You will have to pay attention to properly identify the kind of project to work on. You can also think about mixing both environments to create hybrid experiences: the main branch would be written using “HTML5” and some specific parts into native code. Using this idea, some plug-ins have been created to push a bit further the integration into the Metro UI: PhoneGap Plug-ins for Windows Phone . You’ll find for instance one of them allowing a JavaScript code to update the Tiles. At last, PhoneGap and HTML5 could allow a relative portability to other platforms… with some limitations. But this is a vast subject with passionate debates that would need a complete dedicated article. This article was originally published on the author’s MSDN Blog. It is republished with permission.

    Frequently Asked Questions (FAQs) about Creating HTML5 Apps on Windows Phone with PhoneGap

    How can I access the mobile device camera using HTML5 on Windows Phone with PhoneGap?

    To access the mobile device camera using HTML5 on Windows Phone with PhoneGap, you need to use the navigator.camera.getPicture method. This method provides access to the device’s default camera application. The returned image is either a base64-encoded string or, on Windows Phone 7, a URI pointing to the image file in the temporary directory of the application.

    Can I use HTML5 to create mobile apps for other platforms besides Windows Phone?

    Yes, HTML5 is a versatile language that can be used to create mobile apps for a variety of platforms, not just Windows Phone. With PhoneGap, you can create apps for Android, iOS, and other platforms. However, the specific implementation may vary depending on the platform.

    How can I test my HTML5 app on Windows Phone?

    To test your HTML5 app on Windows Phone, you can use the Windows Phone Emulator included in the Windows Phone SDK. This emulator simulates the Windows Phone OS and hardware, allowing you to test your app in a variety of simulated environments.

    What are some common issues I might encounter when creating HTML5 apps on Windows Phone with PhoneGap?

    Some common issues include compatibility problems with different versions of Windows Phone, difficulties accessing device features like the camera or accelerometer, and performance issues. It’s important to thoroughly test your app on the target platform to identify and resolve any issues.

    Can I use CSS3 and JavaScript along with HTML5 when creating apps with PhoneGap?

    Yes, PhoneGap supports the use of CSS3 and JavaScript along with HTML5. This allows you to create rich, interactive apps with advanced features and functionality.

    How can I optimize the performance of my HTML5 app on Windows Phone?

    There are several strategies to optimize the performance of your HTML5 app on Windows Phone. These include minimizing the use of heavy graphics, optimizing your code for efficiency, and using hardware acceleration where possible.

    Can I access other device features like the accelerometer or GPS using HTML5 on Windows Phone with PhoneGap?

    Yes, PhoneGap provides APIs that allow you to access a variety of device features, including the accelerometer, GPS, and more. However, the specific implementation may vary depending on the platform and device.

    How can I handle different screen sizes and resolutions when creating HTML5 apps on Windows Phone?

    You can use CSS media queries to adapt your app’s layout to different screen sizes and resolutions. This allows you to create a responsive design that looks good on a variety of devices.

    Can I use third-party libraries or frameworks when creating HTML5 apps on Windows Phone with PhoneGap?

    Yes, you can use third-party libraries or frameworks like jQuery Mobile, AngularJS, or Bootstrap to help speed up development and add advanced features to your app.

    How can I distribute my HTML5 app on Windows Phone?

    To distribute your HTML5 app on Windows Phone, you can submit it to the Windows Phone Store. Before submission, make sure to thoroughly test your app and ensure it meets all the store’s submission guidelines.

    David RoussetDavid Rousset
    View Author

    David Rousset is a Senior Program Manager at Microsoft, in charge of driving adoption of HTML5 standards. He has been a speaker at several famous web conferences such as Paris Web, CodeMotion, ReasonsTo or jQuery UK. He’s the co-author of the WebGL Babylon.js open-source engine. Read his blog on MSDN or follow him on Twitter.

    HTML5 Dev CenterHTML5 Tutorials & ArticlesPhonegap
    Share this article
    Read Next
    Get the freshest news and resources for developers, designers and digital creators in your inbox each week