Show Current Location in a Google Map for Android

Here is a full Activity class that places a Marker at the current location, and also moves the camera to the current position. There are a few things going on in sequence here: Check Location permission Once Location permission is granted, call setMyLocationEnabled(), build the GoogleApiClient, and connect it Once the GoogleApiClient is connected, request […]

Shibaji Debnath

Show Current Location in a Google Map for Android

Here is a full Activity class that places a Marker at the current location, and also moves the camera to the current position.
There are a few things going on in sequence here:

  • Check Location permission
  • Once Location permission is granted, call setMyLocationEnabled(), build the GoogleApiClient, and connect it
  • Once the GoogleApiClient is connected, request location updates

MapLocationActivity.java

public class MapLocationActivity extends AppCompatActivity implements OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener {
          
    GoogleMap mGoogleMap;
    SupportMapFragment mapFrag;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Location mLastLocation;
    Marker mCurrLocationMarker;
          
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
        getSupportActionBar().setTitle("Map Location Activity");
        mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFrag.getMapAsync(this);
    }
          
    @Override
    public void onPause() {
        super.onPause();
        //stop location updates when Activity is no longer active
        if (mGoogleApiClient != null) {
          LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }
          
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mGoogleMap=googleMap;
        mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        //Initialize Google Play Services
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
          if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { 
            //Location Permission already granted 
            buildGoogleApiClient(); 
            mGoogleMap.setMyLocationEnabled(true);
          } else {
            //Request Location Permission
            checkLocationPermission();
          }
    } else {
        buildGoogleApiClient();
        mGoogleMap.setMyLocationEnabled(true); }
  }
          
  protected synchronized void buildGoogleApiClient() { 
      mGoogleApiClient = new GoogleApiClient.Builder(this).addConnectionCallbacks(this).addOnConnectionFailedListener(this).addApi(LocationServices.API).build();
        mGoogleApiClient.connect();
  }
          
  @Override
  public void onConnected(Bundle bundle) {
      mLocationRequest = new LocationRequest();
      mLocationRequest.setInterval(1000);
      mLocationRequest.setFastestInterval(1000);
      mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
      if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
      }
  }
          
  @Override
  public void onConnectionSuspended(int i) {}
          
  @Override
  public void onConnectionFailed(ConnectionResult connectionResult) {}
          
  @Override
  public void onLocationChanged(Location location) {
      mLastLocation = location;
      if (mCurrLocationMarker != null) {
          mCurrLocationMarker.remove();
      }
      //Place current location marker
      LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); 
      MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(latLng);
      markerOptions.title("Current Position");
      markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));         mCurrLocationMarker = mGoogleMap.addMarker(markerOptions);
      //move map camera
      mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
      mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(11));
    
    //stop location updates
    if (mGoogleApiClient != null) {
      LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
    }
  }
  
  public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99; 

  private void checkLocationPermission() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
      // Should we show an explanation?
      if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
      // Show an explanation to the user *asynchronously* -- don't block 
      // this thread waiting for the user's response! After the user
      // sees the explanation, try again to request the permission.
      new AlertDialog.Builder(this).setTitle("Location Permission Needed").setMessage("This app needs the Location permission, please accept to use location functionality").setPositiveButton("OK", new DialogInterface.OnClickListener() { 
        @Override
        public void onClick(DialogInterface dialogInterface, int i) { 
          //Prompt the user once explanation has been shown
          ActivityCompat.requestPermissions(MapLocationActivity.this, 
                new String[]{
                  Manifest.permission.ACCESS_FINE_LOCATION 
                }, MY_PERMISSIONS_REQUEST_LOCATION );
        } 
      }).create().show();
        
  } else {
  // No explanation needed, we can request the permission.
      ActivityCompat.requestPermissions(this,
            new String[]{
              Manifest.permission.ACCESS_FINE_LOCATION
            }, MY_PERMISSIONS_REQUEST_LOCATION );
      } 
    }
  }
          
  @Override
  public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
      case MY_PERMISSIONS_REQUEST_LOCATION: {
        // If request is cancelled, the result arrays are empty.
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
              // permission was granted, yay! Do the
              // location-related task you need to do.
              if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                          == PackageManager.PERMISSION_GRANTED) {
                  if (mGoogleApiClient == null) { 
                    buildGoogleApiClient();
              }
              mGoogleMap.setMyLocationEnabled(true); 
          }
        } else {
            // permission denied, boo! Disable the
            // functionality that depends on this permission. 
            Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
        }
            return; 
      }
        // other 'case' lines to check for other
        // permissions this app might request
    } 
  }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent">
        <fragment xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              xmlns:map="http://schemas.android.com/apk/res-auto"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:id="@+id/map"
              tools:context="com.example.app.MapLocationActivity"
              android:name="com.google.android.gms.maps.SupportMapFragment"/>
</LinearLayout>

Result:

Show explanation if needed on Marshmallow and Nougat using an AlertDialog (this case happens when the user had previously denied a permission request, or had granted the permission and then later revoked it in the settings):

Prompt the user for Location permission on Marshmallow and Nougat by calling ActivityCompat.requestPermissions():

Move camera to current location and place Marker when the Location permission is granted:

Call