Permissions
Long Ping never prompts on its own. configure() and start() never show a dialog;
requestPermission() is the only call that does, and it only shows the operating system’s own flow.
Explaining why you need location, before the OS dialog appears, is your app’s job.
The flow
Section titled “The flow”import LongPing, { AuthorizationStatus } from 'react-native-long-ping';
async function goOnDuty() { // 1. Your own screen: who sees the location, when, and why "Always". const agreed = await showLocationRationale(); if (!agreed) return;
// 2. The OS flow. Resolves an AuthorizationStatus number. const status = await LongPing.requestPermission('always');
if (status === AuthorizationStatus.WHEN_IN_USE) { // Tracking works while the app is in use; explain what "Always" adds and offer Settings. await showUpgradeHint(() => LongPing.deviceSettings.openAppSettings()); } if (status === AuthorizationStatus.DENIED || status === AuthorizationStatus.RESTRICTED) { return showBlockedScreen(() => LongPing.deviceSettings.openAppSettings()); }
// 3. Start. Rejects PERMISSION_DENIED or LOCATION_SERVICES_OFF, never prompts. await LongPing.start();}requestPermission(level) takes 'whenInUse' or 'always'.
What each platform shows for 'always'
Section titled “What each platform shows for 'always'”- The “While Using the App” prompt (your
NSLocationWhenInUseUsageDescription). - Then
requestAlwaysAuthorization, which asks to change to “Always” (yourNSLocationAlwaysAndWhenInUseUsageDescription).
The user can decline the upgrade, so read the status you get back. iOS shows each prompt only once per
install; after that, send people to Settings with deviceSettings.openAppSettings() (on iOS,
openLocationSettings() opens the same page).
Users can also turn off Precise Location. getProviderState() reports that as
accuracyAuthorization: 'reduced'.
- The foreground location dialog (fine and coarse).
- Then background location. On Android 11 and newer the system does not offer “Allow all the time” in a dialog, so Long Ping opens the system permission page, where the user picks it.
The call needs an Activity in the foreground to show anything. Without one it rejects NO_ACTIVITY.
POST_NOTIFICATIONS (Android 13+) is separate and is yours to request; see
Installation.
Reading the status
Section titled “Reading the status”requestPermission() resolves an AuthorizationStatus number:
| Value | Name | Meaning |
|---|---|---|
0 |
NOT_DETERMINED |
Not asked yet (or, on Android, the user can still be asked). |
1 |
RESTRICTED |
Blocked by the system or device management (iOS). |
2 |
DENIED |
Refused. Only Settings can change it now. |
3 |
ALWAYS |
Location in the background. What tracking needs. |
4 |
WHEN_IN_USE |
Location only while the app is in use. |
On iOS the values map straight from CLAuthorizationStatus (Apple’s order, except that 3 and 4 are
swapped). On Android they are derived:
- fine or coarse and background granted →
ALWAYS - fine or coarse granted →
WHEN_IN_USE - nothing granted →
DENIEDif the app has asked before and Android will no longer show the dialog, otherwiseNOT_DETERMINED
You can read the current value at any time with getProviderState() (field status) and follow changes
with onProviderChange.
What start() checks
Section titled “What start() checks”start() checks permission and location services, then starts tracking. It rejects with:
| Code | When |
|---|---|
PERMISSION_DENIED |
Location permission is missing. |
LOCATION_SERVICES_OFF |
Location services are switched off on the device. |
Nothing is persisted when start() rejects, so you can fix the cause and call it again.
Battery optimization (Android)
Section titled “Battery optimization (Android)”Permissions are not the whole story on Android: battery managers on many phones freeze apps regardless.
Plan a second, separate screen for that, using the deviceSettings helpers in
Android battery managers.