iTranslated by AI
The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🗺️
FusedLocation - Getting Location Data on Android
Overview
Previously, LocationManager was used, but it seems that using Google Play Service's FusedLocation is now recommended.
Looking at the official documentation, it appears to provide location information in the most suitable way by considering which provider to use (GPS, Wi-Fi, etc.) and battery efficiency.
Request location permissions
Review the basics of requesting app permissions once more.
- Request permissions in context when the user starts interacting with a feature that requires them.
- Do not block the user. Ensure that any UI flow for explaining permissions can always be canceled.
- If the user denies or revokes a required permission, perform graceful degradation so the app remains usable.
- Do not assume system behavior.
Types of permissions
-
ACCESS_FINE_LOCATION
- Uses available location providers like GPS, Wi-Fi, and mobile data to determine the location as accurately as possible.
-
ACCESS_COARSE_LOCATION
- Uses Wi-Fi, mobile routers, or both to determine the location with an accuracy roughly equivalent to a city block.
Implementation
First, check if the permission has been granted.
private fun getLocationPermission() {
val permission = ContextCompat.checkSelfPermission(
this.applicationContext,
Manifest.permission.ACCESS_FINE_LOCATION
)
if (permission == PackageManager.PERMISSION_GRANTED) {
requestDeviceLocation()
} else if (permission == PackageManager.PERMISSION_DENIED) {
/* Returns true if the user previously denied the request.
Also returns false if they selected "Don't ask again." */
if (ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
) {
// Display UI for explaining to the user here
} else {
val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
requestDeviceLocation()
} else {
Napier.w("Permission not granted")
}
}
requestPermissionLauncher.launch(
Manifest.permission.ACCESS_FINE_LOCATION
)
}
}
}
Get the last known location
@SuppressLint("MissingPermission")
private fun requestDeviceLocation() {
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
try {
val locationResult = fusedLocationClient.lastLocation
locationResult.addOnCompleteListener { task ->
if (task.isSuccessful) {
val lastKnownLocation = task.result
if (lastKnownLocation != null) {
// Use lastKnownLocation.latitude and lastKnownLocation.longitude
}
} else {
Napier.i("Request location updates")
locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
locationResult.lastLocation.also {
// Use it.latitude and it.longitude
}
}
}
startLocationUpdates()
requestingLocationUpdates = true
}
}
} catch (e: SecurityException) {
Napier.e("SecurityException", e)
}
}
@SuppressLint("MissingPermission")
private fun startLocationUpdates() {
locationCallback?.also {
fusedLocationClient.requestLocationUpdates(
LocationRequest.create().apply {
interval = 5000
priority = LocationRequest.PRIORITY_HIGH_ACCURACY
}, it, this.mainLooper
)
}
}
override fun onResume() {
super.onResume()
if (requestingLocationUpdates) {
startLocationUpdates()
}
}
override fun onPause() {
super.onPause()
locationCallback?.also {
fusedLocationClient.removeLocationUpdates(it)
}
}
Reference URLs
- Fused Location Provider API | Google Developers
- [Kotlin] How to display the location permission dialog | Hirauchi Genta
- Getting location information using FusedLocationProviderClient - Qiita
- Request location updates | Android Developers
- Get location information with FusedLocation in Google Play Service | tkt989 🍵 Blog
Discussion