Why Does Map Marker Lurch Around The Map

131 Views Asked by At

I'm in Android Studio and I have a map fragment (com.google.android.gms.maps.SupportMapFragment) that has two markers. One is static and called Target. The other tracks my movements and is called Hunter. It works but the problem is that the Hunter marker lurches about. I have the update interval set at 15 milliseconds, but at walking speed it only updates about once every block.

So, how do I properly add a marker to track my location and have it be reasonably accurate and update in real-time? Or what am I doing wrong here?

Greg

onCreate()

    setUpMapIfNeeded();

    if (mMap != null) {
        LatLng Target = new LatLng(TargetLat, TargetLong);
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(Target, 15));
    }


    LocationManager locationManager = (LocationManager) this.getSystemService(this.LOCATION_SERVICE);

    LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            makeUseOfNewLocation(location);
        }

        public void onStatusChanged(String provider, int status, Bundle extras) {}

        public void onProviderEnabled(String provider) {
            registerForUpdates();
        }

        public void onProviderDisabled(String provider) {
            deregisterForUpdates();
        }
    };

    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);


private void registerForUpdates() {
    _locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPS_FREQUENCY_MILLIS, 0, _locationListener);
}

Update marker when location changes. When we get close to the target, vibrate and change the text.

    private void makeUseOfNewLocation(Location loc) {
    HunterLat = loc.getLatitude();
    HunterLong = loc.getLongitude();

    if (Hunter != null) {
        LatLng NewLoc = new LatLng(HunterLat, HunterLong);
        Hunter.setPosition(NewLoc);

        TextView txtItem = (TextView) findViewById(R.id.ItemName);

        if (HunterLong > TargetLong - .0007 && HunterLong < TargetLong + .0007 && HunterLat > TargetLat - .0007 && HunterLat < TargetLat + .0007) {
            txtItem.setTextColor(Color.MAGENTA);
            txtItem.setText(ItemName);
            if (!Vibrated){
                Vibrated = true;
                Vibrator v = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);
                v.vibrate(500);
            }
        }
        else {
            txtItem.setTextColor(Color.BLACK);
            txtItem.setText(getResources().getString(R.string.hunt_item));
        }
    }
    else {
        Hunter = mMap.addMarker(new MarkerOptions().position(new LatLng(HunterLat, HunterLong)).title("You"));
        BitmapDescriptor icon2 = BitmapDescriptorFactory.fromResource(R.drawable.ic_map_person);
        Hunter.setIcon(icon2);

    }
}

Set up the map and add the static target marker

   private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the map.
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                .getMap();
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
}

private void setUpMap() {
    Marker Target = mMap.addMarker(new MarkerOptions().position(new LatLng(TargetLat, TargetLong)).title(Location));
    BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.ic_target);
    Target.setIcon(icon);
}
2

There are 2 best solutions below

2
On BEST ANSWER

After seeing your other question, it looks like the non-map Activity is getting the onProviderEnabled() callback, but your map Activity is not getting it (unless the GPS radio is enabled during use of the map Activity).

Instead of only calling registerForUpdates() in the onProviderEnabled() callback, call it in onCreate() if the GPS radio is enabled, and fall-back to Network Location if GPS is disabled and Network Location is enabled.

Something like this:

    LocationManager locationManager = (LocationManager) this.getSystemService(this.LOCATION_SERVICE);
    if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        registerForUpdates();
    }
    else if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    }

Another thing to note is that you should unregister from all location callbacks in the onPause() override for your Activities that request location updates, so that you don't have unnecessary battery drain caused by your app.

1
On

I was using network instead of GPS.

Changed

 locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

To

 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

It now tracks my movements smoothly. Thanks to Daniel Nugent for pointing this out to me an another post.

Greg