transistorsoft / transistorsoft/react-native-background-geolocation
[Help Wanted]: Fully disable motion detection when using Significant Location Changes on iOS
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 2.9k
- Forks
- 446
- PR merge metrics
- No merged PRs in 30d
Description
Required Reading
- Confirmed
Plugin Version
5.1.1
Mobile operating-system(s)
- iOS
- Android
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
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the configuration for useSignificantChangesOnly, disableMotionActivityUpdates, and disableStopDetection, then trace the logged TSTrackingService start, TSMotionDetector start, and TSScheduler startMonitoringSignificantLocationChanges entry points. Reproduce the reported startup and motion-change logs on iOS. Done means the requested configuration is documented or supported without starting unnecessary motion detection or issuing standard motionchange location requests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- ios, react-native, typescript
- Domain
- mobile-dev, performance
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100