Skip to content

Android Location Updates — Complete Guide

DodaTech Updated 2026-06-24 3 min read

In this tutorial, you'll learn about Android Location Updates. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

The Problem

Your location listener drains the battery in 2 hours, or location updates stop when the app goes to background.

Wrong Approach ❌

// Continuous location updates with very short interval
val locationRequest = LocationRequest.create().apply {
    priority = LocationRequest.PRIORITY_HIGH_ACCURACY
    interval = 1000 // 1 second — extreme battery drain!
    smallestDisplacement = 0f // Every movement triggers update
}

Output: Battery drains rapidly. GPS keeps radio active continuously.

Right Approach ✅

class LocationUpdateManager(private val context: Context) {
    private val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context)
    private val locationCallback = createLocationCallback()
    private var isUpdating = false

    // Battery-efficient location updates
    fun startEfficientUpdates(onLocation: (Location) -> Unit) {
        if (isUpdating) return
        isUpdating = true

        val locationRequest = LocationRequest.create().apply {
            priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY // ~100m is fine
            interval = 60000 // 60 seconds between updates
            fastestInterval = 30000 // At most 30 seconds
            smallestDisplacement = 100f // Only update if moved 100m
            maxWaitTime = 120000 // Batch updates within 2 minutes
        }

        val callback = object : LocationCallback() {
            override fun onLocationResult(result: LocationResult) {
                result.lastLocation?.let { onLocation(it) }
            }
        }

        fusedLocationClient.requestLocationUpdates(
            locationRequest,
            callback,
            Looper.getMainLooper()
        ).addOnFailureListener { isUpdating = false }
    }

    // Background location with Foreground Service
    fun startBackgroundUpdates(notification: Notification) {
        val serviceIntent = Intent(context, LocationService::class.java)
        ContextCompat.startForegroundService(context, serviceIntent)

        val locationRequest = LocationRequest.create().apply {
            priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
            interval = 120000 // 2 minutes in background
            fastestInterval = 60000
            smallestDisplacement = 200f
        }

        // Use PendingIntent for background updates
        val pendingIntent = PendingIntent.getService(
            context,
            0,
            serviceIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )

        fusedLocationClient.requestLocationUpdates(locationRequest, pendingIntent)
    }

    fun stopUpdates() {
        if (!isUpdating) return
        isUpdating = false
        fusedLocationClient.removeLocationUpdates(locationCallback)
    }

    // For Android 12+ background location
    fun checkBackgroundLocationPermission(): Boolean {
        return ActivityCompat.checkSelfPermission(
            context,
            Manifest.permission.ACCESS_BACKGROUND_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
    }

    private fun createLocationCallback(): LocationCallback {
        return object : LocationCallback() {
            override fun onLocationResult(result: LocationResult) {
                // Handle location
            }
        }
    }
}

// Location Service for background updates
class LocationService : Service() {
    override fun onBind(intent: Intent?) = null
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        startForeground(NOTIFICATION_ID, createNotification())
        return START_STICKY
    }
}

Output: Battery-efficient location updates with appropriate intervals.

Prevention

  • Use longer intervals (30-120 seconds) for most use cases.
  • Use smallestDisplacement to filter insignificant movements.
  • Use PRIORITY_BALANCED_POWER_ACCURACY when GPS is unnecessary.
  • Use maxWaitTime to batch location updates.
  • For background, use a Foreground Service with appropriate interval.

Common Mistakes with location update

  1. Forgetting deriving (Show, Eq) on custom data types needed for debugging
  2. Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
  3. Using head and tail instead of pattern matching, causing runtime errors on empty lists

These mistakes appear frequently in real-world Android code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.

Practice Exercise

Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.

This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.

FAQ

### How do I request background location on Android 12+?

Request ACCESS_FINE_LOCATION (foreground), then separately request ACCESS_BACKGROUND_LOCATION. The dialog must explicitly ask for "all the time" access.

### What is the maxWaitTime parameter?

It tells FusedLocationProvider to wait up to maxWaitTime before delivering batched locations. This saves battery by allowing the GPS to sleep between updates.

### Can I get location updates when the app is killed?

No. Location updates via FusedLocationProvider stop when the app Process is killed. Use a Foreground Service to keep the Process alive, or use Geofencing for region-based triggers.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro