Get Current Location In Android With Kotlin: A Simple Guide

by Jhon Lennon 60 views

Hey guys! Ever needed to grab the user's current location in your Android app? It's a pretty common task, whether you're building a maps app, a fitness tracker, or even a simple weather app. In this guide, we'll walk you through how to get the current latitude and longitude in your Android app using Kotlin. We'll break it down into simple steps, so even if you're new to Android development, you'll be able to follow along. Let's dive in!

Setting Up Permissions

Before we even start writing any code, we need to make sure our app has the necessary permissions to access the device's location. Android requires you to explicitly ask the user for permission to access their location data. There are two main location permissions you might need:

  • ACCESS_FINE_LOCATION: This permission gives your app access to precise location data, using GPS, Wi-Fi, and cellular networks.
  • ACCESS_COARSE_LOCATION: This permission gives your app access to less precise location data, typically using Wi-Fi and cellular networks. It's less accurate than ACCESS_FINE_LOCATION but might be sufficient for some use cases. Keep in mind that on Android 12 and higher, the user has the option to grant precise or approximate location, regardless of what you request in the manifest. Always handle the case where the user grants only approximate location if your app really needs precise location.

To request these permissions, you'll need to add them to your AndroidManifest.xml file. Open your AndroidManifest.xml file (usually located in the app/manifests directory) and add the following lines within the <manifest> tag:

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

However, simply declaring the permissions in the manifest is not enough. You also need to request these permissions at runtime, meaning you need to ask the user to grant them when your app is running. We'll cover how to do that in the next section.

Requesting Location Permissions at Runtime

Requesting permissions at runtime is crucial because users can revoke permissions at any time. If you don't handle this properly, your app might crash or behave unexpectedly when it tries to access location data without permission. Here's how you can request location permissions in Kotlin:

First, you need to check if you already have the necessary permissions. You can use the ContextCompat.checkSelfPermission() method to do this. This method returns PackageManager.PERMISSION_GRANTED if the permission is granted, and PackageManager.PERMISSION_DENIED if it's not.

import android.Manifest
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class MainActivity : AppCompatActivity() {

    private val LOCATION_PERMISSION_REQUEST_CODE = 123 // Use any integer

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            // Permission already granted
            getLocation()
        } else {
            // Request permission
            ActivityCompat.requestPermissions(this,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                LOCATION_PERMISSION_REQUEST_CODE)
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
            if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                // Permission granted
                getLocation()
            } else {
                // Permission denied
                // Handle the case where the user denies permission
            }
        }
    }

    private fun getLocation() {
        // Get location here
    }
}

In this code snippet:

  • We define a constant LOCATION_PERMISSION_REQUEST_CODE to identify the permission request. You can use any integer value.
  • In the onCreate() method, we check if the ACCESS_FINE_LOCATION permission is already granted using ContextCompat.checkSelfPermission().
  • If the permission is granted, we call the getLocation() method (which we'll implement later).
  • If the permission is not granted, we use ActivityCompat.requestPermissions() to request the permission from the user. This method takes the activity, an array of permissions to request, and the request code as arguments.
  • The onRequestPermissionsResult() method is called when the user responds to the permission request. We check if the request code matches our LOCATION_PERMISSION_REQUEST_CODE and if the permission was granted. If it was, we call the getLocation() method. If not, we handle the case where the user denied the permission (e.g., by displaying a message explaining why the permission is needed).

Important: Always provide a clear explanation to the user about why your app needs location access. This will increase the chances that they will grant the permission.

Using Fused Location Provider

Now that we have the necessary permissions, we can finally get the user's location. The recommended way to do this on Android is to use the Fused Location Provider (FLP). The FLP is a Google Play Services API that provides a unified and efficient way to access location data. It intelligently manages the underlying location sources (GPS, Wi-Fi, cellular) to provide the best possible accuracy and battery life.

To use the FLP, you need to add the Google Play Services Location dependency to your build.gradle file (Module: app):

implementation 'com.google.android.gms:play-services-location:21.1.0'

Replace 21.1.0 with the latest version number. Make sure to sync your Gradle files after adding the dependency.

Next, you need to create a FusedLocationProviderClient instance in your activity:

import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationServices

class MainActivity : AppCompatActivity() {

    private lateinit var fusedLocationClient: FusedLocationProviderClient

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

        // ... rest of your code
    }

    // ... rest of your code
}

Now, let's implement the getLocation() method to retrieve the user's location:

import android.annotation.SuppressLint
import android.location.Location
import com.google.android.gms.tasks.Task

class MainActivity : AppCompatActivity() {

    // ... existing code

    @SuppressLint("MissingPermission")
    private fun getLocation() {
        fusedLocationClient.lastLocation
            .addOnSuccessListener {
                    location : Location? ->
                // Got last known location. In some rare situations this can be null.
                if (location != null) {
                    val latitude = location.latitude
                    val longitude = location.longitude
                    // Do something with the location
                }
            }
    }

    // ... rest of your code
}

In this code snippet:

  • We use the fusedLocationClient.lastLocation property to get the last known location of the device. This returns a Task<Location> object.
  • We use addOnSuccessListener to listen for the result of the task. If the task is successful and the location is not null, we can access the latitude and longitude from the Location object.
  • We use the `@SuppressLint(