Background Location is Restricted—Here's Why and How to Handle It
When you build a location-based feature in Flutter, you quickly discover that background location is restricted on modern mobile platforms. Users expect real-time tracking, delivery updates, and fitness metrics without draining their battery or compromising their privacy. But Android and iOS enforce strict rules about when and how your app can access location data in the background, and app stores are increasingly rigorous about enforcing these rules during review.
In this article, I'll walk you through the reality of background location permissions, show you why stores reject apps that misuse them, and share concrete patterns I've used across ride-hailing, delivery, and travel platforms to get approval without compromising user experience.
Background Location Needs Extra Permissions
On Android, there are three location permission levels. Most developers know about ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION—these grant foreground access. But accessing location while your app runs in the background requires ACCESS_BACKGROUND_LOCATION, a separate permission that users grant independently on Android 10 and above.
The key difference: foreground location is available whenever your app is visible and active. Background location applies when the app has moved to the background, the screen is off, or the user has switched to another app. On iOS, the situation is slightly different but equally restrictive. Always-on location access (the blue arrow icon users see) triggers a battery and privacy warning in the OS itself.
Here's the permission setup in your AndroidManifest.xml:
<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" />But declaring the permission in the manifest is only the first step. You must request it at runtime using a package like geolocator or permission_handler. When you request ACCESS_BACKGROUND_LOCATION, the OS shows users a special dialog explaining that your app can track their location at all times.
On iOS, you'll declare NSLocationWhenInUseUsageDescription for foreground access and NSLocationAlwaysAndWhenInUseUsageDescription for background access in Info.plist:
<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to show nearby drivers.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We need continuous location access to track your ride.</string>The subtle but important point: iOS distinguishes between "when in use" and "always," and users have a separate control for each. Requesting "always" permission shows a yellow banner warning the user of continuous tracking.
Store Review is Stricter Than You'd Expect
Apple and Google have both tightened their app store policies around background location. Both platforms explicitly state that background location access is only acceptable if your app's core functionality genuinely requires it. A fitness app that tracks routes needs it. A social networking app that shows friends' locations does not.
During the review process, I've seen rejections with messages like: "This app requests background location permission, but we do not see a clear user-facing feature that requires continuous location tracking." The reviewers test your app, look for the promised functionality, and reject if the use case feels forced or deceptive.
Google Play in particular has flagged apps that request background location but show generic features like "nearby stores" or "local recommendations." The bar for what counts as a legitimate use case is high. Here's what typically passes:
- Ride-hailing or taxi apps tracking live driver position
- Delivery services showing real-time package location
- Fitness apps recording jogging or cycling routes
- Navigation apps like Google Maps maintaining navigation in the background
- Geofencing-based features like work clock-in when arriving at an office
What often fails:
- Games requesting background location
- Shopping apps offering "nearby deals"
- General social apps claiming location is for safety
- Apps requesting it but never using it in the user-facing UI
My recommendation: document your background location use case in plain language in your app's privacy policy and in-app help section. During review, stores may ask you to justify it. Have a clear, honest answer ready. If your feature doesn't truly need background location, remove the permission and use geofencing or periodic location checks instead.
Use Foreground Services on Android
Foreground services are the Android-first solution to background work that users should be aware of. A foreground service runs with a persistent notification, making it clear to users that something is happening. This is what Uber, DoorDash, and Google Maps use while actively tracking location.
The advantage: you don't need ACCESS_BACKGROUND_LOCATION permission if you use a foreground service. The service keeps your app alive, and the notification keeps users informed. Store reviewers generally accept foreground services because the permission model is transparent.
To implement a foreground service in Flutter, you'll use platform channels or a package like flutter_foreground_task. Here's a basic example:
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
void startLocationTracking() {
FlutterForegroundTask.startService(
serviceId: 256,
notificationTitle: 'Tracking Your Ride',
notificationText: 'Your location is being shared.',
notificationIcon: null,
callback: _updateLocationCallback,
);
}
void _updateLocationCallback() {
// This runs in an isolate, even if app is backgrounded
// Fetch location and send to backend
}The notification is mandatory and always visible. Users can see at a glance that your app is accessing their location. This transparency is why stores favor it. The user can also swipe away the notification or kill the service directly from the notification panel.
Important caveat: foreground services consume battery. On older devices, this is noticeable. If your use case is truly real-time (like active ride tracking), foreground services are the right choice. If you only need periodic updates, consider batching location requests or using geofencing triggers instead.
On iOS, the equivalent is to request NSLocationAlwaysAndWhenInUseUsageDescription and use CLLocationManager with allowsBackgroundLocationUpdates = true. iOS shows a blue status bar when location is active, serving a similar transparency function.
Only Request What Your Feature Needs
This is the principle that ties everything together. Every permission request is a friction point for users. Each one requires explicit consent. Each one is scrutinized by app reviewers. So ask yourself: does my feature need background location, or can I achieve the goal another way?
In a delivery tracking app I built, we initially requested background location for drivers. But we realized that drivers spend most of their active time in the app, and for the brief moments they minimize it, periodic GPS updates (every 5-10 seconds) were sufficient. We switched to requesting only foreground location, used a foreground service during active delivery, and reduced battery drain significantly. The app passed review on the first submission.
Here are alternatives worth considering:
- Geofencing: Trigger actions when the user enters or leaves a region without continuous tracking. Works offline and uses far less battery.
- Periodic location updates: Fetch location at intervals (e.g., every 30 seconds) rather than continuous streaming. Still works in the background but saves power.
- WiFi and cell tower location: Coarse-grained location that doesn't require GPS, uses less battery, and doesn't need background permission.
- Significant location change: On iOS, use
startMonitoringSignificantLocationChangesto get notified only when the user moves significantly (e.g., 500m).
In the geolocator package, you can set location accuracy and distance filters to minimize battery drain:
await Geolocator.getPositionStream(
locationSettings: LocationSettings(
accuracy: LocationAccuracy.medium, // Use medium instead of best
distanceFilter: 100, // Only update every 100 meters
),
).listen((Position position) {
// Handle location update
});The principle applies to all permissions. Request location when you truly need it, at the granularity you truly need it, and no more. This approach respects user privacy, reduces battery drain, and speeds up app review.
Common Mistakes
- Requesting background location without a foreground service on Android: This triggers app suspensions and review rejections. If you need background location, use a foreground service or geofencing.
- Declaring the permission in the manifest but never asking the user at runtime: Reviewers test by denying permissions and checking if the app handles it gracefully. Always request permissions explicitly, check the result, and degrade gracefully.
- Showing a vague justification message: When you request background location, the permission dialog shows your app name and the system message. Have a clear, contextual explanation in your app before requesting it, not after.
- Testing only on your own device: You've granted permissions, so your app will work. Test on a clean device or emulator where permissions are denied by default. Ensure the app still works and explains why it needs the permission.
- Leaving background location enabled in a production build by mistake: In development, you might request it for testing. Make sure it's tied to a feature flag or development-only code path. Accidentally shipping it will trigger reviewer scrutiny.
Key Takeaways
- Background location requires explicit permission on both iOS and Android, and both platforms restrict it to features where continuous tracking is genuinely necessary.
- App store reviewers test background location claims during review. If your app requests it but doesn't visibly use it, expect rejection.
- Use foreground services on Android to avoid
ACCESS_BACKGROUND_LOCATIONpermission while keeping the user informed via a persistent notification. - Geofencing, periodic updates, and WiFi/cell-based location are lighter-weight alternatives that often satisfy use cases without requiring background access.
- Always request the minimum permission needed for your feature. Each permission is a friction point and a review risk.
- Test permission denial scenarios early. Build the app so it works without location, then add location as an enhancement.
- Document your background location use case clearly in your privacy policy and help text. You may be asked to justify it during review.






Comments
Loading comments…