View
 

PhoneGap Geolocation Sample Application

Page history last edited by Alexis 1 year, 8 months ago

In this brief PhoneGapplication tutorial, I will describe using the PhoneGap JavaScript API to access the device's GPS receiver and retrieve the client's current GPS coordinates, then use this information to retrieve a Google Maps static image of the client's current location.

 

This technique is used in an open-source PhoneGap application I am building called BeerMe, which is also hosted on GitHub here.

 

HTML

 

Here is some basic markup that you can use as the basis for the application. All we have for body content is an <img> tag whose src attribute we will be changing based on our position and will call a Google Maps service.

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html>

     <head>

          <meta name="viewport" content="width=device-width; height=device-height; user-scalable=no" />

          <meta http-equiv="Content-type" content="text/html; charset=utf-8">

          <title>Beer Me</title>

          <link rel="stylesheet" href="/master.css" type="text/css" media="screen" />

          <script type="text/javascript" src="scripts/phonegap.js"></script>

          <script type="text/javascript">

               function loader() {

                    var state = document.readyState;

                    if (state == 'loaded' || state == 'complete') {

                         run();

                    } else {

                         if (navigator.userAgent.indexOf('Browzr') > -1) {

                              setTimeout(run, 250);

                         } else {

                              document.addEventListener('deviceready',run,false);

                         }

                    }

               }

               function run() {
                    var win = function(position) {                          // Grab coordinates object from the Position object passed into success callback.
                         var coords = position.coords;
                         // Call for static google maps data - make sure you use your own Google Maps API key!
                         var url = "http://maps.google.com/maps/api/staticmap?center=" + coords.latitude + "," + coords.longitude + "&zoom=13&size=320x480&maptype=roadmap&key=MyGoogleMapsAPIKey&sensor=true";
                         document.getElementById('map').setAttribute('src',url);
                    };
                    var fail = function(e) {
                         alert('Can\'t retrieve position.\nError: ' + e);
                    };
                    navigator.geolocation.getCurrentPosition(win, fail);
               } 

          </script>

     </head>

     <body onload="loader();">

          <img id="map" />

     </body>

</html>

 

Things that you should note from the markup:

  • The 'phonegap.js' JavaScript file referenced should be included in your www/ folder automatically, but you have to make sure that your application includes a reference to the script (in the HTML).
  • The meta-viewport tag is used to tell the rendering engine the dimensions of the viewport, i.e. the screen of your device. You can use device-width and device-height to tell the renderer 'whatever the dimensions of my screen are', or you can hard-code these values. See this W3C article section and this Safari Dev Center article for more details about this tag.
  • In the <head> section of the HTML, there is a reference to a master.css stylesheet file. There is a styles section at the end of this article that lists out all of the style directives used in this sample application.

 

JavaScript

 

The JavaScript present in this sample application is composed of two parts: a "loader" function that will robustly attach and execute our application logic, and the application logic itself. Both of these are encapsulated in separate functions in the last <script> tag in the <head> section of the above markup, 'loader' and 'run' respectively.

 

Running Application Code after PhoneGap is Ready

 

This is the 'loader' code. This function takes a peak at the ready state of the document, and, depending on if the document is already loaded or not, will either immediately run the application logic (by invoking the run() function) or will attach the application logic to the 'deviceready' event. This event is fired by (most) PhoneGap frameworks when the PhoneGap JavaScript API is ready to accept commands. This is necessary since PhoneGap involves a JavaScript shim that in one form or another enables communication between your PhoneGap application (built as a web page) and the device's native end. Sometimes, this deviceready event fires only after some loading time following page rendering (usually on the order of a few milliseconds). In faster phones today like the iPhone 3GS and the Nexus One, the deviceready event fires quite quickly - sometime even before the page is fully loaded! As such, that is why I have included a check for the document's readyState - just for this case.

 

Finally, you may be wondering why the loader code is sniffing for a user-agent string containing 'Browzr'. This is what the old RIM browser that is present on most BlackBerries identifies itself as. This browser is very primitive and lacks a lot of JavaScript and DOM implementation compliance. One of these limitations is an inability to fire custom events - thus, the deviceready event is never fired on PhoneGap BlackBerry applications.

 

Mapping Code

 

The run() function defined in the application is composed of three parts: two callback functions, win & fail, and a call to the PhoneGap JavaScript API to retrieve your GPS system location (the last line in the run() function). The two callbacks, win and fail, are success and error callbacks respectively. The win function should have a parameter which will be a Position object - see the JavaScript API for more details on what makes up this object. We extract the Coordinates object, which is a member of the Position object, and access its latitude and longitude members for use as part of the request URL to the Google Static Maps API (this is the 'url' variable declared in the win callback). As you can see, we make a request to Google servers for a static map. The URL itself tells Google what we want it to return. You can see that we specify the size of the map as 320x480 pixels, pass longitude and latitude as a 'center' parameter, provide a zoom level (set to 13 in this case), as well as some required parameters from the Google service such as a Google Maps API key as well as whether or not a GPS-enabled device is requesting the map (this is the sensor parameter). The last step of the success callback is to assign the generated URL to the <img> tag's 'src' attribute.

 

Styles

 

Very basic styles defined in this application (more of a style reset than anything else):

 

body, img { margin: 0; padding:0; border: 0; }

#map { width: 100%; height: 100%; z-index:1; }