Requesting always-on background location when only foreground location is needed is one of the most common grounds for App Store rejection and a clear GDPR Art. 5(1)(c) data-minimisation violation. Apple's location always permission (NSLocationAlwaysAndWhenInUseUsageDescription) triggers a two-step authorization flow that explicitly warns users their location is tracked in the background — users decline this at far higher rates than when-in-use. On Android 10+, background location requires an additional ACCESS_BACKGROUND_LOCATION permission that triggers a separate, more alarming system dialog. Apps requesting always-on location for features like map display or restaurant search — where when-in-use is sufficient — face Google Play policy strikes and user complaints.
High because requesting always-on location for features that only need foreground location violates GDPR Art. 5(1)(c), triggers heightened Apple and Google review scrutiny, and causes significantly higher permission denial rates.
Default to LOCATION_WHEN_IN_USE for all location features. Only escalate to LOCATION_ALWAYS when a documented background feature (fitness tracking, delivery tracking, geofencing) specifically requires it.
import { request, PERMISSIONS, RESULTS } from 'react-native-permissions'
// Default: request when-in-use
const foregroundResult = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE)
// Only if a background feature genuinely exists:
if (userEnablesBackgroundTracking) {
const backgroundResult = await request(PERMISSIONS.IOS.LOCATION_ALWAYS)
}
In app.json, only add NSLocationAlwaysAndWhenInUseUsageDescription if your app has an active background location feature. Remove the key entirely if the app only needs foreground location — its presence alone triggers additional scrutiny during App Store review.
ID: mobile-permissions-privacy.permission-requests.location-granularity
Severity: high
What to look for: Count all location permission request calls. For each, quote the actual permission constant used (e.g., PERMISSIONS.IOS.LOCATION_WHEN_IN_USE vs PERMISSIONS.IOS.LOCATION_ALWAYS). Check iOS Info.plist for NSLocationWhenInUseUsageDescription vs NSLocationAlwaysAndWhenInUseUsageDescription. On Android, check ACCESS_FINE_LOCATION vs background location.
Pass criteria: If the app needs location, it requests at minimum when-in-use and only escalates to always if genuinely needed for background location features. At least 1 location permission request uses the granular when-in-use API. User is not forced into always-on location.
Fail criteria: App requests always-on location for features that only need when-in-use location. OR app provides no distinction between permission levels. Do NOT pass when the app requests LOCATION_ALWAYS but has no background location feature.
Skip (N/A) when: App does not use location (no location permission requests or declarations found).
Detail on fail: Quote the actual permission constant. "App requests location 'always' permission but primary feature (map display) only needs when-in-use access" or "Location permission offers no distinction between levels — user cannot choose when-in-use only"
Remediation: Minimize location access scope. For most features, when-in-use location is sufficient. Only request always-on location if your app genuinely needs background location (e.g., fitness tracking, delivery tracking):
// iOS: Distinguish permission levels
const iosConfig = {
NSLocationWhenInUseUsageDescription: 'We use your location to show nearby content while the app is open',
NSLocationAlwaysAndWhenInUseUsageDescription: 'We need background location for fitness tracking'
}
// Request when-in-use by default
const result = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE)