如何将地图聚焦到用户位置



我创建了一个MapActivity,它将把地图聚焦到用户位置。

public void getMyLatLng() {
    LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    LocationListener ll = new LocationListener() {
        @Override
        public void onStatusChanged(String provider, int status,
                Bundle extras) {
        }
        @Override
        public void onProviderEnabled(String provider) {
        }
        @Override
        public void onProviderDisabled(String provider) {
        }
        @Override
        public void onLocationChanged(Location location) {
            myLatLng = new LatLng(location.getLatitude(),location.getLongitude());
        }
    };
    lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, ll);
    lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    //myLatLng = new LatLng(myLoc.getLatitude(), myLoc.getLongitude());
}

当它第一次运行时,我遇到了java.lang.NullPointerException问题。但当我再次运行它时,它会起作用。第二个问题是,当我使用NETWORK_PROVIDER而不是GPS_PROVIDER时,它会很好地工作。有什么建议可以解决这个问题吗?

您可以从GPS和nework请求位置更新类似这样的东西:

 public class LocationService implements LocationListener {
    boolean isGPSEnabled = false;
    boolean isNetworkEnabled = false;
    boolean canGetLocation = false;
    final static long MIN_TIME_INTERVAL = 60 * 1000L;
    Location location;

    // The minimum distance to change Updates in meters
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 10
    // The minimum time between updates in milliseconds
    private static final long MIN_TIME_BW_UPDATES = 1; // 1 minute
    protected LocationManager locationManager;
    private CountDownTimer timer = new CountDownTimer(5 * 1000, 1000) {
        public void onTick(long millisUntilFinished) {
        }
        public void onFinish() {
            stopUsingGPS();
        }
    };
    public LocationService() {
        super(R.id.gps_service_id);
    }

    public void start() {
        if (Utils.isNetworkAvailable(context)) {
            try {

                timer.start();

                locationManager = (LocationManager) context
                        .getSystemService(Context.LOCATION_SERVICE);
                isGPSEnabled = locationManager
                        .isProviderEnabled(LocationManager.GPS_PROVIDER);
                isNetworkEnabled = locationManager
                        .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
                this.canGetLocation = true;
                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 tempLocation = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (tempLocation != null
                                && isBetterLocation(tempLocation,
                                        location))
                            location = tempLocation;
                    }
                }
                if (isGPSEnabled) {
                    locationManager.requestSingleUpdate(
                            LocationManager.GPS_PROVIDER, this, null);
                    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 tempLocation = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (tempLocation != null
                                && isBetterLocation(tempLocation,
                                        location))
                            location = tempLocation;
                    }
                }
            } catch (Exception e) {
                onTaskError(e.getMessage());
                e.printStackTrace();
            }
        } else {
            onOfflineResponse(requestData);
        }
    }
    public void stopUsingGPS() {
        if (locationManager != null) {
            locationManager.removeUpdates(LocationService.this);
        }
    }
    public boolean canGetLocation() {
        locationManager = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);
        // getting network status
        isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        return isGPSEnabled || isNetworkEnabled;
    }
    @Override
    public void onLocationChanged(Location location) {
        if (location != null
                && isBetterLocation(location, this.location)) {
            this.location = location;
        }
    }
    @Override
    public void onProviderDisabled(String provider) {
    }
    @Override
    public void onProviderEnabled(String provider) {
    }
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }
    @Override
    public Object getResponseObject(Object location) {
        return location;
    }
    public static 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 > MIN_TIME_INTERVAL;
        boolean isSignificantlyOlder = timeDelta < -MIN_TIME_INTERVAL;
        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;
    }
}

请注意,每次我们得到一个位置时,我们都会将其与已知位置进行比较,通过调用isBetterLocation可以更好地找到这个新位置。

要从GPS卫星接收位置,需要一些时间。

如果你的测试地点在室内,GPS信号太长,所以你可能无法定位。

当你在建筑物里时,你可以接收位置,而不是使用网络提供商,但它的精度比GPS低。

如果你在android上使用谷歌地图api 2,你可以实现LocationSource来强制地图到你想要的位置。

最新更新