[This is part of the Android Diary.] Some notes on how, as a programmer, you can get practical use out of the “Location Providers” on early Android devices.
I’m really not working much on Android any more; it was essentially a Christmas-vacation project, and these days I’m having fun digging into Sun cloud stuff. Problem is, I had an Android paper accepted at Community One so I had to go back and do a little bit of polishing.
I had expanded my
little Android
cookie-crumbs app so it can map, not just geotagged feeds, but where
you’ve been with the phone. It sort of worked, except
for the GPS interface
was really unreliable. The online resources, for example Reto Meier’s
excellent
How To Program
Google Android, suggest that you all you need to do is ask a
locationManager
for a locationProvider
and use its
getLastKnownLocation()
. Easy enough, but I observed that the
location coming out of the GPS was typically, well, wrong. Unless I used the
Maps application first and asked for Current Location and stood outside under
the sky and waited two or three minutes for the GPS to stabilize and figure
out where I was.
So here’s what I eventually worked out. There may be a better way, but this works:
Although the interface to location providers is nicely abstracted, all the built-in code seems to know about the GPS and (cellphone) “Network” providers. So, mine does too.
When you start up you grab an approximate location from the Network provider, which could possibly be turned off but almost never is.
You stash that away in a bestLocation
global, and if
getAccuracy()
happens to work, stash that in a
bestAccuracy
global. Otherwise use a big estimate like
10km.
Also stash away a time a few minutes in the future, call it
stopTime
or something; the maximum time you’re going to spin
waiting for the GPS to come up with a good value.
Issue a call that looks something like this:
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 15 * 1000, 1, this);
This asks the GPS to check its position every 15 seconds and call your
onLocationChanged()
method when it notices a change.
In your onLocationChanged()
method, check the location’s
accuracy, and if it’s better than your best accuracy, you have a new
bestLocation
.
Also, see if your time has run out by checking against
stopTime
. If it has, use manager.removeUpdates()
to
cancel the GPS request.
That’s about the size of it. In English: Set the GPS to spin every little while for a few minutes, and chances it’ll stabilize and get you a decent position fix. Don’t forget to turn off the spinning or you’ll run down your battery in no time at all. And of course three-quarters of your code will be error handling for the cases where the provider service goes away or whatever. But it seems to work.