How do I get the current Latitude and Longitude of the mobile device in android using location tools?
This is an old question and most answers are outdated. This is how I do it my apps now:
This class help to track the device location and return list of Address of device using Geocoding. Put it in some util class
import android.Manifest
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.*
import android.os.Bundle
import android.provider.Settings
import android.util.Log
import androidx.core.app.ActivityCompat
import com.bmw.weatherapp.R
import kotlinx.coroutines.*
import java.io.IOException
import java.lang.ref.WeakReference
import java.util.*
import kotlin.coroutines.CoroutineContext
/**
* Use GPS or Network Provider to get Device Location
*/
class DeviceLocationTracker(context: Context, deviceLocationListener: DeviceLocationListener) : LocationListener, CoroutineScope {
private var deviceLocation: Location? = null
private val context: WeakReference
private var locationManager: LocationManager? = null
private var deviceLocationListener: DeviceLocationListener
private val job = Job()
override val coroutineContext: CoroutineContext
get() = job + Dispatchers.Main
init {
this.context = WeakReference(context)
this.deviceLocationListener = deviceLocationListener
initializeLocationProviders()
}
private fun initializeLocationProviders() {
//Init Location Manger if not already initialized
if (null == locationManager) {
locationManager = context.get()
?.getSystemService(Context.LOCATION_SERVICE) as LocationManager
}
locationManager?.apply {
// flag for GPS status
val isGPSEnabled = isProviderEnabled(LocationManager.GPS_PROVIDER)
// flag for network status
val isNetworkEnabled = isProviderEnabled(LocationManager.PASSIVE_PROVIDER)
//If we have permission
if (ActivityCompat.checkSelfPermission(context.get()!!, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(context.get()!!, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//First Try GPS
if (isGPSEnabled) {
requestLocationUpdates(
LocationManager.GPS_PROVIDER,
UPDATE_FREQUENCY_TIME,
UPDATE_FREQUENCY_DISTANCE.toFloat(), this@DeviceLocationTracker)
deviceLocation = locationManager!!.getLastKnownLocation(LocationManager.GPS_PROVIDER)
} else {
// Show alert to open GPS
context.get()?.apply {
AlertDialog.Builder(this)
.setTitle(getString(R.string.title_enable_gps))
.setMessage(getString(R.string.desc_enable_gps))
.setPositiveButton(getString(R.string.btn_settings)
) { dialog, which ->
val intent = Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS)
startActivity(intent)
}.setNegativeButton(getString(R.string.btn_cancel))
{ dialog, which -> dialog.cancel() }.show()
}
}
//If failed try using NetworkManger
if(null==deviceLocation && isNetworkEnabled) {
requestLocationUpdates(
LocationManager.PASSIVE_PROVIDER,
0, 0f,
this@DeviceLocationTracker)
deviceLocation = locationManager!!.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
}
}
}
}
/**
* Stop using GPS listener
* Must call this function to stop using GPS
*/
fun stopUpdate() {
if (locationManager != null) {
locationManager!!.removeUpdates(this@DeviceLocationTracker)
}
}
override fun onLocationChanged(newDeviceLocation: Location) {
deviceLocation = newDeviceLocation
launch(Dispatchers.Main) {
withContext(Dispatchers.IO) {
var addressList: List? = null
try {
addressList = Geocoder(context.get(),
Locale.ENGLISH).getFromLocation(
newDeviceLocation.latitude,
newDeviceLocation.longitude,
1)
deviceLocationListener.onDeviceLocationChanged(addressList)
Log.i(TAG, "Fetch address list"+addressList)
} catch (e: IOException) {
Log.e(TAG, "Failed Fetched Address List")
}
}
}
}
override fun onProviderDisabled(provider: String) {}
override fun onProviderEnabled(provider: String) {}
override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
interface DeviceLocationListener {
fun onDeviceLocationChanged(results: List?)
}
companion object {
// The minimum distance to change Updates in meters
private const val UPDATE_FREQUENCY_DISTANCE: Long = 1 // 10 meters
// The minimum time between updates in milliseconds
private const val UPDATE_FREQUENCY_TIME: Long = 1 // 1 minute
private val TAG = DeviceLocationTracker::class.java.simpleName
}
}
Add Strings for alert dialog in case GPS is disabled
Enable GPS
GPS is not enabled. Do you want to go to settings menu?
Open Settings
Cancel
Add these permission in your Android manifest and request them in app start
Usage
Implement DeviceLocationListener in your Activity/Fragment class
class MainActivity : AppCompatActivity, DeviceLocationTracker.DeviceLocationListener {
Override onDeviceLocationChanged callback. You will get current location in onDeviceLocationChanged
override fun onDeviceLocationChanged(results: List?) {
val currntLocation = results?.get(0);
currntLocation?.apply {
currentlLat = latitude
currentLng = longitude
Country = countryCode
cityName = getAddressLine(0)
}
}
To start tracking create a DeviceLocationTracker object in onCreate method of your. Pass the Activity as Context & this as DeviceLocationListener.
private lateinit var deviceLocationTracker: DeviceLocationTracker
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
...
deviceLocationTracker= DeviceLocationTracker(this, this)
That is it, now you will start to get location update in onDeviceLocationChanged.