Get location android Kotlin

I know it's late, but now Google has made it simpler to use. In the developer site, it says that you need to create a Client:

private lateinit var fusedLocationClient: FusedLocationProviderClient

Then onCreate get the provider:

override fun onCreate(savedInstanceState: Bundle?) {
    // ...
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
}

And finally, to get your last location just call:

//Don't forget to ask for permissions for ACCESS_COARSE_LOCATION 
//and ACCESS_FINE_LOCATION
@SuppressLint("MissingPermission")
private fun obtieneLocalizacion(){
    fusedLocationClient.lastLocation
            .addOnSuccessListener { location: Location? ->
                latitude =  location?.latitude
                longitude = location?.longitude
            }
}

*Tested with this implementation for location (Setup in your app gradle file)

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

For more info, check this link:

Obtain last location


In 2019 Best Offical Solution in Kotlin

Google API Client/FusedLocationApi are deprecated and Location Manager is not useful at all. So Google prefer Fused Location Provider Using the Google Play services location APIs "FusedLocationProviderClient" is used to get location and its better way for battery saving and accuracy

Here is sample code in kotlin to get the last known location /one-time location( equivalent to the current location)

 // declare a global variable of FusedLocationProviderClient
    private lateinit var fusedLocationClient: FusedLocationProviderClient

// in onCreate() initialize FusedLocationProviderClient
    fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)

 /**
     * call this method for receive location
     * get location and give callback when successfully retrieve
     * function itself check location permission before access related methods
     *
     */
    fun getLastKnownLocation() {
            fusedLocationClient.lastLocation
                .addOnSuccessListener { location->
                    if (location != null) {
                       // use your location object
                        // get latitude , longitude and other info from this
                    }

                }

    }

If your app can continuously track the location then you have to receive Receive location updates

Check the sample for that in kotlin

// declare a global variable FusedLocationProviderClient
        private lateinit var fusedLocationClient: FusedLocationProviderClient

    // in onCreate() initialize FusedLocationProviderClient
        fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)


      // globally declare LocationRequest
        private lateinit var locationRequest: LocationRequest

        // globally declare LocationCallback    
        private lateinit var locationCallback: LocationCallback


        /**
         * call this method in onCreate
         * onLocationResult call when location is changed 
         */
        private fun getLocationUpdates()
        {

                fusedLocationClient = LocationServices.getFusedLocationProviderClient(context!!)
                locationRequest = LocationRequest()
                locationRequest.interval = 50000
                locationRequest.fastestInterval = 50000
                locationRequest.smallestDisplacement = 170f // 170 m = 0.1 mile
                locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY //set according to your app function
                locationCallback = object : LocationCallback() {
                    override fun onLocationResult(locationResult: LocationResult?) {
                        locationResult ?: return

                        if (locationResult.locations.isNotEmpty()) {
                            // get latest location 
                            val location =
                                locationResult.lastLocation
                            // use your location object
                            // get latitude , longitude and other info from this
                        }


                    }
                }
        }

        //start location updates
        private fun startLocationUpdates() {
            fusedLocationClient.requestLocationUpdates(
                locationRequest,
                locationCallback,
                null /* Looper */
            )
        }

        // stop location updates
        private fun stopLocationUpdates() {
            fusedLocationClient.removeLocationUpdates(locationCallback)
        }

        // stop receiving location update when activity not visible/foreground
        override fun onPause() {
            super.onPause()
            stopLocationUpdates()
        }

        // start receiving location update when activity  visible/foreground
        override fun onResume() {
            super.onResume()
            startLocationUpdates()
        }

Make sure you take care about Mainfaist permission and runtime permission for location

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

and for Gradle add this

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

For more details follow these official documents

https://developer.android.com/training/location/retrieve-current

https://developer.android.com/training/location/receive-location-updates

https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient


When GetUserLocation returns, locationManager goes out of scope and presumably is destroyed, preventing onLocationChanged from being called and providing updates.

Also, you've defined mylocation inside of GetUserLocation so it also goes out of scope and further kills any chance or your getting an update.

You have not shown where and how the outer mylocation is declared (outside of GetUserLocation), but how ever it is declared, it is being shadowed by the one inside of GetUserLocation. So you aren't getting much.

Here is an example of how you might do it. (The variable thetext is defined within the layout xml and accessed with Kotlin extensions.)

// in the android manifest
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
// allow these through Appliation Manager if necessary

// inside a basic activity
private var locationManager : LocationManager? = null

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

    // Create persistent LocationManager reference
    locationManager = getSystemService(LOCATION_SERVICE) as LocationManager?

    fab.setOnClickListener { view ->
        try {
            // Request location updates
            locationManager?.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0L, 0f, locationListener)
        } catch(ex: SecurityException) {
            Log.d("myTag", "Security Exception, no location available")
        }
    }
}

//define the listener
private val locationListener: LocationListener = object : LocationListener {
    override fun onLocationChanged(location: Location) {
        thetext.text = ("" + location.longitude + ":" + location.latitude)
    }
    override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
    override fun onProviderEnabled(provider: String) {}
    override fun onProviderDisabled(provider: String) {}
}