FusedLocationProvider损坏了吗?

时间:2018-10-17 14:34:34

标签: android location fusedlocationproviderapi google-location-services

我有一个FusedLocationProviderClient,每2分钟请求一次定位。现在已经存在了很长时间的问题,在某些情况下用户不会收到位置更新,并且由于我们在应用程序中的处理方式,我们有效地将用户锁定在应用程序的主要部分之外。

再次访问该主题后,我发现根据developer guide,如果您禁用了GPS,则清除了位置缓存。

细腻而有趣,因此,下次用户访问该应用程序时,您希望缓存被清除,客户端获取更新所需的时间会稍长一些,因此您可以再次访问。可悲的是,事实并非如此。我在15:55禁用了gps,将其保留到16:00,然后在16:00重新启用,但在16:40仍然没有更新

我发现我可能在请求任务中某处出现异常,因此我添加了所有4个回调(onFailure,onCanceled,onSuccess,onComplete),并得到了onSuccessonComplete的信号,没有什么不对。

我正在使用play-services-base 16.0.1play-services-location 16.0.0。我已授予权限ACCESS_FINE_LOCATION,并且我肯定是使用FusedLocationProviderClient::requestLocationUpdates

开始了位置更新请求

这是我的代码

public class LocationHandler extends LocationCallback {

  private static final String APPSTART_LOCATION = "APPSTART_LOCATION";
  private static final String MOST_RECENT_LOCATION = "MOST_RECENT_LOCATION";

  private final static int GPS_TIMEOUT = 3000;

  private final Context context;
  private final PreferencesHandler preferences;
  private final Bus eventBus;
  private BehaviorRelay<Location> subject;
  private FusedLocationProviderClient client;

  private boolean isRequestingLocations = false;
  private Disposable timerDisposable;

  public LocationHandler(Context context, PreferencesHandler preferences, Bus eventBus) {
    this.context = context;
    this.preferences = preferences;
    this.eventBus = eventBus;
    subject = BehaviorRelay.create();
    client = new FusedLocationProviderClient(context);
  }

  @SuppressLint("MissingPermission")
  public void connect() {
    if (!isRequestingLocations && hasRequiredPermissions()) {
      client.requestLocationUpdates(createLocationRequest(), this, null)
          .addOnFailureListener(e -> Timber.e(e, "onFailure"))
          .addOnCanceledListener(() -> Timber.d("onCanceled"))
          .addOnSuccessListener(aVoid -> Timber.d("onSuccess"))
          .addOnCompleteListener(task -> Timber.d("onComplete"));
      isRequestingLocations = true;

      //start a timer so the client will act like nothing's amiss if he didn't receive a location-update within the given timeout
      timerDisposable = Observable.timer(GPS_TIMEOUT, TimeUnit.MILLISECONDS).subscribe(ignored -> {

        //the reason why this happens is because the provider just uses cached locations. When the user deactivates GPS, the cache is cleared
        //once you reactivate gps it should technically work, but it takes a long time nonetheless

        ReportingUtil.trackFbEvent(new GPS_NO_LOCATION_RECEIVED((int) TimeUnit.MILLISECONDS.toSeconds(GPS_TIMEOUT)));
        preferences.setHasGeolocation(true);
        eventBus.post(new NoLocationReceivedEvent());
        eventBus.post(new FirstLocationArrivedEvent());
      });
    }
  }

  private LocationRequest createLocationRequest() {
    LocationRequest request = new LocationRequest();
    long interval = TimeUnit.MINUTES.toMillis(Constants.GPSINTERVAL);
    request.setInterval(interval);
    request.setFastestInterval(interval);
    request.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    return request;
  }

  public void disconnect() {
    if (isRequestingLocations) {
      timerDisposable.dispose();
      client.removeLocationUpdates(this);
      isRequestingLocations = false;
    }
  }

  public Observable<Location> getAllLocations() {
    return subject;
  }

  @Override
  public void onLocationResult(LocationResult result) {
    Timber.d("onLocationResult: %s", result);
    if (result != null && result.getLocations().size() != 0) {
      Location location = result.getLocations().get(0);
      if (location != null) {
        if (timerDisposable != null) {
          timerDisposable.dispose();
        }
        subject.accept(new Location(location));
      }
    }
  }

  private boolean hasRequiredPermissions() {
    return ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
  }

  public void restart() {
    disconnect();
    connect();
  }

}

0 个答案:

没有答案