【问题标题】:How to get last location on Glass reliably?如何可靠地获取 Glass 上的最后一个位置?
【发布时间】:2014-02-17 08:03:09
【问题描述】:

来自LocationManager 的方法getLastLocation() 通常返回null,选择最佳提供者非常棘手。文档说:

警告:不要使用 LocationManager.getBestProvider() 方法或常量 GPS_PROVIDER 或 NETWORK_PROVIDER 来监听位置更新。 Glass 使用一组动态的提供者,并且只监听一个提供者可能会导致您的应用程序错过位置更新。

如何获得最佳的最后位置?

【问题讨论】:

    标签: google-glass google-gdk


    【解决方案1】:

    由于 Glass 使用一组动态的提供者,您需要从所有提供者中获取位置并选择最准确的位置:

     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;
     }
    

    【讨论】:

    • 我的玻璃杯中出现空值。我错过了什么吗?
    • 在其中一条线上,我认为 location.getAccuracy 应该是 location.getAccuracy()
    【解决方案2】:

    应调整答案中的代码以处理“0.0”的精度,这表示“NO Accuracy”已知!

    这是包含此调整的替代方案

    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;
    }
    

    【讨论】:

    • 我得到了该位置的空值。我错过了什么吗?
    【解决方案3】:

    Destil 的上述回答正确处理了至少一个提供者为getLastKnownLocation() 返回有效位置的情况。

    但是,我也看到 Glass 为所有提供商(特别是 XE16)返回 nullgetLastKnownLocation()

    在这种情况下,您唯一的选择是注册 LocationListener 并等待新的位置更新。

    例如,在创建新 Activity 时获取位置的上下文中,它将如下所示:

    public class MyActivity extends Activity implements LocationListener {
    ...
    LocationManager mLocationManager;
    Location mLastKnownLocation;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Activity setup
        ...
        // Use Destil's 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);
            }
        }
        ...
    }
    ...
    }
    

    然后您需要处理 LocationListener 回调:

    @Override
    public void onLocationChanged(Location location) {
        if (mLastKnownLocation == null) {
            // At least one location should be available now
            // Use Destil's 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) {}
    

    更改为异步模型以避免在等待更新时阻塞 UI 线程可能有点棘手,并且可能需要移动一些应用程序逻辑。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2013-04-11
      • 1970-01-01
      • 1970-01-01
      • 2017-05-27
      • 1970-01-01
      相关资源
      最近更新 更多