Android SharedPreferences Tutorial and Example

Using FusedLocationProviderClient for Location Updates in Android

FusedLocationProviderClient sits at the heart of modern Android location services, blending signals from GPS satellites, Wi-Fi access points, and cellular towers into a single, battery-friendly stream of coordinates. Rather than juggling three separate subsystems, developers call one API and let the Google Play services location stack decide which sensors to wake up and when. The result is faster fixes in dense cities and longer battery life when the device is sitting still.

For Australian developers, the fused provider is particularly attractive because it handles the country's mixed coverage profile gracefully. A user moving from a high-rise in Sydney's CBD to a beach in Bondi, then onto a regional train towards Newcastle, will see the API switch seamlessly between GPS dominance and network-based fallbacks. Older APIs like android.location.LocationManager require manual sensor orchestration, which is error-prone and rarely justified given how well the fused client performs.

This walkthrough covers the full lifecycle of a location session: declaring the right permissions, building a LocationRequest, attaching a callback, handling background restrictions introduced in Android 10, and finally tearing everything down to preserve battery. Along the way, we'll touch on local realities such as carrier coverage differences between Telstra and Optus, and the disclosure expectations under the Privacy Act 1988 that shape how you ask users for location access.

Granting Location Permissions the Right Way

Before any code can request a coordinate, your manifest must declare what the app is allowed to ask for. ACCESS_FINE_LOCATION grants access to precise GPS data, while ACCESS_COARSE_LOCATION only provides network-derived approximations accurate to a few hundred metres. Most production apps in Australia request both, then downgrade to coarse only if the user declines fine access. If you plan to keep tracking the user while the app is in the background, you also need ACCESS_BACKGROUND_LOCATION on Android 10 and above.

Runtime permission requests are mandatory from API level 23 onward, and the recommended pattern is to use ActivityResultContracts.RequestMultiplePermissions. Trigger the dialog from a user-initiated action, such as tapping a "Find nearby cafes" button, rather than on first launch. Australians are increasingly aware of location tracking following high-profile data breaches, and showing a clear value proposition reduces the chance of a flat rejection. Always handle the "Don't ask again" case gracefully by directing users to system settings.

The Privacy Act 1988 and the Australian Privacy Principles require that personal information, including precise location, be collected with consent and used only for the stated purpose. If your app logs coordinates for analytics, disclose this in your privacy policy and consider truncating the data to the nearest suburb before storage.

Configuring the Location Request

A LocationRequest describes what your app actually needs from the location stack. The modern builder syntax reads almost like English: LocationRequest.Builder(Priority.PRIORITY_BALANCED_POWER_ACCURACY, 5000L).setMinUpdateIntervalMillis(2000L).setWaitForAccurateLocation(false).build(). The interval sets the desired cadence, while the fastest interval caps how often the system can deliver updates even if other apps are requesting more frequent fixes.

Choosing the right priority is a trade-off between accuracy and battery. The table below summarises the four built-in options and when each one shines in real Australian conditions.

Priority Typical accuracy Power use Best for
PRIORITY_HIGH_ACCURACY 5–10 m High Turn-by-turn navigation, fitness tracking
PRIORITY_BALANCED_POWER_ACCURACY 30–100 m Moderate Local weather, nearby store finders
PRIORITY_LOW_POWER 100–500 m Low News localisation, coarse audience segmentation
PRIORITY_PASSIVE Varies Minimal Listening to other apps' updates

For a ride-share app operating around Melbourne's tram network, balanced accuracy is often sufficient. For a hiking companion helping users navigate the Larapinta Trail, high accuracy is non-negotiable. The setSmallestDisplacement method adds another lever, telling the system to skip updates that haven't moved the user by at least a specified number of metres, which is invaluable for stationary scenarios like waiting at a café in Surry Hills.

Receiving Updates Through a LocationCallback

With a configured request, the next step is wiring up a LocationCallback. Pass an instance to requestLocationUpdates along with a Looper, typically Looper.getMainLooper() for UI-bound updates or a background HandlerThread for batch processing. The override onLocationResult(LocationResult result) delivers a list of Location objects, each carrying latitude, longitude, accuracy, bearing, speed, and a timestamp from the system clock.

Always null-check the result parameter and iterate defensively through the location list. A single callback can contain multiple fixes if the system buffered them while the device was asleep. For a quick one-shot coordinate, such as centring a map on the user's current suburb in Brisbane, call getCurrentLocation instead, which returns a Task that resolves to the best available fix or null if none is available within the timeout.

It's worth listening for the availability callback as well. Override onLocationAvailability to detect when the system has temporarily lost access to all location sources, which happens more often than developers expect inside concrete-and-steel car parks or during prolonged black spots on regional highways. Show a friendly message rather than spinning indefinitely, and consider degrading features gracefully until the next fix arrives.

Working with Background Updates

Android 10 introduced a dedicated runtime permission for background access, and Android 12 further tightened the rules by hiding the option behind a separate settings screen. If your use case genuinely requires tracking the user while the app is not visible, you must justify it to Google Play reviewers and request the background permission in a separate flow after the foreground permission is granted. For most apps, a foreground service with a persistent notification is the only acceptable path.

A common pattern is to combine location updates with a foreground service that draws a notification explaining why tracking is active. This satisfies user expectations and keeps the process alive during long journeys, such as a road trip from Adelaide to Alice Springs. When you only need location while the app is in the foreground, skip the background permission entirely; the system grants foreground updates as part of the fine or coarse runtime grant.

For the UI side of presenting location-aware content, you might pair the callback with swipeable screens. The tutorial on Using ViewPager2 with TabLayout for swipeable tabs walks through building a tabbed interface that can hold map fragments, place lists, and route summaries side by side. It's a natural fit when each tab needs its own location-driven content.

Stopping Updates and Optimising Battery

The single most common mistake in production apps is forgetting to call removeLocationUpdates when the activity stops or the feature is no longer needed. Leaving a request active drains the battery within hours and can trigger user complaints that lead to uninstalls. Tie the cleanup to the appropriate lifecycle method, onStop for activity-scoped requests and onCleared in a ViewModel, so the work stops the moment the user leaves the screen.

Beyond explicit cleanup, several patterns reduce background drain. Coalesce updates by setting a generous fastest interval, drop accuracy when the screen is off, and prefer the getCurrentLocation one-shot API for features that only need a single coordinate. If your app offers a "locate me" button rather than continuous tracking, the one-shot method is dramatically more efficient. Battery telemetry in API 31 and above can help you measure the impact directly.

Wi-Fi positioning, which the fused provider leans on heavily indoors, depends on the quality and configuration of nearby access points. Developers testing location flows inside an office or warehouse should ensure their network hardware is set up correctly; guides like Edimax router setup walk through positioning routers for stable coverage, which in turn yields more reliable indoor fixes. Combined with the runtime practices above, this kind of attention to detail is what separates a polished location experience from one that frustrates users.