Categories
Android

How to get GPS coordinates

Fetching the longitude and latitude on Android devices isn't hard. In this tutorial we'll get the GPS location of our Android phone, tablet or emulator. Let's begin!

Select Basic Activity.
Select Kotlin.

This tutorial uses Kotlin, the preferred language of Google and myself. Open AndroidManifest.xml (inside the app -> manifest folder), then add the required permission for getting the location. This is required.

Location permissions in Android Studio.

The Manifest should now look like the following.

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

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

That's it for permissions. Now, let's add a Gradle import. We need this for location services to function.

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

The entire build.gradle (Module: app) file should look like this:

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 29
    defaultConfig {
        applicationId "com.example.firstgpslocation"
        minSdkVersion 21
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.material:material:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

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

Let's move on to the Kotlin code we need to write. Because we selected Basic Activity when creating this project, Android Studio by default adds unnecessary code to MainActivity.kt. Before editing, it looks like this:

package com.example.firstgpslocation

import android.os.Bundle
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity
import android.view.Menu
import android.view.MenuItem

import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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

        fab.setOnClickListener { view ->
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                .setAction("Action", null).show()
        }
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // Inflate the menu; this adds items to the action bar if it is present.
        menuInflater.inflate(R.menu.menu_main, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        return when (item.itemId) {
            R.id.action_settings -> true
            else -> super.onOptionsItemSelected(item)
        }
    }
}

But let's get rid of most of it, so it looks like this:

package com.example.firstgpslocation

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivity : AppCompatActivity() {

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

Add the Location Services code inside onCreate.

        LocationServices.getFusedLocationProviderClient(this).lastLocation
            .addOnSuccessListener { location: Location? ->
                
            }

If you get an error on Location, click on Location, then press Alt+Enter (on Windows/Linux) or Option+Enter (Mac).

Click, then press Alt+Enter.

For debugging, we can also add an addOnFailureListener.

            .addOnFailureListener {
                d("daniel", "error: ${it.localizedMessage}")
            }

Run the app by pressing the green play (or restart) button. Then open Logcat and search for daniel (or whatever your d() log statement says).

Logcat.

You may see this error:

com.example.firstgpslocation D/daniel: error: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any location operations.

If you see this, go to your app's settings screen on the Android device, then enable the Location permission. If you're using an Emulator and not a physical device you may need to set a location as well.

Run the app again and notice the longitude/latitude in Logcat:

com.example.firstgpslocation D/daniel: longitude: -95.3698017 29.7604267

By Daniel Malone

Daniel Malone is an Android Developer in Austin, Texas. He enjoys writing code, whether it be HTML, CSS, JavaScript, PHP, Java, XML or Kotlin. Daniel started writing code at age 12. By the time he was 15, he had a technology news website that received about 200 visitors a day. His first computer was a Dell Dimension 3000, with an 80GB hard drive, 512MB RAM and a broken DVD drive.