Required Reading
Plugin Version
5.1.1
Mobile operating-system(s)
Device Manufacturer(s) and Model(s)
iPhone, unsure of model
Device operating-systems(s)
iOS 18.6
React Native / Expo version
0.81
What do you require assistance about?
Hello, we're investigating some issues with battery usage in our app that uses react-native-background-geolocation.
To save battery, we are using the Significant Location Changes API on iOS. We have also configured disableMotionActivityUpdates: false and disableStopDetection: false since we are using SLC and it doesn't seem like stop detection is needed. I think disableMotionActivityUpdates: false might be wrong (according to the docs), since it uses the expensive fallback instead of CMMotionActivityManager. I'm pretty sure changing it back to true will save some battery, but we would like to completely disable activity detection if possible, assuming that monitoring CMMotionActivityManager also costs some battery compared to only use SLC.
Is it possible to configure the SDK to never use TSMotionDetector/CMMotionActivityManager? Is motion detection needed at all when SLC is used?
I can provide more complete logs if needed.
[Optional] Plugin Code and/or Config
{
geolocation: {
useSignificantChangesOnly: true,
desiredAccuracy: BackgroundGeolocation.DesiredAccuracy.Low,
deferTime: Platform.OS === 'android' ? 10 * 60 * 1000 : undefined,
disableLocationAuthorizationAlert: true,
showsBackgroundLocationIndicator: false,
},
activity: {
disableMotionActivityUpdates: Platform.OS === 'ios',
disableStopDetection: Platform.OS === 'ios',
},
app: {
stopOnTerminate: false,
startOnBoot: true,
},
persistence: {
persistMode: BackgroundGeolocation.PersistMode.Location,
maxDaysToPersist: 30,
locationTemplate:
'{"location":{"latitude":<%= latitude %>,"longitude":<%= longitude %>},"dateTime":"<%= timestamp %>","accuracy":<%= accuracy %>,"version":1}',
},
http: {
batchSync: true,
url: `redacted`,
method: 'POST',
autoSync: true,
autoSyncThreshold: 10,
rootProperty: 'locations',
maxBatchSize: 10_000,
},
logger: {
logMaxDays: 7,
logLevel: LogLevel.Verbose,
},
}
[Optional] Relevant log output
Config at launch (trimmed):
2026-08-14 13:52:36.575 TSLocationManager (build 4109)
{
activity = {
activityRecognitionInterval = 10000;
disableMotionActivityUpdates = 1;
disableStopDetection = 1;
minimumActivityRecognitionConfidence = 70;
stopDetectionDelay = 0;
stopOnStationary = 0;
triggerActivities = "";
};
geolocation = {
desiredAccuracy = 100;
pausesLocationUpdatesAutomatically = 1;
showsBackgroundLocationIndicator = 0;
stationaryRadius = 25;
stopTimeout = 5;
useSignificantChangesOnly = 1;
};
preventSuspend = 0;
enabled = 1;
}
start still starts the detector (SLC starts on the next lines):
2026-08-14 13:52:36.580 App launched with background=true, location=true
2026-08-14 13:52:37.147 -[TSTrackingService start:] trackingMode: 1
2026-08-14 13:52:37.148 -[TSMotionDetector start]
2026-08-14 13:52:37.148 -[TSMotionDetector startSensorDetection]
2026-08-14 13:52:37.148 -[TSTrackingService changePace:] isMoving: 0
2026-08-14 13:52:37.148 -[TSLocationRequestService requestLocation:] [motionchange] maximumAge: 5000
2026-08-14 13:52:37.148 Adaptive sampling -> dt=0.100s (10 Hz)
2026-08-14 13:52:37.149 -[TSScheduler startMonitoringSignificantLocationChanges]
Classifier keeps running and flip-flops at speed=0.20 (still → moving → still → running/100 → still):
2026-08-14 13:52:47.285 classifyWithSpeed: walkP=2.137 runP=2.574 speed=0.20
2026-08-14 13:52:47.287 Adaptive sampling -> dt=0.200s (5 Hz)
2026-08-14 13:52:47.287 onMotionActivityChange: | still/80 | isMoving: 0
2026-08-14 13:53:07.236 classifyWithSpeed: walkP=93.070 runP=101.557 speed=0.20
2026-08-14 13:53:07.237 Adaptive sampling -> dt=0.100s (10 Hz)
2026-08-14 13:53:07.238 onMotionActivityChange: | moving/50 | isMoving: 1
2026-08-14 13:53:17.278 onMotionActivityChange: | still/80 | isMoving: 0
2026-08-14 13:53:27.201 Adaptive sampling -> dt=0.040s (25 Hz)
2026-08-14 13:53:27.201 onMotionActivityChange: | running/100 | isMoving: 1
2026-08-14 13:53:47.188 onMotionActivityChange: | still/80 | isMoving: 0
Those flips request standard location updates ([motionchange] 20 m), which defeats SLC:
2026-08-14 18:25:33.193 Classifier suggests still/80 at speed=-1.00
2026-08-14 18:25:33.195 -[TSTrackingService changePace:] isMoving: 0
2026-08-14 18:25:33.196 requestLocation: [motionchange] maximumAge: 5000
2026-08-14 18:25:33.209 trySatisfy [motionchange] desiredAccuracy: 20.0 m
Session counts (13:48–21:37): 1642 classifier ticks, 188 activity changes, 119 isMoving flips
Required Reading
Plugin Version
5.1.1
Mobile operating-system(s)
Device Manufacturer(s) and Model(s)
iPhone, unsure of model
Device operating-systems(s)
iOS 18.6
React Native / Expo version
0.81
What do you require assistance about?
Hello, we're investigating some issues with battery usage in our app that uses
react-native-background-geolocation.To save battery, we are using the Significant Location Changes API on iOS. We have also configured
disableMotionActivityUpdates: falseanddisableStopDetection: falsesince we are using SLC and it doesn't seem like stop detection is needed. I thinkdisableMotionActivityUpdates: falsemight be wrong (according to the docs), since it uses the expensive fallback instead of CMMotionActivityManager. I'm pretty sure changing it back to true will save some battery, but we would like to completely disable activity detection if possible, assuming that monitoring CMMotionActivityManager also costs some battery compared to only use SLC.Is it possible to configure the SDK to never use TSMotionDetector/CMMotionActivityManager? Is motion detection needed at all when SLC is used?
I can provide more complete logs if needed.
[Optional] Plugin Code and/or Config
[Optional] Relevant log output
Config at launch (trimmed): 2026-08-14 13:52:36.575 TSLocationManager (build 4109) { activity = { activityRecognitionInterval = 10000; disableMotionActivityUpdates = 1; disableStopDetection = 1; minimumActivityRecognitionConfidence = 70; stopDetectionDelay = 0; stopOnStationary = 0; triggerActivities = ""; }; geolocation = { desiredAccuracy = 100; pausesLocationUpdatesAutomatically = 1; showsBackgroundLocationIndicator = 0; stationaryRadius = 25; stopTimeout = 5; useSignificantChangesOnly = 1; }; preventSuspend = 0; enabled = 1; } start still starts the detector (SLC starts on the next lines): 2026-08-14 13:52:36.580 App launched with background=true, location=true 2026-08-14 13:52:37.147 -[TSTrackingService start:] trackingMode: 1 2026-08-14 13:52:37.148 -[TSMotionDetector start] 2026-08-14 13:52:37.148 -[TSMotionDetector startSensorDetection] 2026-08-14 13:52:37.148 -[TSTrackingService changePace:] isMoving: 0 2026-08-14 13:52:37.148 -[TSLocationRequestService requestLocation:] [motionchange] maximumAge: 5000 2026-08-14 13:52:37.148 Adaptive sampling -> dt=0.100s (10 Hz) 2026-08-14 13:52:37.149 -[TSScheduler startMonitoringSignificantLocationChanges] Classifier keeps running and flip-flops at speed=0.20 (still → moving → still → running/100 → still): 2026-08-14 13:52:47.285 classifyWithSpeed: walkP=2.137 runP=2.574 speed=0.20 2026-08-14 13:52:47.287 Adaptive sampling -> dt=0.200s (5 Hz) 2026-08-14 13:52:47.287 onMotionActivityChange: | still/80 | isMoving: 0 2026-08-14 13:53:07.236 classifyWithSpeed: walkP=93.070 runP=101.557 speed=0.20 2026-08-14 13:53:07.237 Adaptive sampling -> dt=0.100s (10 Hz) 2026-08-14 13:53:07.238 onMotionActivityChange: | moving/50 | isMoving: 1 2026-08-14 13:53:17.278 onMotionActivityChange: | still/80 | isMoving: 0 2026-08-14 13:53:27.201 Adaptive sampling -> dt=0.040s (25 Hz) 2026-08-14 13:53:27.201 onMotionActivityChange: | running/100 | isMoving: 1 2026-08-14 13:53:47.188 onMotionActivityChange: | still/80 | isMoving: 0 Those flips request standard location updates ([motionchange] 20 m), which defeats SLC: 2026-08-14 18:25:33.193 Classifier suggests still/80 at speed=-1.00 2026-08-14 18:25:33.195 -[TSTrackingService changePace:] isMoving: 0 2026-08-14 18:25:33.196 requestLocation: [motionchange] maximumAge: 5000 2026-08-14 18:25:33.209 trySatisfy [motionchange] desiredAccuracy: 20.0 m Session counts (13:48–21:37): 1642 classifier ticks, 188 activity changes, 119 isMoving flips