Showing posts with label geolocation. Show all posts
Showing posts with label geolocation. Show all posts

Wednesday, March 03, 2010

Testing Geolocation for Mobile Web Apps

Using geolocation in a web application is really cool. The JavaScript API is quite simple. Testing it, can be a different story. Here are some useful tips:

If you only need to get the user's location once, testing is not too bad at all. First, you can actually use Firefox 3.5+. However, make sure that you are using wi-fi, or otherwise you will never get a location. Your app will just seem to hang. Anyways, being able to use Firefox for testing is great because it is a full desktop browser with awesome developers tools like Firebug. Often you will have some pretty complex JavaScript in a web application that uses geolocation, so being able to debug with Firefox/Firebug is invaluable.

Of course you will also want to test on mobile browsers. You can definitely use the iPhone simulator that is part of the iPhone SDK. Geolocation works great on this, but it gives you a bogus location -- the location of Apple's HQ in Cupertino, CA. If you actually live near Cupertino, this can be really misleading. Anyways, it will only give you this location, never anything else. So it is somewhat limited.

Testing on an Android emulator is another possibility. However, in my experience, it is currently broken. On an Android device, when a web page wants your location, the browser brings up a window to prompt you for permission. On the emulator's browser, I never see this permission window and the app just hangs and never returns a location. That's a bummer, since the Android SDK makes it possible to send mock GPS coordinates to an Android emulator. It would be great if web developers could take advantage of this.

Testing on an actual devices is of course a possibility. Your web application needs to be reachable by the device. This could mean using wi-fi on your device, so you are in the same intranet as your development sever, or it could mean deploying your app somewhere public. I like using the Google App Engine for the latter, and then test on the assortment of devices that I have laying around.

If you need to test location updates, i.e. when the user moves you want your web application to know about it and respond in some way, then things get trickier. The iPhone simulator is out of the question. An Android emulator still suffers from the same problems. So now you are down to devices. There is no way to send mock GPS to an iPhone, so to test on an iPhone, you need to actually change your physical location. Coding and driving FTW!

However, it should be possible to test on an Android device. The Android SDK theoretically allows you to send mock GPS to a real device. The command that should work is "adb -s XXX shell geo fix AAA BBB" where XXX is the serial number of your device (get it by doing "adb devices"), and AAA/BBB are the fake latitude/longitude. Sounds good, right? I tried this on my Nexus One, and got a big fat permission denied. Turns out you need to be root to do this on a real device. Ok, so I rooted my Nexus One. Then I tried it. Result? "gps: not found." Suddenly the gps command was not recognized. So ... coding and driving FTW!

Monday, November 16, 2009

Cross Browser Geolocation

You might have heard that Joe Hewitt has given Apple the finger, and is moving on (or more accurately moving back to) mobile web development. You can do a lot on mobile web browsers -- more than you can do on desktop browsers. This can seem counterintuitive at first. However, flavors of WebKit have a huge share of mobile web use, and it supports a lot of features that you can't count on in the IE-dominated world of desktop browsers. One of those coveted features is geolocation. However, geolocation support is far from standardized even among the high end WebKit based browsers.

Geolocation on Mobile Safari is nice, or more accurately it is "standardized." It follows the W3C standard. All you have to do is access the navigator.geolocation object. Here is a super simple example:
var gps = navigator.geolocation;
    if (gps){
        gps.getCurrentPosition(successHandler);
    } 
}

function successHandler(position){
  var lat = position.coords.latitude;
  var long = position.coords.longitude;
  doSomethingUseful(lat, long);
}
Pretty easy, huh? This will work on Mobile Safari running on iPhone OS 3+. As mentioned, it is standard. It will also work on newer versions of Firefox, which presumably includes Mobile Firefox, a.k.a. Fennec. However, that is the limit of the portability of this code. It will not work in Android's browser.
Android's flavor of WebKit, does not support the standard. However, it does support geolocation via Google Gears. That's right, instead of supporting the open standard, it implements the same feature using a proprietary technology. Shocking, I know. So if you are going to run JS that should access geolocation on both the iPhone and one of the zillion Android phones out there, you will need to include the gears_init.js bootstrap file. Then you can re-write the above like this:
function load(){
    var gps = navigator.geolocation;
    if (gps){
        gps.getCurrentPosition(successHandler);
    } else {
        if (window.google && google.gears){
            gps = google.gears.factory.create('beta.geolocation');
            gps.getCurrentPosition(function (position){
               successHandler({coords : position});
            }) ;
        }
    }
}

function successHandler(position){
  var lat = position.coords.latitude;
  var long = position.coords.longitude;
  doSomethingUseful(lat, long);
}
So this is pretty close to the standard, but not quite. The Gears variant also supports the getCurrentPosition API. However, the object that it passes to the success function is different. It is a flatter structure. So in the above example, we wrap it inside another object so that we can reuse the same handler.
I haven't tried the webOS browser, yet or the Nokia WebKit variant yet. Here's hoping they are close to the standard used by Safari.