How to reliably get the last place on the glass?

The getLastLocation() method from LocationManager often returns null, and it's pretty hard to choose the best provider. The documentation states:

A warning. Do not use the LocationManager.getBestProvider () method or GPS_PROVIDER or NETWORK_PROVIDER constants to listen for location updates. Glass uses a dynamic set of providers and listening to only one provider may cause your application to skip location updates.

How to get the best last location?

+7
google-glass google-gdk
source share
3 answers

Since Glass uses a dynamic set of suppliers, you need to get a location from all of them and choose a location with the greatest accuracy:

  public static Location getLastLocation(Context context) { LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); Criteria criteria = new Criteria(); criteria.setAccuracy(Criteria.NO_REQUIREMENT); List<String> providers = manager.getProviders(criteria, true); List<Location> locations = new ArrayList<Location>(); for (String provider : providers) { Location location = manager.getLastKnownLocation(provider); if (location != null && location.getAccuracy()!=0.0) { locations.add(location); } } Collections.sort(locations, new Comparator<Location>() { @Override public int compare(Location location, Location location2) { return (int) (location.getAccuracy() - location2.getAccuracy()); } }); if (locations.size() > 0) { return locations.get(0); } return null; } 
+8
source share

The correct answer from Destil handles the case when at least one provider returns a valid location for getLastKnownLocation() .

However, I also saw Glass return null for getLastKnownLocation() for all providers (specifically in XE16).

In this case, your only option is to register a LocationListener and wait for the new location to be updated.

For example, in the context of obtaining a location when creating a new action, it looks like this:

 public class MyActivity extends Activity implements LocationListener { ... LocationManager mLocationManager; Location mLastKnownLocation; @Override protected void onCreate(Bundle savedInstanceState) { // Activity setup ... // Use Destil answer to get last known location, using all providers mLastKnownLocation = getLastLocation(this); if (mLastKnownLocation != null) { // Do something with location doSomethingWithLocation(mLastKnownLocation); } else { // All providers returned null - start a LocationListener to force a refresh of location mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); List<String> providers = mLocationManager.getProviders(true); for (Iterator<String> i = providers.iterator(); i.hasNext(); ) { mLocationManager.requestLocationUpdates(i.next(), 0, 0, this); } } ... } ... } 

Then you need to handle the LocationListener callbacks:

 @Override public void onLocationChanged(Location location) { if (mLastKnownLocation == null) { // At least one location should be available now // Use Destil answer to get last known location again, using all providers mLastKnownLocation = getLastLocation(this); if (mLastKnownLocation == null) { // This shouldn't happen if LocationManager is saving locations correctly, but if it does, use the location that was just passed in mLastKnownLocation = location; } // Stop listening for updates mLocationManager.removeUpdates(this); // Do something with location doSomethingWithLocation(mLastKnownLocation); } } @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override public void onProviderEnabled(String provider) {} @Override public void onProviderDisabled(String provider) {} 

It can be a little tricky to switch to an asynchronous model to avoid blocking the UI thread while waiting for an update, and you may need to move some part of your application logic.

+4
source share

The code in the response must be adjusted to handle the accuracy of "0.0", which represents the "NO Accuracy" known!

Here is an alternative that includes this setting

 public static Location getLastLocation(Context context) { Location result = null; LocationManager locationManager; Criteria locationCriteria; List<String> providers; locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); locationCriteria = new Criteria(); locationCriteria.setAccuracy(Criteria.NO_REQUIREMENT); providers = locationManager.getProviders(locationCriteria, true); // Note that providers = locatoinManager.getAllProviders(); is not used because the // list might contain disabled providers or providers that are not allowed to be called. //Note that getAccuracy can return 0, indicating that there is no known accuracy. for (String provider : providers) { Location location = locationManager.getLastKnownLocation(provider); if (result == null) { result = location; } else if (result.getAccuracy() == 0.0) { if (location.getAccuracy() != 0.0) { result = location; break; } else { if (result.getAccuracy() > location.getAccuracy()) { result = location; } } } } return result; } 
+1
source share

All Articles