How to get the Current Location (Latitude and Longitude) in Android

Kapil Sachan
5 min readDec 26, 2020
Get Current Location (Latitude and Longitude) in Android

This tutorial helps you to learn How to get the current latitude and longitude in the Android.

As a developer when you work on locations, maps, or any new component of Android then you always have some doubts about selecting the best and most efficient approach for your requirement. But don’t worry, I will try to clear all your doubts with my articles on all doubtful topics of Android in my coming Articles.

So let’s focus on our today’s topic: How to get the Current Location (Latitude and Longitude) in Android.

There are two ways to get the current location of any Android device:

→ Android’s Location Manager API

→ Fused Location Provider: Google Play Services Location APIs

Question: Which one is efficient and why?

Answer: Fused Location Provider because it optimizes the device’s use of battery power.

Before moving any of the above methods we will have to take location permission.

Important: Taking Location Permission

Step 1: Define uses permissions for location access in the manifest.

<!-- To request foreground location access, declare one of these permissions. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Required only when requesting background location access on Android 10 (API level 29) -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />

In order to receive location updates from NETWORK_PROVIDER or GPS_PROVIDER, you must request the user’s permission by declaring either the ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission, respectively, in your Android manifest file. Without these permissions, your application will fail at runtime when requesting location updates.

If you are using both NETWORK_PROVIDER and GPS_PROVIDER, then you need to request only the ACCESS_FINE_LOCATION permission, because it includes permission for both providers. Permission for ACCESS_COARSE_LOCATION allows access only to NETWORK_PROVIDER.

Step 2: Define uses permission for internet access because we are going to use Internet Provider.

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

Step 3: Write a function for checking whether location permission is granted or not. If permission is not granted then ask for the permissions in run time.

private fun isLocationPermissionGranted(): Boolean {
return if (ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
this,
android.Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(
android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION
),
requestcode
)
false
} else {
true
}
}

Now after handling location permissions, we are going learn how can we get a location in android.

First Method: By Android’s Location Manager API

Note: We assume that user has granted Location Permission. If not then ask first.

Step 1: Create an instance of LocationManager in the context of LOCATION_SERVICE.

private var currentLocation: Location? = null
lateinit var locationManager: LocationManager
locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager

Step 2: Check if the GPS and Network are available or not and if both are available then we use one with greater accuracy.

val hasGps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)//------------------------------------------------------//val hasNetwork = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)

Step 3: Create an instance of LocationListener (package: android.location) for both(GPS and Network).

val gpsLocationListener: LocationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
locationByGps= location
}

override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
override fun onProviderEnabled(provider: String) {}
override fun onProviderDisabled(provider: String) {}
}
//------------------------------------------------------//val networkLocationListener: LocationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
locationByNetwork= location
}

override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
override fun onProviderEnabled(provider: String) {}
override fun onProviderDisabled(provider: String) {}
}

Step 4: If any of the GPS or Network providers is enabled then we will request a current location update from the LocationManager with LocationListener.

if (hasGps) {
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
5000,
0F,
gpsLocationListener
)
}
//------------------------------------------------------//if (hasNetwork) {
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
5000,
0F,
networkLocationListener
)
}

Step 5: Now we check which provider has given us the more accurate location and then we will use that location as per our requirement.

val lastKnownLocationByGps =
locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
lastKnownLocationByGps?.let {
locationByGps
= lastKnownLocationByGps
}
//------------------------------------------------------//val lastKnownLocationByNetwork =
locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
lastKnownLocationByNetwork?.let {
locationByNetwork
= lastKnownLocationByNetwork
}
//------------------------------------------------------//if (locationByGps != null && locationByNetwork != null) {
if (locationByGps.accuracy > locationByNetwork!!.accuracy) {
currentLocation = locationByGps
latitude = currentLocation.latitude
longitude = currentLocation.longitude
//use latitude and longitude as per your need
} else {
currentLocation = locationByNetwork
latitude
= currentLocation.latitude
longitude = currentLocation.longitude
//use latitude and longitude as per your need
}
}

Finally, I am providing a gist of all steps.

Now after learning how can we get a location in android by Location Manager API, we are moving to the second method Fused Location Provider (Google Play Services Location APIs).

Second Method: By Fused Location Provider

Note: We assume that user has granted Location Permission. If not then ask first.

Fused Location Provider is the Google Play services location APIs. It provides a simple API for getting locations with high, medium, and low accuracy. It also optimizes the device’s use of battery power. So we should prefer this method.

Step 1: Declare variables of FusedLocationProviderClient, LocationRequest, LocationCallback, and Location.

/* FusedLocationProviderClient - Main class for receiving location            updates.*/
private lateinit var fusedLocationProviderClient: FusedLocationProviderClient

/* LocationRequest - Requirements for the location updates, i.e., how often you should receive updates, the priority, etc.*/
private lateinit var locationRequest: LocationRequest

/* LocationCallback - Called when FusedLocationProviderClient has a new Location.*/
private lateinit var locationCallback: LocationCallback
/* This will store current location info. */
private var currentLocation: Location? = null

Step 2: Initialize fusedLocationProviderClient.

fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)

Step 3: Initialize locationRequest.

locationRequest = LocationRequest().apply {
/* Sets the desired interval for active location updates. This interval is inexact.*/
interval = TimeUnit.SECONDS.toMillis(60)

/* Sets the fastest rate for active location updates. This interval is exact, and your application will never receive updates more frequently than this value.*/
fastestInterval = TimeUnit.SECONDS.toMillis(30)

/* Sets the maximum time when batched location updates are delivered. Updates may be delivered sooner than this interval.*/
maxWaitTime = TimeUnit.MINUTES.toMillis(2)

priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}

Step 4: Initialize locationCallback.

locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult?) {
super.onLocationResult(locationResult)
locationResult?.lastLocation?.let {
currentLocation = locationByGps
latitude = currentLocation.latitude
longitude = currentLocation.longitude

//use latitude and longitude as per your need
} ?: {
Log.d(TAG, "Location information isn't available.")

}
}
}

Step 5: Now that you initialized everything, you need to let the FusedLocationProviderClient know that you want to receive updates. So Subscribe to location changes.

fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper())

Step 6: When the app no longer needs access to location information, it’s important to unsubscribe from location updates.

val removeTask = fusedLocationProviderClient.removeLocationUpdates(locationCallback)
removeTask.addOnCompleteListener { task ->
if (task.isSuccessful) {
Log.d(TAG, "Location Callback removed.")
} else {
Log.d(TAG, "Failed to remove Location Callback.")
}
}

Cheers! You have done this :)

Thank you for reading 😊.

Stay safe and Keep Coding ✌.

Now you are able to get the current latitude and longitude on your android device. If you have any issue regarding the same, please put it in the comment section.

--

--