How to Get the Current Location Through the Android Application in Kotlin and Then Save the Longitude and Latitude in Firebase Firestore
This tutorial helps you learn How to get the current latitude and longitude in the Android application and then saving them in Firebase Firestore. As a developer if you know how to get the location of any android device, you will surely make some great things.
There are two ways to get the current location of any Android device:
→ Android’s Location Manager API
→ Fused Location Provider
So we will take a look at both. Let’s start with the first one →
Android’s Location Manager API
Before diving into the location manager and its listener firstly we need to understand that what are the provider’s available in our android device for location. There are two provider’s available in any device:
- GPS Provider
- Network Provider
Both of them have their unique advantages, but we have to use both to get precise location coordinates. Because in some cases like in-door situations Network works and in other GPS works. The network gives the location based on the nearest mobile towers while GPS gives us the exact location.
First of all, before implementing any method we have to take user permission:
Location Permission
To protect user privacy, apps that use location services must request location permissions. Therefore we have to set the two permissions in the Android Manifest file before starting anything.
<!-- To request foreground location access, declare one of these permissions. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Required only when requesting background location access on Android 10 (API level 29). -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
We may also ask for permission for Internet access as we are using the Network provider and also saving the coordinates in Firestore
<uses-permission android:name="android.permission.INTERNET"/>
We can check that if permissions are granted or not. If not granted then we can request permission in realtime.
if(ActivityCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,android.Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this,arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION)
,requestcode
}
<!--Here above we checks first that if permission is not granted through ActivityCompat and then asks for permission in realtime by requestpermission which takes three arguement - Context, permission , RequestCode. -->
Location Manager Instance
Now that we have checked for the permissions, it’s time for getting location by creating the location manager instance in the context of Location service
lateinit var locationManager: LocationManager
<!-- lateinitialize a variable locationManager -->locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
Now we will check that if the GPS is on or not and we also check for network and if both then we use one with greater accuracy.
If any of the GPS or Network provider is enabled then we will request a current location update from the location manager like this :
locationmanager.requestLocationUpdates(LocationManager.GPS_PROVIDER,minTimeinMS,minDistanceinM,locationlistener)
In the above code snippet, you will see the location listener and the other two arguments for time and distance. We will receive location updates from LocationListener on change of location. LocationListener will be notified when the distance interval specified or the number of seconds changes.
And LocationListner has some callbacks methods to provide location-based on some behaviors in the android device, but in kotlin, we use only one that is onLocationChanged which will update in the specified time and distance provided in locationmanager.requestlocationupdate .
override fun onLocationChanged(p0: Location) {
TODO("Not yet implemented")
}
onLocationChanged(p0: Location) — Run’s when location is changed.
override fun onProviderDisabled(provider: String) {
super.onProviderDisabled(provider)
}override fun onProviderEnabled(provider: String) {
super.onProviderEnabled(provider)
}override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {
super.onStatusChanged(provider, status, extras)
}
There are also three other callbacks like :
onProviderDisabled(provider: String) — Run’s when the provider is disabled in Device.
onProviderEnabled(provider: String) — Run’s when the provider is enabled in Device.
onStatusChanged(provider: String?, status: Int, extras: Bundle?) — This callback will never be invoked on Android Q and above, and providers can be considered as always in the LocationProvider#AVAILABLE state.
Now let’s put all in one and makes an example
Now after a user turns on his location the longitude and latitude are saving in Firebase Firestore in the given path.
Fused Location Provider
Firstly follow all the steps for asking permission and requesting in realtime from the above part and then follow next.
private lateinit var fusedLocationClient: FusedLocationProviderClientoverride fun onCreate(savedInstanceState: Bundle?) {
<!--Inside the onCreate give the lateinitialized variable an instance of Fused Location -->fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)}
- getLastLocation(GoogleApiClient): It should be used when there is no need for continuous access to the location from an application.
- requestLocationUpdates(GoogleApiClient,LocationRequest, LocationListener): It should be used when there a need for continuous location updates and the location is accessed when the application is active in the foreground.
val request = LocationRequest()
request.interval = 10000
request.fastestInterval = 5000
request.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
val permission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION
)
if (permission == PackageManager.PERMISSION_GRANTED) {
// Request location updates and when an update is
// received, store the location in Firebase
fusedLocationClient.requestLocationUpdates(request, object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
val location: Location? = locationResult.lastLocation
if (location != null) { Firebase.firestore.collection("Collection").document(doc).update("Longitude",location!!.longitude,"Latitude", location!!.latitude)
}
}
}, null)
}