Android: Principle of least surprise violation in GPS emulation
Some of the most viewed posts on this blog have been about Android development, namely some workarounds for bizarre bugs that Google *still* has not fixed, months later. I haven’t touched Android in a few months, but recently have started to dive back in. Here’s yet another instance where an Android related piece of software performs completely counter-intuitively.
When developing an Android application, I often use the emulator rather than an actual hardware device. In order to test GPS related functionality, you can either send simulated GPS events through the Dalvik Debug Monitor Service (DDMS) via Eclipse or through the Android terminal via telnet. I’ll detail surprising bugs/defects in both ways.
The DDMS Eclipse view is available after installing the ADT plugin, and it’s absolutely crucial in order to see logging messages produced from your application (“LogCat”). It also allows you to send GPS coordinates, as the following screenshot shows.
Unfortunately there is a bug in this software that drove me up the wall, and I never would have figured it out myself. I was running into the problem where the first GPS coordinate sent would be received by the emulator, but all subsequent ones would not. It turns out the problem has to do with locales and decimals being treated as commas, or vice versa. See the following Google bug report for more details. The bug has been open over a year; fortunately it looks like it’s slated to be fixed in the next SDK release.
If you telnet into your emulator instance, you have access to the Android console environment.
telnet localhost 5554
Android Console: type ‘help’ for a list of commands
One of the commands you can send is fix, which send a latitude longitude pair to the emulator. Well, that’s what I assumed it did. After wondering why all my locations were were coming out incorrectly, I read the documentation a little more carefully.
|fix <longitude> <latitude> [<altitude>]||Send a simple GPS fix to the emulator instance.||Specify longitude and latitude in decimal degrees. Specify altitude in meters.|
There is a VERY strong convention to specify latitude before longitude. (“latitude and longitude” returns 4,240,000 results as opposed to 542,000 for “longitude and latitude”) Having this command take arguments in the opposite order is very surprising and counter-intuitive. I notice that the DDMS screen has it longitude, latitude as well, but even within the Android APIs, you specify the latitude first!
I realize I should have read the documentation first, but it still is a flaw that the software behaves in unexpected manners (it violates the Principle of Least Surprise/Astonishment), and inconsistent with how API calls in the rest of the OS work. If someone has an explanation for why it’s written this way, I’d love to hear it.
Edit: Later I learned that KML has the same convention, longitude followed by latitude. This corresponds with the x,y ordering conventional in math, so it’s perhaps not so surprising after all. This ordering problem is fairly minor in the grand scheme of things, and reflects more on my own inexperience with geospatial APIs than any fault of Android itself.