View Course Path

LocationManager Tutorial in Android Studio : Getting the User’s Location Coordinates – Full Code and Explanation

In this tutorial, we will learn how to get the user’s location coordinates – Latitude, Longitude and Altitude by building a simple Android Application that will use the LocationManager class.

What is LocationManager?

This class provides access to the device’s location services. These services allow the applications to obtain periodic updates of the device’s geographical location, or to be notified when the device enters the proximity of a given geographical location. This class helps to leverage the location capabilities of the user’s Android device.

To use this class, we first need to obtain some permissions from the user. These are:

  • Manifest.permission.ACCESS_COARSE_LOCATION: This allows the app to access the approximate location of the user.
  • Manifest.permission.ACCESS_FINE_LOCATION: This allows the app to access the exact location of the user.

Note that declaring the ACCESS_FINE_LOCATION permission implies the ACCESS_COARSE_LOCATION permission already.

Instantiating the Location Manager

To get a reference of the LocationManager, we use the getSystemService() method, to access the Location Service of the device.

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

Setting Up LocationListener

After getting the reference of the LocationManager, now we need to get the current location of the user. To do that we set up the LocationListener – an Event Listener that tells us when the location has changed. This interface has three methods:

  • abstract void onLocationChanged(Location location): This method is called when the location has changed. The location object contains all the attributes of the user’s current location, like Latitude, Longitude and Altitude.
  • default void onProviderDisabled(String provider): This method is called when the Location Provider (or the location service of the device like GPS) has been disabled by the user.
  • default void onProviderEnabled(String provider): This method is called when the Location Provider (or the location service of the device like GPS) has been enabled by the user.

Here is how we set up the LocationListener:

LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(android.location.Location location) {
 //get the attributes of current location using the location variable
 //example, location.getLatitude()
}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onProviderDisabled(String provider) {

}
};

To get the location of the user, we use the requestLocationUpdates() method of LocationManager class. It takes in 4 arguments:

  • String provider: a location provider, to see a list of all location providers, use getAllProviders(). This value cannot be null.
  • long minTimeMs: minimum time interval between location updates in milliseconds. The location updates will be sent when the time specified by the parameter has passed.
  • float minDistanceM: minimum distance between location updates in meters. The location will be updated when the difference between the present location and previous location is greater than or equal to this value.
  • LocationListener listener: the listener to receive location updates This value cannot be null.

How to use it in code:

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

Creating the App

We will now begin creating our app. The function of the app is pretty simple and straightforward: get the location coordinates of the user and display it on the button click. Create a new project with an empty activity.

Defining the Layout

Our layout will have 2 widgets:

  • TextView: To display the coordinates
  • Button: To get the location coordinates

Open up activity_main.java and write the following:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/textview1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="156dp"
        android:text="Get My Location"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textview1" />

</androidx.constraintlayout.widget.ConstraintLayout>

Adding the Permissions in the Manifest

Open up AndroidManifest.xml, and add these lines above the beginning of the <application> tag:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>

Permission Handling

We need to ask the user explicitly to grant the permissions required by our app, and if the user denies those permissions, we need to notify them that the action cannot be performed without permission. Every time we perform an action that requires some permissions – e.g. the requestLocationUpdates() method of LocationManager requires location permissions; we need to check whether the permission has already been provided by the user or not. If not, then we will trigger the mechanism that will ask for permissions.

To do that, we use the ActivityCompat.checkSelfPermission() method to check for permissions, and ActivityCompat.requestPermissions to request for the permissions. The function descriptions are as follows:

int checkSelfPermission (Context context, String permission)

The arguments to this method:

  • context –  The Context of the Activity/Fragment calling this method
  • String permission- The name of the permission being checked.

It returns PERMISSION_GRANTED if you have the permission, or PERMISSION_DENIED if not.

void requestPermissions (Activity activity, String[] permissions, int requestCode)

The arguments to this method:

  • activity: The target activity.
  • String [] permissions: The requested permissions. Must be non-null and not empty.
  • requestCode: Application specific request code to match with the result obtained after permission
  • request through the onRequestPermissionsResult(). This is useful when we have multiple function
  • calls to requestPermissions(), and we need to identify which method call has triggered the callback. Its value should be >= 0.

Here’s how to check for permissions and request permissions for location:

if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(MainActivity.this, new String[] {
            Manifest.permission.ACCESS_FINE_LOCATION
    }, PERMISSION);
} else {
    manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, MainActivity.this);
}

Where PERMISSION is an integer constant. Now, we need to override the onRequestPermissions() method.

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
       if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        } else {
           Toast.makeText(this, "Can't access location without permission", Toast.LENGTH_SHORT).show();
       }
    }
}

Wiring up the functionality

Let us now use the different code snippets described in the explanation above to create our app. Open up MainActivity.java, and add the following fields to the file:

LocationManager manager;
TextView tv;
Button getLocation;
private static final int PERMISSION = 200;
  • The first field will be used for our main purpose: getting the user’s location.
  • The second and third fields are references to our widgets.
  • The fourth field is a constant that would be supplied to the requestPermissions() method, as explained above.

We also need to implement the LocationListener. Change the class description as follows:

public class MainActivity extends AppCompatActivity implements LocationListener

We will now need to implement the methods of this interface. Write the following:

@Override
public void onLocationChanged(Location location) {
    tv.setText("Latitude: " + location.getLatitude() + "\nLongitude: " + location.getLongitude() + "\nAltitude: " + location.getAltitude());

}

@Override
public void onStatusChanged(String s, int i, Bundle bundle) {

}

@Override
public void onProviderEnabled(String s) {

}

@Override
public void onProviderDisabled(String s) {

}

Add the following code in onCreate():

tv = findViewById(R.id.textview1);
getLocation = findViewById(R.id.button);
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
getLocation.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(MainActivity.this, new String[] {
                    Manifest.permission.ACCESS_FINE_LOCATION
            }, PERMISSION);
        } else {
            manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, MainActivity.this);
        }
    }
});

Finally, override the onRequestPermissionsResult() method, and write the following:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
       if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        } else {
           Toast.makeText(this, "Can't access location without permission", Toast.LENGTH_SHORT).show();
       }
    }
}

We have only asked for the ACCESS_FINE_LOCATION permission, as it automatically grants the ACCESS_COARSE_LOCATION permission as well.

Our app is ready, now let us test our app.

App Screenshots

App UI
App UI
Asking for Permission on Button Click
Asking for Permission on Button Click

 

Coordinates Displayed
Coordinates Displayed

The emulator has a default location whose coordinates are displayed. To change the location, click the 3 horizontal dots at the bottom of the emulator controls menu (located on the right side of the emulator). In the Location menu, choose any location on the map and click ‘Set Location’ (bottom right).

Changing the Location of the Emulator
Changing the Location of the Emulator

Full Code

Related courses for this will be up soon!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.