Search code examples
androidgoogle-mapsgoogle-maps-api-2onresumelocation-services

Location in Map Activity not set immediately?


What I want is my map activity to zoom to the users current location when the map is opened. If I enable location services before running the app, it works fine. When I disable location services and run my app, I have a prompt for the user to turn on location services. It takes them to settings to turn it on, and when they hit back, the map should zoom to their current location. I've placed my zoomToLocation in setUpMap(), which is called in OnResume(), but for whatever reason it doesn't seem to work.

Code:

Location Services check:

private boolean checkLocationEnabled() {
    //credits: http://stackoverflow.com/questions/10311834/how-to-check-if-location-services-are-enabled
    LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    final boolean gpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    boolean networkEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    if (!gpsEnabled) {
        AlertDialog.Builder gpsAlertBuilder = new AlertDialog.Builder(this);
        gpsAlertBuilder.setTitle("Location Services Must Be Turned On");
        gpsAlertBuilder.setMessage("Would you like to turn them on now? (Note: if not, you will be unable to use the map to find breweries. You will still be able to search for them.");
        gpsAlertBuilder.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
                Intent enableGPSIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                startActivity(enableGPSIntent);
            }
        });
        gpsAlertBuilder.setNegativeButton("No", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();

            }
        });
        AlertDialog gpsAlert = gpsAlertBuilder.create();
        gpsAlert.show();
    }

    return gpsEnabled;


}

Zoom and zoomToLocation() methods:

 private void zoom(Location location) {
    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
            new LatLng(location.getLatitude(), location.getLongitude()), 13));

    CameraPosition cameraPosition = new CameraPosition.Builder()
            .target(new LatLng(location.getLatitude(), location.getLongitude()))      // Sets the center of the map to location user
            .zoom(17)                   // Sets the zoom// Sets the orientation of the camera to east// Sets the tilt of the camera to 30 degrees
            .build();                   // Creates a CameraPosition from the builder
    mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}

private void zoomToLocation() {
    //credits: http://stackoverflow.com/questions/18425141/android-google-maps-api-v2-zoom-to-current-location
    //http://stackoverflow.com/questions/14502102/zoom-on-current-user-location-displayed/14511032#14511032
    LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    Criteria criteria = new Criteria();

    Location location = locationManager.getLastKnownLocation(locationManager.getBestProvider(criteria, false));
    if (location != null) {

        zoom(location);

    } else {

       return;
    }

}

setUpMap method:

private void setUpMap() {
    UiSettings settings = mMap.getUiSettings();
    settings.setZoomControlsEnabled(true);
    settings.setZoomGesturesEnabled(true);
    mMap.setMyLocationEnabled(true);
    settings.setMyLocationButtonEnabled(true);
    setUpActionBar();
    if(checkLocationEnabled()) {
        zoomToLocation();

    }
}

OnResume method:

 protected void onResume() {
    super.onResume();
    setUpMapIfNeeded(); //setUpMap called in setUpMapIfNeeded
}

And finally mySetUpMapIfNeeded() method:

  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();
            setUpActionBar();
        }
    }
}

Solution

  • Your setUpMapIfNeeded() onResume is probably called.

    But in your setUpMapIfNeeded you only call setUpMap() if first mMap is null. Which isn't null when you resume your application. You have to set zoom level using some other function as well other than inside setUpMap().

    Something like this.

    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();
                setUpActionBar();
            }
        }
        else{
             //setup zoom level since your mMap isn't null.
        }
    }