-
Notifications
You must be signed in to change notification settings - Fork 444
Description
Required Reading
- Confirmed
Plugin Version
5.0.3
Mobile operating-system(s)
- iOS
- Android
Device Manufacturer(s) and Model(s)
Apple, Oppo, Samsung
Device operating-systems(s)
iOS 26.3 and Android 15
React Native / Expo version
0.84.0
What do you require assistance about?
We’re using react-native-background-geolocation for a business requirement where we need:
-> A real-time-ish UI moving/stationary state and current location while the app is open
-> Same state via MQTT for other users (so if someone stops, others must receive that “stopped” state)
-> Works in Android killed/terminated mode (headless) (we already added in the index.js for android as you suggested)
-> Geofencing accuracy / triggers around ~100 meters
-> Real time speed for the user when driving
** The issue / question **
We want to confirm that our configuration approach is correct, given that we are using battery-saving modes:
--> We set desiredAccuracy to BackgroundGeolocation.DesiredAccuracy.VeryLow (and sometimes Low)
--> But we also configure a small distanceFilter (like 1 or 10) and even dynamically update it based on current motion/speed (for 0-50 mph, 10 for 51-60, 20 for 61--80 and 25 and 81-90 and 40 for 91+)
--> iOS shows as moving but not always, but Android is causing issues in a bit of testing we did
We already verified from docs that Low / Lowest do not use GPS.
--> required moving/stationary transitions
--> required location updates for UI + MQTT
--> required geofence behavior around ~100m
--> and reliable behavior in headless mode
--> Real time speed when user moving
** Why we think it might be wrong **
We observe that Android is creating issues as well, in real testing, the user is not always moving. We suspect it’s related to the combination of:
--> desiredAccuracy: VeryLow/Low
--> distanceFilter being small but still > 0
--> allowIdenticalLocations: false
--> and/or how the plugin determines state changes when not using GPS
** Questions **
- Config correctness: Is it correct to use desiredAccuracy: VeryLow / Low together with a very small distanceFilter (e.g., 1 or 10) to achieve reliable moving/stationary state transitions for UI + MQTT?
- Geofence behavior around ~100m: With desiredAccuracy set to Low/VeryLow, will geofence triggering be consistent for ~100m geofences, or do we need a higher desiredAccuracy for acceptable geofence behavior?
- State transition behavior without GPS: Since Low/VeryLow do not use GPS (as confirmed in docs), does the plugin still reliably generate the kind of state transition we need when the user stops (so other users can receive the “stopped” state)?
- allowIdenticalLocations: With allowIdenticalLocations: false, is it expected that after stopping the SDK may stop emitting location/state updates (or emit fewer updates), even if distanceFilter is small? Should we change this for our use case?
- What to change (docs-aligned): If our current “VeryLow + small distanceFilter” strategy is not the intended approach for this business logic, what configuration knobs should we adjust instead (e.g. recommended locationUpdateInterval strategy, heartbeat usage, stop-detection / stationary settings), specifically for moving/stationary + MQTT + geofences in headless?
Our goal
We want a doc-confirmed configuration strategy that is battery-conscious but still fulfills:
--> UI moving/stationary updates
--> MQTT broadcasting of stopped/moving transitions to other users
--> geofencing that works at ~100m
--> reliability even when app is killed (Android headless)
If you can point to the recommended config (or any “gotchas” around desiredAccuracy Low/VeryLow + distanceFilter + stop/stationary handling), that would be very helpful.
Thanks for your support
[Optional] Plugin Code and/or Config
BackgroundGeolocation.ready({
geolocation:{
desiredAccuracy: BackgroundGeolocation.DesiredAccuracy.VeryLow,
distanceFilter: 1, // we are changing when user start moving (below is below)
stopTimeout: 5,
stationaryRadius: 5,
pausesLocationUpdatesAutomatically: false,
locationAuthorizationRequest: 'Always',
showsBackgroundLocationIndicator: true,
activityType: BackgroundGeolocation.ActivityType.Other,
disableElasticity: false, // i think we need to disable it according to doc
allowIdenticalLocations: false,
},
logger:{
debug: false,
logLevel: BackgroundGeolocation.LogLevel.Error
},
activity: {
stopOnStationary: false,
},
app:{
stopOnTerminate:false,
startOnBoot:true,
enableHeadless:true
},
});
// updating the distance filter
if (speedMph === null || speedMph <= 3) {
// Standing / very slow
distance = 50;
distanceFilter = 1;
} else if (speedMph <= 10) {
// Walking / slow jog
distance = 75;
distanceFilter = 1;
} else if (speedMph <= 20) {
// City cycling / slow city traffic
distance = 100;
distanceFilter = 1;
} else if (speedMph <= 30) {
// Faster city traffic
distance = 150;
distanceFilter = 1;
} else if (speedMph <= 40) {
distance = 200;
distanceFilter = 1;
} else if (speedMph <= 50) {
distance = 250;
distanceFilter = 1;
} else if (speedMph <= 60) {
distance = 300;
distanceFilter = 10;
} else if (speedMph <= 70) {
distance = 350;
distanceFilter = 20;
} else if (speedMph <= 80) {
distance = 400;
distanceFilter = 20;
} else if (speedMph <= 90) {
distance = 450;
distanceFilter = 25;
} else {
distance = 500;
distanceFilter = 40;
}
const currState = await BackgroundGeolocation.getState();
if (currState.geolocation.distanceFilter !== distanceFilter) {
try {
await BackgroundGeolocation.setConfig({ geolocation:{ distanceFilter } });
} catch (error) {}
}