【问题标题】:Not able to get accurate location on android device无法在安卓设备上获取准确位置
【发布时间】:2019-05-22 12:30:00
【问题描述】:

我们开发了一个像 ola 和 uber 这样的外卖应用。骑手可以在哪里接受订单并交付给客户。我们已经创建了一个 android 服务(后台服务),我们已经初始化了我们的位置变量。我们通过 3 种方法获取位置,网络提供商、Gps 提供商、Google Fused 位置 API。所有这三个我们都用来获取一个位置,当我们得到一个位置时,它存储到我们的成员变量中(后来它在辅助项目中使用),并且相同的位置被保存到我们的服务器中以对抗该骑手。我们具体面临2或3个问题。 1.有时用户位置是正确的,在 20-30 秒内我们得到了一些错误的位置,准确度说 > 50 或 100。 2.有些时间位置卡了几分钟或者卡了一个小时。

我们正在使用 Google 规定的专门定位策略。下面是示例。

private static final int TWO_MINUTES = 1000 * 60 * 2;

/** Determines whether one Location reading is better than the current Location fix
 * @param location  The new Location that you want to evaluate
 * @param currentBestLocation  The current Location fix, to which you want to compare the new one
 */
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
    if (currentBestLocation == null) {
        // A new location is always better than no location
        return true;
    }

    // Check whether the new location fix is newer or older
    long timeDelta = location.getTime() - currentBestLocation.getTime();
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
    boolean isNewer = timeDelta > 0;

    // If it's been more than two minutes since the current location, use the new location
    // because the user has likely moved
    if (isSignificantlyNewer) {
        return true;
        // If the new location is more than two minutes older, it must be worse
    } else if (isSignificantlyOlder) {
        return false;
    }

    // Check whether the new location fix is more or less accurate
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
    boolean isLessAccurate = accuracyDelta > 0;
    boolean isMoreAccurate = accuracyDelta < 0;
    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

    // Check if the old and new location are from the same provider
    boolean isFromSameProvider = isSameProvider(location.getProvider(),
            currentBestLocation.getProvider());

    // Determine location quality using a combination of timeliness and accuracy
    if (isMoreAccurate) {
        return true;
    } else if (isNewer && !isLessAccurate) {
        return true;
    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
        return true;
    }
    return false;
}

/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
    if (provider1 == null) {
        return provider2 == null;
    }
    return provider1.equals(provider2);
}


if (isMoreAccurate)
{
    return true;
}
else if (isNewer && !isLessAccurate) 
{
    return true;
}
else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) 
{
    return true;
}

return false;

我不知道下一步该做什么。

我已经集成了网络提供、GPS 提供者和融合位置提供者。我正在获取位置,但不太准确。我还维护了最近 10 个连续位置的列表。当我收到第 11 个位置时,我搜索到列表,如果发现所有位置都相同(这意味着位置被卡住),那么我清除了我的列表并通过停止并使用新连接再次重新启动服务来删除位置连接。

【问题讨论】:

    标签: android gps location


    【解决方案1】:

    Android 有restrictions 用于从后台服务获取位置更新。您要么必须从前台活动获取位置,要么将您的服务更改为带有固定通知的前台服务,以获取定期位置更新。

    定位精度问题也可能是由于用户未在设备中设置高精度定位模式。这将检查用户设备中是否启用了位置。如果启用了定位但未启用高精度,则会显示对话框。

    private static final int REQUEST_CHECK_SETTINGS = 001;
    
    private void displayLocationSettingsRequest(Context context) {
            GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context)
                    .addApi(LocationServices.API).build();
            googleApiClient.connect();
    
            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationRequest.setInterval(10000);
            locationRequest.setFastestInterval(10000 / 2);
    
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
            builder.setAlwaysShow(true);
    
            PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
            result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
                @Override
                public void onResult(LocationSettingsResult result) {
                    final Status status = result.getStatus();
                    switch (status.getStatusCode()) {
                        case LocationSettingsStatusCodes.SUCCESS:
                            //Location settings satisfied
                            break;
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            //Location settings are not satisfied. Show the user a dialog to upgrade location settings
                            try {
                                status.startResolutionForResult(Activity.this, REQUEST_CHECK_SETTINGS);
                            } catch (IntentSender.SendIntentException e) {
                                LogUtil.i("PendingIntent unable to execute request.");
                            }
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            //Location settings are inadequate, and cannot be fixed here. Dialog not created.
                            Toast.makeText(Activity.this, "Error enabling location. Please try again", Toast.LENGTH_SHORT).show();
                            break;
                    }
                }
            });
        }
    

    【讨论】:

    • 是的,我们只实施了前台服务(特定于 oreo)。很抱歉没有在问题中提及。
    • @DeepakPrasad 你能发布你的完整代码吗?你在实施 LocationListener 吗?您在位置请求中定义了什么频率和优先级?此外,FusedLocation 基于设备移动、gps、wifi 和蓝牙,因此您不必分别从移动和 gps 提供商获取位置。
    • 是的@Arun,我用过LocationListener。优先级为 HIGH,频率为 30 秒。
    • @DeepakPrasad 如果您已经正确实现了 LocationListener,那么您应该在OnLocationChanged() 回调中获得定期更新。您的服务不是完全前台,因此您在一段时间后没有获得位置更新,或者您的位置实施存在问题。确保您的服务有一个固定通知,以指示您的服务是否正在运行。如果您确定它正在运行,那么它可能是您的位置实施的问题。您正在从多个来源获取位置并对其进行处理,因此该逻辑可能存在问题。
    • 是的,我们从 3 个来源获取位置。在每种情况下,当我们的应用收到新位置时,都会调用 OnLocationChanged。我遵循了新的前台服务方式来实现这一点(通过后台服务示例进行谷歌定位)。我发布了我的小代码以找出更好的位置。还有什么我需要执行的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-19
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多