Adventures with PhoneGap

Palm Pre, Motorola DROID, iPod TouchI’ve been working with PhoneGap this week to create a simple geolocation app. It’s a framework for creating mobile applications in HTML, JavaScript, and CSS that will run on all the major platforms. You write your application and reference the APIs that PhoneGap provides. Then you simply drop your HTML and JavaScript into the various platform-specific template projects they provide and compile it with the platform’s native compiler. Simple as that.

But the devil is in the details. Every platform and device has subtle differences that make cross-platform development painful. There are even differences between how an emulator and a device run the application.

I’ve been testing on three platforms: webOS (Palm Pre Plus), Android (Motorola DROID with Android 2.1), and iPhone OS 3 (iPod Touch).

Here are a few of my frustrating findings:

Notification: alert, beep, vibrate

First off, webOS doesn’t support the alert() command at all. Android and iPhone do, in the typical fashion.

Beeping is fine on the devices themselves (the Motorola DROID even says “Droid” when you call that function). But the Android SDK emulator kills my app when I call it.

Vibration works on Android. I assume it also works on the iPhone, but I only have an iPod Touch at the moment, and it doesn’t have a vibrator in the first place. The Palm Pre won’t vibrate unless the package name begins with com.palm. Obviously for testing purposes it would be fine to label your app as coming from Palm, Inc. itself, but that won’t fly if you want to distribute the app. So no vibration on webOS. And can you guess what the iPhone simulator does with the vibrate() command? It makes the app hang. Go figure.

Moral of the story: Alert, beep, and vibrate won’t work reliably if you need to support every platform and don’t want your code to break in an emulator.

Location services

The webOS and iPhone simulators both show their location as the headquarters of their respective companies (Sunnyvale or Cupertino). The Android simulator doesn’t even provide location data, so it’s utterly useless for testing in that regard.

My Palm Pre Plus (running on Verizon) can get its location relatively accurately when I’m running it on 3G (even inside my office). Not so if I’m on the WiFi. If I get a fix at all, it’ll take a long time and may be quite inaccurate. (Note that this is the behavior I get everywhere in webOS, not just with PhoneGap.)

The iPod inexplicably thinks it’s in Lilburn, Georgia. For comparison, I’m in Provo, Utah. Only 1,927 miles off. Google Maps on the iPod gets the correct location, but not PhoneGap.

The worst of my problems, though, is the Motorola DROID. More than half the time, my app can’t find its location. It doesn’t matter whether I’m on 3G or WiFi, inside the office or out on ground level. When I compile and run the app immediately after I’ve changed something, it usually seems to get a location fix. But when I subsequently run the app (whether connected to the debugger or not), it fails to get the location. I’ve tried it on two different DROIDs and they both exhibit the same behavior. Google Maps and turn-by-turn navigation work perfectly–they find the location and track it reliably. But something between the phone’s GPS and the PhoneGap library is getting screwed up.

Device UUID

webOS and iPhone OS both return a useful UUID on the device.uuid property. However, Android (both on the emulator and on the DROID) returns simply the unhelpful “undefined.” My app needs to be able to identify users by the UUID of their device, which simply doesn’t work on the Android.

UPDATE: Android 2.2 (Froyo) returns a UUID as you would expect. Only problem is that hardly anyone has it as of now (July 2010), and a lot of older mainstream handsets won’t be getting it at all.

HTML Select boxes

This one really ought not to be a problem. But webOS won’t let you tap on an HTML select box inside a PhoneGap application. It’ll display just fine, but you can’t make a selection. Select boxes work fine on normal web pages. iPhone and Android both support the select box perfectly, including the native OS skins. No dice with PhoneGap on the Palm Pre.

EDIT: Ryan from Nitobi is working on a solution for this on webOS. You can read about it on his blog.

UPDATE: Ryan has fixed this now. See his comment below for the updated files for your project.

Conclusion

So. After wrestling with all of these issues, what have I determined?

PhoneGap is a really slick framework, and it makes it very easy to create a mobile app that is “write once, run anywhere.” But the actual implementation details get hairy, and even fundamental operations like geolocation services and vibration are not implemented uniformly across all these devices.

Caveat emptor.


For those interested, I’ve posted a few questions about these issues on Stack Overflow:

  • http://www.nitobi.com Ryan

    Thanks for the solid PhoneGap feedback. We want to see more people trying it out, as its tough for us to get time to both develop it and create full-spectrum applications which provide real-world results.

    I implemented PhoneGap Palm, so I'll provide some comments on your observations with the Palm platform:

    - alert(): if it doesn't break the Mojo framework, I will implement the alert function using a Mojo popup dialog (should've done this before).

    - vibrate: yes basically the vibrate function is a private api and is only available to “Palm” applications, for whatever reason. I guess we shouldn't have even known about it, but was probably leaked. Either way, I wanted to see PhoneGap make a Palm device vibrate, so I implemented that. but in reality, vibrate is unsupported on webOS, since we cannot identify our apps as com.palm apps. hopefully we can get the webOS guys to make this API public.

    - location services: obviously the location retrieved by PhoneGap is completely dependent on what the GPS device / Mojo Service framework provide us here. Though I have to say my experiences here have been fairly good regarding GPS accuracy — though maybe thats just cause I'm in good spot.

    - html select boxes: big discovery, amazed I haven't come across this one. Can't believe that webOS / Mojo doesn't support this. I commented on your Stackoverflow post, and I too am going to do a blog post on this and try to expose it to Palm, as well as investigate our own solutions.

    Thanks again for this great post.

  • http://globalconstant.wordpress.com/ Steven Nay

    Ryan,

    Thank you so much for your research! It's encouraging to know how invested the PhoneGap developers are in making this platform a success. Feel free to post the link to your blog post here when you get it done. I look forward to hearing what you discover and develop!

  • http://phonegap.com Brian LeRoux

    Hey Ryan, our android/blackberry rockstar Fil did some quick tests of Android EVO and the UUID shows up properly. We can't reproduce the GPS not getting a fix issue — thinking it might be an older build of Android you have. What is the SHA of the git / version you downloaded?

    We're going to look into why the emulator on Android crashes when you call beep(). It works fine on device which is how we normally test.

  • http://globalconstant.wordpress.com/ Steven Nay

    I downloaded the phonegap-android package that had the May 14 commit from Joe Bowser (SHA a65b5784492044324b49).

    I'm running Android 2.1 on both of the Motorola DROID phones, as well as the Android SDK emulator, so I don't think the age of the OS build has anything to do with it.

  • Jason W

    From my testing, it appears that while using the latest git pull, Android 2.2 does display the UUID properly. Anything below 2.2 returned “undefined” (tested 1.6 and 2.1).

  • http://globalconstant.scnay.com/ Steve Nay

    That's very interesting. I'm getting the same result in my testing. Thanks for finding that, Jason!

  • Jason W

    So as for the emulator returning a UUID of null, that appears to be somewhat normal, at least from this posting:

    http://osdir.com/ml/AndroidDevelopers/2009-07/m…

    Not sure why 2.2 actually returns a UUID, but it would explain the case for previous versions. Just some more information that might help explain the problem.

  • Ryan @ Nitobi

    I've implemented the missing functionality of html select boxes in PhoneGap (here's the hack attack fix: http://github.com/phonegap/phonegap-palm/blob/m…).

    Basically just show a Mojo Submenu onclick, and upon selection, manually modify the select's value and fire the onchange event.

  • http://globalconstant.scnay.com/ Steve Nay

    Thanks, Ryan! It works perfectly.