融合位置提供程序 - onLocationChanged停止调用

时间:2016-05-23 15:50:58

标签: android gps google-play-services location-services fusedlocationproviderapi

在我们的应用中,我们使用融合位置提供程序(FLP)来跟踪位置。我们注意到,应用程序偶尔会进入一个状态,其中位置回调停止被调用。该应用程序主要用于两个平板电脑(nexus 7和LG G-pad 8.3)。我们已经看到两个设备都出现了这个问题。通常,重置设备似乎可以缓解这个问题。我们相信我们遵循大多数使用FLP的最佳实践。但是,以防我们整理这个示例代码,说明我们如何使用FLP。

获取google api客户端并致电connect:

m_googleApiClient = builder
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
m_googleApiClient.connect()

连接后,我们开始侦听位置回调:

@Override
public void onConnected(Bundle bundle) {
    m_fusedLocationProviderApi.requestLocationUpdates(m_googleApiClient, m_locationRequest, this);
}

位置请求如下所示:

    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
    locationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);

然后我们像这样实现回调:

    @Override
public void onLocationChanged(Location location) {
   // set location member var and record timestamp.
}

当问题发生时,我们似乎没有得到任何错误回调。当我们检测到我们在很长一段时间内没有收到GPS时,我们也尝试在google api客户端上调用reset()。我们还每2秒使用一个计时器监控位置可用性(使用getLocationAvailability)。通常我们发现让用户重置他们的设备(开机,关机)可以解决问题。

我们的问题是:

  1. 还有其他人注意到FLP的这个问题吗?
  2. 我们还能做些什么来解决问题,而不是让用户重置?会删除添加位置更新帮助吗?
  3. 我们可以/应该收集更多信息来诊断问题吗?

2 个答案:

答案 0 :(得分:3)

我与FusedLocationProvider在广泛的设备上进行了广泛的合作,包括低端和低端设备。高端和已经看到类似的问题,其中GPS数据之间存在不良补丁。因此,我做了一些改变,以应对与可靠性和可靠性相关的这些问题。坚固性(如下所列)和在此之后还没有看到这些问题。

根据我的经验,这些问题的可能解决方案是:

  1. 更新Play服务 当我遇到这些问题时,我正在使用7.x - 8.x范围内的Android Play服务版本。

      
        

    Sol:最近,更新到10.x版本的播放服务有助于解决问题。我们在更新后没有看到这些问题,所以这肯定也是您案例中的原因之一。

      
  2. 让Android服务更可靠&健壮: 这是我们看到GPS数据停电的主要原因之一,当重新启动设备或再次初始化设置时,我们通常会重启服务。因此,重新启动的服务可能会使位置更新恢复正常。

      
        

    Sol:我使用Foreground Service而不是后台服务,这是迄今为止最可靠的解决方案,但这会为用户提供粘性UI通知。如果不是这样,那么为后台服务保持健康检查(运行或杀死)也是一个不错的选择。

      
  3. 在连接暂停/错误时重新连接GoogleAPIClient 我已经看到GoogleAPIClient连接被挂起或由于网络状况不佳或其他原因而返回错误的情况。虽然我无法验证这对位置数据丢失的直接影响,但在这种情况下,这很可能是一个原因。为了支持这一点,如果发生GoogleAPIClient连接问题,重置位置更新将会失败,这也是您所观察到的。

      
        

    Sol: GoogleAPIClient在暂停或错误时的简单重新连接可以解决此问题。

      
  4. 除此之外,还有一个原因可以解决这个问题:

    设备GPS修复丢失: 有时设备会丢失其GPS定位导致GPS数据缺失,直到它可以恢复GPS定位。由于GPS定位,绝对无法确定位置是否丢失。重置设备的位置设置会影响设备尝试GPS修复,这也可能是此原因。

    免责声明:我是Android开发者@ HyperTrack,我们正在为在应用中构建位置功能的开发人员开发位置堆栈,这些都是问题我们一直在解决。您可以使用我们的SDKs测试类似的情况,如果您仍然看到问题我们很乐意帮助您找到根本原因并解决问题。

答案 1 :(得分:-2)

您可以尝试像这样检查LocationSettings:

    request = LocationRequest.create();
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(request);
    builder.setAlwaysShow(true);
    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(apiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(@NonNull LocationSettingsResult result) {
            final Status status = result.getStatus();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, request, locationListener);
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    try {
                        status.startResolutionForResult(context, REQUEST_CODE);
                    } catch (IntentSender.SendIntentException e) {}
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    break;
            }
        }
    });

然后在onActivityResult

中处理设置请求
switch (requestCode) {
    case REQUEST_CODE:
      switch (resultCode) {
        case Activity.RESULT_OK:
        // All required changes were successfully made
        LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, request, locationListener);
        break;
        case Activity.RESULT_CANCELED:
        // The user was asked to change settings, but chose not to
        break;
        default:
        break;
      }
    break;
}

如果没有帮助,请尝试降级google-play-services版本。