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);
}
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 theonProviderEnabled()
callback, call it inonCreate()
if the GPS radio is enabled, and fall-back to Network Location if GPS is disabled and Network Location is enabled.Something like this:
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.