views:

779

answers:

2

I am trying to determine the most accurate location of a device, in the shortest time possible.

I am storing the data as a geopoint, and have it displayed on a mapview.

The last time I activated the GPS on my device and let it get a location lock, i was approx 80 miles from where I am now.

I have a location manager setup and a location listener.

If I do this, I get NULL.

  myLocOverlay = new MyLocationOverlay(this, mapView);
  GeoPoint test = myLocOverlay.getMyLocation();

but in the next couple of lines;

  myLocOverlay.enableMyLocation();      
  mapView.getOverlays().add(myLocOverlay);

With this, the overlay on the map shows the current location. It is using the Network provider, but is also attempting to get a GPS fix (it can't as I am indoors and no where near the top floor).

If I construct the geopoint like this;

    if(lm.getLastKnownLocation("gps") != null) 
    {
     test = new GeoPoint(
        (int) (lm.getLastKnownLocation("gps").getLatitude() * 1E6), 
        (int) (lm.getLastKnownLocation("gps").getLongitude() * 1E6));
    }

    else
    {

    if(lm.getLastKnownLocation("network") != null) 
    {
     test = new GeoPoint(
       (int) (lm.getLastKnownLocation("network").getLatitude() * 1E6), 
       (int) (lm.getLastKnownLocation("network").getLongitude() * 1E6));
    }
    //bad things
    }

Then I get confusing results. If I disable the devices GPS provider then the code moves onto the Network Provider and gives me a fairly accurate result. If I enable the GPS provider, then the geopoint comes back as the last place I allowed the device to get a GPS lock.

I want to avoid the above results, and so was looking at using;

GeoPoint test = myLocOverlay.getMyLocation();

BUT as I said above, I just get NULL from that.

Short of getting the geopoints from both GPS and Network and then comparing them, and disregarding the GPS result if it is say 1 mile out of the Network location - i'm a bit stuck. why doesn't getMyLocation() work, shouldnt that return the GeoPoint of what myLocOverlay is showing on the mapview?

+2  A: 

It may return null because it hasn't obtained a fix yet. You should register a LocationListener that accepts updates from both the Network and GPS sources. Then, when you get a location update, you can look at the accuracy of the location and decide if you want to use it.

CaseyB
It is the initial value i want though, I want to the mapview to display roughly the right tiles. If we ignore getting any location updates, and just look at what is there already. I can pull two different locations from the providers, one from GPS and the other from Network. I want a way of getting the newest of the two. Which is what I thought getMyLocation() would do.
arc
"just look at what is there already" -- if it's `null`, there is nothing "there already".
CommonsWare
but then why does lm.getLastKnownLocation("gps").getLatitude() return a value.
arc
It returns a value due to the way GPS chipsets work. GPS chipsets have to different ways to acquire a fix, hot-fix and cold-fix. A hot0fix is where it takes the last location that it knew about and starts trying to query satellites that should be in that area. If you haven't moved too far it will find them and be able to get a quick fix. If a hot-fix fails it will go to a cold-fix where it starts trying to query all the satellites that exist until it finds some that talk back.
CaseyB
It always tries a hot fix first because it is a LOT faster, so it has to store the last known location even if it does turn out to be really far away.
CaseyB
I don't think i'm being clear with that I mean. enableMyLocation() on an overlay shows the devices location on a mapview. Where is that data coming from? I have commented out all my code in onLocationChanged, so i know its not updates. Why doesn't getMyLocation() return the geocode of the point that is being displayed on the map
arc
+1  A: 

I would guess that you are asking too fast for a geo point. The MyLocationOverlay will use its own listeners to retrieve a fix. And maybe it is asking for the gps fix looking how old that is, then if that is too old acquiring the network fix and using that while waiting for a gps fix.

This means speaking with the gps chipset and the gsm modem and a web backend in the background.
That won't be possible in the time your program needs to go to the next line.

In the UI it will look pretty instantaneous but that is measured with humans eyes.

You could go with the answer from CaseyB and register your own gps listener on both of the providers and decide for yourself which coorodinate you want to use. If you want to do this there are methods to acquire time of the last fix (Location.getTime()) and accuracy for locations.

The second possibility is to wait a little bit and look if the call still returns null if so then wait a little bit longer.

Janusz
Thanks. I think the best option would be to keep checking the call until it returns a value. I did begin writing some logic to 'pick' the best location fix - but if the code is already there, and works well then it makes sense to make use of it. I am curious as to how to get the time of the last fix - I've yet to find that on the documentation (but know about accuracy).
arc
I added this to my answer it is loctaion.getTime()
Janusz