transistorsoft / transistorsoft/react-native-background-geolocation

[Help Wanted]: Fully disable motion detection when using Significant Location Changes on iOS

Open
#2,652 18 comments 0 reactions 0 assignees View on GitHub

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.