react-native-background-geolocation
react-native-background-geolocation copied to clipboard
iOS tracking is cutting (going still but it IS moving).
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
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
Increase Config.stopTimeout as desired.
See api docs Config.disableStopDetection, Config.pausesLocationUpdatesAutomarically.
Read the wiki "Philosophy of Operation".
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.
I suggest you increase the stopTimeout (to one hour, for example).
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).
we don't really understand how expanding the stopTimeout
It will give the motion api more time and opportunity to detect movement.
Try it.
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?
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.