Developing Cross Platform Apps with PhoneGap: Part 1

2 BY devrel

Introducing PhoneGap

When you build an application for a mobile device you usually build it using the SDK specifically for that platform. This gives you a completely native look and feel, as well as full access to features specific to that device or operating system. Sometimes, however, you don’t need full device access. Sometimes you might want code at a very high level using just web standards and be able to run the application on multiple OSes. This is similar to coding a mobile website, except that as an local application your app can launch faster, work offline, and have access to local resources.

PhoneGap is an open source, cross platform tool for writing code once that runs on multiple mobile platforms using just HTML, JavaScript, and CSS. It is not a full OS toolkit and does not provide GUI widgets or high level features. It’s simply a common API and set of build tools that give you have uniform access to the browser and device services.

This is part one of a series on using PhoneGap to build apps for webOS and other mobile operating systems like iPhone and Android. In this first part we will build a simple webOS app using PhoneGap and HTML Canvas; no webOS specific APIs. In future parts of the series we will port this same application to Android and iPhone.

Note: this tutorial assumes you have already downloaded the Palm webOS SDK for free from developer.palm.com. See this article for full instructions.

Setting up PhoneGap

Go to www.phonegap.com, click ‘download phone gap‘, to get the latest release (0.9.1 at the time of this writing).
You will get a zip file containing a bunch of directories, one for each platform. Put this in a safe place. You will use it as the clean base for all of your apps.

Make a copy of the phonegap-palm directory and rename it for your app. For this blog I’m going to make an app called stars.

From the command line, go into the stars directory and run make clean; make. If you have the emulator open or your webOS device attached via USB then it will successfully build, package, and launch the app. Congrats, you’ve built a phonegap app that perfectly does nothing. Now let’s make it useful by drawing a bunch of stars.

The actual app is in framework/www/ directory. Open up framework/www/index.html in your favorite text editor. This is the core of your app.

Put the following code in the header right below the phonegap.js line


    <!-- include our own javascript -->
     <script src="Starfield.js" type="text/javascript"></script>
     <!-- include our own style for this page -->
        <style type="text/css">
            body.palm-default {     background-color : #000000;     color: white; }
            h2, h3 { text-align: center; margin: 3px;}
            h3 { font-size: 75% }
        </style>

this will set a few styles and include the starfield.js file where the actual code is.

In the body element put this:

        <div id="myapp">
        <h2>Star Field</h2>
        <h3>tap to start</h3>
        <canvas id="svgCanvas" width="320" height="320" onclick="starfieldStart()"></canvas>
        </div>

This creates a header and a canvas ready for us to draw into. When you click on the canvas it will call starfieldStart(), which begins
the star simulator. Now let’s put in some real code.

Paste this into a file called Starfield.js in the directory “framework/www”.

var ctx;var width = 320;
var height = 320;
var partx;
var party;
var partdx;
var partdy;
var PARTS=100;
var count=0;
var ramp=1;
var intervalId;

function circle(x,y,r) {
     ctx.beginPath();
     ctx.arc(x, y, r, 0, Math.PI*2, true);
     ctx.closePath();
     ctx.fill();
};

function draw() {
     ctx.clearStyle = "#000000";
     ctx.clearRect(0,0,width,height);
     ctx.fillStyle = "#000000";
     ctx.fillRect(0,0,width,height);
     ctx.fillStyle = "#FFFFFF";
     for(i=0;i<ramp;i++) {
          circle(partx[i],party[i],2);
          partx[i] += partdx[i];
          party[i] += partdy[i];
          if(partx[i] > width || partx[i]<0) {
               partx[i] = width/2;
               party[i] = height/2;
          }
     }
     count++;
     if(count > 500) {
          ramp--;
          if(ramp < 1) ramp = 0;
     } else {
          ramp++;
          if(ramp > PARTS) ramp = PARTS;
     }
     if(count > 600) {
          clearInterval(intervalId);
     }
};

function starfieldStart() {
     count = 0;
     ramp = 1;
     ctx = document.getElementById("svgCanvas").getContext("2d");

     partx = new Array(PARTS);
     party = new Array(PARTS);
     partdx = new Array(PARTS);
     partdy = new Array(PARTS);

     for(i=0;i<PARTS;i++) {
          partx[i] = width/2;
          party[i] = height/2;
          partdx[i] = Math.random()*5-5/2;
          partdy[i] = Math.random()*5-5/2;
     }
     intervalId = setInterval(draw, 10);
};

run ‘make’ and you’ll the app start. click in the middle to start the stars. after a few seconds (technically 600 iterations of the loop) it will end, but you can click to start it again.

palm_emu_running.png

That’s all there is to creating an app with phonegap. Of course, we want to create the best possible experience for our users, so there’s a few things we need to fix. Let’s see if we can make it launch faster and give it a proper name.

Launch Faster

Mojo is the standard Javascript framework that most webOS apps are built with. However, if you aren’t using any features within it then it’s just costing you startup time. You can actually get rid of Mojo by just commenting out the script tag at the top of your index.html page.

<!--
<script language="javascript" type="text/javascript"
  src="/usr/palm/frameworks/mojo/mojo.js"
  x-mojo-version="1"></script>
-->

Mojo does one thing that we need however. It tells the window manager when we the app is fully loaded and ready to go. We can do this manually with a simple onLoad event handler. Add the following script to the head of the index.html page

<script language="javascript" type="text/javascript" charset="utf-8">
function onLoad() {
    if (window.PalmSystem) {
        window.PalmSystem.stageReady();
    }
}
</script>

then add a call in the body’s onload event.

<body onload="onLoad()">

That’s it. Now the app will load without Mojo and start up very quickly.

A Better Name

Now lets give it a proper name. Edit the appinfo.json file and change the id, version, vendor, and title to something more appropriate.:

{
     "id": "com.palmdts.phonegap.stars",
     "version": "0.0.1",
     "vendor": "Josh Marinacci",
     "type": "web",
     "main": "index.html",
     "title": "Stars",
     "icon": "icon.png"
}

If you change the id or version fields above (which you should) then you’ll need to edit the deploy and run targets in the Makefile as well.

A New Icon

Now we can replace icon.png with a new image. Here’s the one I whipped up in Photoshop.

icon.png

You may need to delete the app from your phone and reinstall it for webOS to pick up the new name and icon.

palm_emu_icon.png

Debugging

If you are having any trouble with your app code you can debug it using two methods. First, most of your code should run perfectly in a modern desktop browser like FireFox or Chrome. Start developing your app in the browser first, and port it to PhoneGap only after the core functionality works. This will give you access to the great debugging tools built into these browsers.

Second, once you have your app running on webOS you can watch the debugging log on the device using the palm-log command.

palm-log -f com.palmdts.phonegap.stars

This will start watching the log so you can see JavaScript errors and your debugging output to the console.

Conclusion

Now we’ve done it: a cross platform canvas app for webOS using PhoneGap. In the next part of this series I’ll show you how to set up the android SDK and run this exact same app on Android with almost no code changes.

Comments (2)

  1. omt says:

    Thanks for sharing the info Josh. I don’t develop Palm apps at this point but definitely considering soon. I love the WebOS, I think that’s one of the best. Hope HP continues supporting it and uses in other products (I heard at least one slated for early 2011)

  2. Marcel Nijman says:

    I propose a small change in the turorial:

    “Paste this into a file called Starfield.js” should read “Paste this into a file called Starfield.js in the directory framework/www”