When building Android apps that use GPS or location services, many developers encounter the issue of Kotlin location not updating in real devices. This problem usually happens when testing location-based applications such as maps, delivery tracking, or fitness apps. Although the emulator often works perfectly, on physical devices the location updates either stop working or never trigger.

In this article, we will explore common causes, step-by-step fixes, and provide a complete Kotlin code example to ensure that your Android app can properly request and update real-time location data.
Why Location Is Not Updating on Real Devices
Before diving into solutions, it’s important to understand why this issue happens. Here are some common reasons:
- Missing permissions: The app does not have the required runtime permissions (
ACCESS_FINE_LOCATION
orACCESS_COARSE_LOCATION
). - Location services disabled: The user has disabled GPS/location services on the device.
- Using old API: The deprecated
LocationManager
API might not give consistent results compared toFusedLocationProviderClient
. - Battery optimization: Some devices block location updates to save battery.
- Incorrect update interval: Setting too high or too low intervals may cause the app to fail in receiving updates.
Step-by-Step Solution
- Add Required Permissions: Update your
AndroidManifest.xml
with the following:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
- Request Runtime Permissions: Starting from Android 6.0 (Marshmallow), permissions must be requested at runtime. You should prompt the user to allow access before using location services.
private fun checkLocationPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION), 1001 ) } }
- Use FusedLocationProviderClient: This is the recommended API by Google for efficient and accurate location updates.
class MainActivity : AppCompatActivity() { private lateinit var fusedLocationClient: FusedLocationProviderClient private lateinit var locationCallback: LocationCallback override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) fusedLocationClient = LocationServices.getFusedLocationProviderClient(this) checkLocationPermission() startLocationUpdates() } private fun startLocationUpdates() { val locationRequest = LocationRequest.Builder( Priority.PRIORITY_HIGH_ACCURACY, 5000L ).setMinUpdateIntervalMillis(2000L).build() locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult) { super.onLocationResult(locationResult) for (location in locationResult.locations) { Log.d("LOCATION_UPDATE", "Lat: ${location.latitude}, Lng: ${location.longitude}") } } } if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { fusedLocationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper()) } } }
Common Mistakes Developers Make
- Not requesting background location: If your app needs to track location even when the app is closed or minimized, you need
ACCESS_BACKGROUND_LOCATION
permission. - Incorrect Looper usage: Always pass
Looper.getMainLooper()
to avoid background thread issues. - Not checking device settings: Always prompt the user to enable location if disabled.
How to Prompt Users to Enable Location
private fun checkLocationSettings() { val locationRequest = LocationRequest.Builder( Priority.PRIORITY_HIGH_ACCURACY, 5000L ).build() val builder = LocationSettingsRequest.Builder() .addLocationRequest(locationRequest) val client = LocationServices.getSettingsClient(this) val task = client.checkLocationSettings(builder.build()) task.addOnFailureListener { exception -> if (exception is ResolvableApiException) { try { exception.startResolutionForResult(this, 1002) } catch (sendEx: IntentSender.SendIntentException) { sendEx.printStackTrace() } } } }
Comparison: LocationManager vs FusedLocationProviderClient
Feature | LocationManager | FusedLocationProviderClient |
---|---|---|
Accuracy | Depends on provider (GPS/Network) | Automatically chooses best provider |
Battery Efficiency | Consumes more power | Optimized for battery usage |
Ease of Use | Requires manual handling | Simple and modern API |
Recommended | No | Yes |
Best Practices to Ensure Location Updates
- Always check and request runtime permissions properly.
- Use
FusedLocationProviderClient
instead ofLocationManager
. - Prompt users to enable GPS if disabled.
- Adjust update interval according to your app needs (not too frequent).
- Test on different devices, as some brands (like Xiaomi or Oppo) have aggressive battery optimizations.
Conclusion
Handling Kotlin location not updating in real devices requires careful setup of permissions, APIs, and device settings. By following the steps above and using FusedLocationProviderClient
, your app will be able to consistently receive accurate location updates in real devices.
If you are developing apps that rely heavily on location, always test on multiple physical devices rather than just the emulator. This ensures that your code works under real-world scenarios.
For further reading, you can check the official documentation on Request Location Updates provided by Google.