Skip to content

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

Description

@fractalbeauty

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions