react-native-background-geolocation icon indicating copy to clipboard operation
react-native-background-geolocation copied to clipboard

iOS tracking is cutting (going still but it IS moving).

Open benjamin-beau opened this issue 1 year ago • 6 comments

Your Environment

  • Plugin version: 4.14.3
  • Platform: iOS
  • OS version: 17.1.2
  • Device manufacturer / model: iPhone12,8
  • React Native version (react-native -v): 11.3.7
  • Plugin config
{
    reset: true,
    desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_NAVIGATION,
    distanceFilter: 10,
    stopTimeout: 5,
    stationaryRadius: 1,
    stopOnTerminate: false,
    startOnBoot: true,
    foregroundService: true,
    enableHeadless: true,
    preventSuspend: true,
    showsBackgroundLocationIndicator: true,
    locationAuthorizationRequest: 'Always',
    locationAuthorizationAlert: {
      titleWhenNotEnabled: "La géolocalisation en arrière plan n'est pas activée",
      titleWhenOff: 'La géolocalisation est désactivée',
      instructions:
        "Pour garantir un bon enregistrement, il faut choisir '{locationAuthorizationRequest}' dans tes paramètres de géolocalisation.",
      settingsButton: 'Paramètres',
      cancelButton: 'Annuler',
    },
    backgroundPermissionRationale: {
      title:
        'Autoriser {applicationName} à accéder à la localisation de cet appareil en arrière-plan ?',
      message:
        "Afin de suivre votre activité en arrière-plan, veuillez activer l'autorisation de localisation {backgroundPermissionOptionLabel}.",
      positiveAction: 'Changer pour {backgroundPermissionOptionLabel}',
      negativeAction: 'Annuler',
    },
    notification: {
      channelName: 'Enregistrement en cours',
      title: 'Enregistrement en cours',
      text: "Surlo est actuellement en train d'enregistrer votre progression. Appuyer pour revenir à l'application.",
      smallIcon: 'mipmap/ic_notification',
    },
    debug: isAndroid && Config.ENV === 'staging',
    logLevel: BackgroundGeolocation.LOG_LEVEL_VERBOSE,
    // HTTP & Persistence
    method: 'POST',
    params: {
      session: `api/sessions/${getSession()?.id}`,
    },
    httpRootProperty: 'trackings',
    locationTemplate:
      '{' +
      '"lat": <%= latitude %>,' +
      '"lng": <%= longitude %>,' +
      '"bearing": 1,' +
      '"trackTime": "<%= timestamp %>",' +
      '"specifics": {' +
      '"heading": <%= heading %>,' +
      '"speed":<%= speed %>,' +
      '"accuracy":<%= accuracy %>,' +
      '"event":"<%= event %>",' +
      '"activity_type":"<%= activity.type %>",' +
      '"activity_confidence":<%= activity.confidence %>,' +
      '"battery_level":<%= battery.level %>,' +
      '"battery_is_charging":<%= battery.is_charging %>,' +
      '"mock":<%= mock %>,' +
      '"is_moving":<%= is_moving %>,' +
      `"os":"${isAndroid ? 'android' : 'ios'}",` +
      `"osVersion":"${DeviceInfo.getSystemVersion()}",` +
      `"brand":"${DeviceInfo.getBrand()}",` +
      `"device":"${DeviceInfo.getDeviceId()}",` +
      `"appVersion":"${getVersion()}.${getBuildNumber()}"` +
      (__DEV__ ? ',"emulated" : true' : '') +
      '}' +
      '}',
    url: `${Config.API_URL}api/surlo_trackings/multiple`,
    authorization: {
      strategy: 'JWT',
      accessToken: getCurrentToken(),
      refreshToken: authData.refreshToken,
      refreshUrl: `${Config.API_URL}token/refresh`,
      refreshPayload: {
        refresh_token: '{refreshToken}',
      },
      expires: undefined,
    },
    autoSync: true,
    batchSync: true,
    maxBatchSize: 5,
    maxDaysToPersist: 14,
  }

Expected Behavior

No pause in tracking because the device IS moving.

Actual Behavior

Screenshot 2024-02-19 at 12 46 27

We observe issues on iOS while tracking sailing boat on water. The tracking pauses randomly and then starts back up for a while (see capture). It doesn't occur on Android only iOS. It seems to be related to activity recognition and motion change. We implemented this code to try and solve our issues (you will find it in logs) but it didn't help:

