如何在 android 中获取准确的当前位置?

How to get Accurate Current location in android?

我试过getLastKnownLocation(),但我发现它有时无法提供准确的位置,而且它正在获取错误的位置,否则很好。

谁能帮帮我? 我是 android studio

的初学者

下面是我的 GPS 追踪器代码....

if (isGPSEnabled)
{
    locationManager.requestLocationUpdates(
            LocationManager.GPS_PROVIDER,
            MIN_TIME_BW_UPDATES,
            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

    Log.d("GPS Enabled", "GPS Enabled");

    if (locationManager != null)
    {
        location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        updateGPSCoordinates();
    }
}
} else if (isNetworkEnabled) {
locationManager.requestLocationUpdates(
        LocationManager.NETWORK_PROVIDER,
        MIN_TIME_BW_UPDATES,
        MIN_DISTANCE_CHANGE_FOR_UPDATES, this);

Log.d("Network", "Network");

if (locationManager != null)
{
    location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
    updateGPSCoordinates();
}
}

// ...

@Override
public void onLocationChanged(Location location) 
{ 
this.location = location;
updateGPSCoordinates();
}

Android Developper documentation 上有一个非常有用的页面,希望对您有所帮助。为了我的目的,我不得不稍微调整一下,但主要思想保持不变:

You might expect that the most recent location fix is the most accurate. However, because the accuracy of a location fix varies, the most recent fix is not always the best. You should include logic for choosing location fixes based on several criteria. The criteria also varies depending on the use-cases of the application and field testing.

private static final long TWO_MINUTES = TimeUnit.MINUTES.toNanos(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.getElapsedRealtimeNanos() - currentBestLocation.getElapsedRealtimeNanos();
    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);
}