Capture Location in Android

Android allows to capture current location of the device and we can build location-aware applications. When developing location aware-application we can choose location provider. It provides periodic location reports of the device. Which provider to use relies on project requirements.

Description
GPS_PROVIDERDetermines location using satellites. It is most accurate, quickly consumes battery power, only works outdoors.
NETWORK_PROVIDERDetermines location using nearby of cell towers and WiFi access points. It uses less battery power than GPS, works indoors and outdoors.

A layout XML file contains two TextView elements which will be used to display coordinates.

app/src/main/res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/latitudeView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/longitudeView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

Application should have appropriate permissions in order to receive location updates. So we need to request the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission in the manifest file.

If we using NETWORK_PROVIDER, then we need to request the ACCESS_COARSE_LOCATION permission. If we using GPS_PROVIDER or both, then we need to request only the ACCESS_FINE_LOCATION permission, because it includes permission for both providers.

app/src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">

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

    <application>
        ...
    </application>

</manifest>

The LocationManager provides access to the system location services and notifies listener when the device location was changed.

The LocationListener receives events from the LocationManager when the location was changed.

The method ContextCompat.checkSelfPermission() allows to check if the user has already granted required permission. If permisison not granted, then the method ActivityCompat.requestPermissions() can be called to request permission.

To inform that we want to receive location updates we need to call the method requestLocationUpdates().

app/src/main/java/com/example/app/MainActivity.kt

package com.example.app

import android.Manifest
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity()
{
    private val permission: String = Manifest.permission.ACCESS_FINE_LOCATION
    private val requestCode: Int = 1
    private val minTimeBetweenUpdates: Long = 1       // 1 millisecond
    private val minDistanceBetweenUpdates: Float = 1f // 1 meter

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

        val locManager = getSystemService(LOCATION_SERVICE) as LocationManager

        val locListener = object: LocationListener {
            override fun onLocationChanged(location: Location) {
                latitudeView.text = location.latitude.toString()
                longitudeView.text = location.longitude.toString()
            }

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

        if (ContextCompat.checkSelfPermission(this, permission)
            != PackageManager.PERMISSION_GRANTED
        ) {
            ActivityCompat.requestPermissions(this, arrayOf(permission), requestCode)
        } else {
            locManager.requestLocationUpdates(
                LocationManager.GPS_PROVIDER,
                minTimeBetweenUpdates,
                minDistanceBetweenUpdates,
                locListener
            )
        }
    }
}

Leave a Comment

Your email address will not be published. Required fields are marked *