onMotionChangeListener = BackgroundGeolocation.onMotionChange(onMotionChange)

...

const onMotionChange = ({ isMoving }: MotionChangeEvent) => {
  if (!isMoving) {
    BackgroundGeolocation.logger.warn(
      'MOTION CHANGE EVENT DETECT user is now still, executing changePace(true).',
    )
    BackgroundGeolocation.changePace(true)
      .then(() => BackgroundGeolocation.logger.info('EXECUTION SUCCESSFULL for changePace(true).'))
      .catch((error: string) =>
        BackgroundGeolocation.logger.error(`ERROR WHILE EXECUTING changePace(true) : ${error}`),
      )
  }
}

It wakes the tracking up but not until after 5mins of no locations...

Context

We provided one example but it occurs on many devices on iOS, we tested other tracking apps on those device and it works. Here are the location data we received on our server : data-1708342969435.csv

How could we improve the activity recognition or prevent motion changes ?
Could disabling the activity recognition help prevent this problem ?

Debug logs

_background-geolocation.log

benjamin-beau avatar Feb 19 '24 12:02 benjamin-beau

Increase Config.stopTimeout as desired.

See api docs Config.disableStopDetection, Config.pausesLocationUpdatesAutomarically.

Read the wiki "Philosophy of Operation".

christocracy avatar Feb 19 '24 13:02 christocracy

Increase Config.stopTimeout as desired.

I don't think it will improve on this issue. What we don't understand is why we are entering the stopTimeout even though the device IS moving. You can see in the following log extract that we are getting location data however still entering the stopTimeout of 5 minutes. We are getting no location while in the timeout and the MotionActivity API thinks that the device is still which is not the case. We only get locations back whenever the plugin enters the stationary state, which triggers the changePace callback. Is the problem coming from the fact that iOS can't detect properly the activity type when sailing a boat on water ?

2024-01-28 10:24:51.002 🔵-[TSLocationManager startMotionTriggerTimer] Motion-trigger timer engaged: Stop-detection will trigger in 10 seconds...
2024-01-28 10:24:53.039 
📍<+47.65187970,-3.34931992> +/- 4.77m (speed 2.60 mps / course 144.21) @ 28/01/2024, 10:24:52 Central European Standard Time
2024-01-28 10:25:01.007 🔵-[TSLocationManager beginStopDetection] ⏲Stop-timeout engaged: 300 s...
2024-01-28 10:30:01.056 🔵-[TSLocationManager onStopTimeout:] stopTimer fired
2024-01-28 10:30:01.057 🔵-[TSLocationManager setPace:] 0
2024-01-28 10:30:02.080 ✅-[TSLocationManager locationManager:didUpdateLocations:] Acquired motionchange position: <+47.64641678,-3.34405364> +/- 4.76m (speed 2.23 mps / course 150.36) @ 28/01/2024, 10:30:01 Central European Standard Time

See api docs Config.disableStopDetection,
Config.pausesLocationUpdatesAutomarically.

If we configure the plugin to ignore the stop detection system and thus not needing the activity permission, we are at risk of overusing the user's device battery if they don't properly stop the tracking. Is there a way to stop the plugin from the server ? I remember reading an article about you needing this feature to prevent overuse of your test server.

benjamin-beau avatar Feb 19 '24 18:02 benjamin-beau

I suggest you increase the stopTimeout (to one hour, for example).

christocracy avatar Feb 19 '24 18:02 christocracy

As I said, we don't really understand how expanding the stopTimeout can improve on this situation. We don't receive location data while in the timeout. It works again whenever the plugin goes into stationnary state, thus triggering the changePace callback (snippet showed in my initial message).

benjamin-beau avatar Feb 21 '24 10:02 benjamin-beau

we don't really understand how expanding the stopTimeout

It will give the motion api more time and opportunity to detect movement.

Try it.

christocracy avatar Feb 21 '24 10:02 christocracy

Do you mean we need to give the library more time initially for it to learn how to properly detect movements so that it detects them more rapidly afterwards?

benjamin-beau avatar Feb 21 '24 14:02 benjamin-beau

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Apr 17 '24 01:04 github-actions[bot]

This issue was closed because it has been inactive for 14 days since being marked as stale.

github-actions[bot] avatar May 01 '24 01:05 github-actions[bot]