react-native-background-geolocation
react-native-background-geolocation copied to clipboard
Bug in dwell events and loitering delay on iOS
I created a geofence with radius 500m and with loiteringDelay as 900000ms (15mins). I had the app running on all times. When the app was stationary or with very little movement, the dwell event was fired after the exact loitering delay time. But if i continued activity and kept walking with the phone on, the dwell event fires as soon as the phone detects movement (when the location cursor shows up in the statusbar).
Your Environment
- Plugin version: 4.4.4
- Platform: iOS
- OS version: 15.2
- Device manufacturer / model: iPhone XS max
- React Native version (
react-native -v
): 0.64.0 - Plugin config
BackgroundGeolocation.onGeofence(this._onGeofenceEventChange);
_onGeofenceEventChange = async (geofenceEvent) => {
showMessage({ title: geofenceEvent.action })
return;
}
BackgroundGeolocation.ready({
// Geolocation Config
distanceFilter: 10,
preventSuspend: true,
requestTemporaryFullAccuracy: true,
locationAuthorizationRequest: 'Always',
disableLocationAuthorizationAlert: true,
desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
backgroundPermissionRationale: {
title: "Allow {applicationName} to access to this device's location in the background?",
message: "In order to track your activity in the background, please enable {backgroundPermissionOptionLabel} location permission",
positiveAction: "Change to {backgroundPermissionOptionLabel}",
negativeAction: "Cancel"
},
notification: {
largeIcon: 'drawable/ic_notification',
smallIcon: 'drawable/ic_notification'
},
}
import React from 'react';
import { ScrollView } from 'react-native';
import BackgroundGeolocation from 'react-native-background-geolocation';
import {
P1,
Height,
Container,
PrimaryButton,
} from '@components';
import {
getLocation
} from '@helpers/backgroundLocation';
const GeofenceTestController = () => {
const [location, setLocation] = React.useState({
lat: null,
long: null,
})
const [enabled, setEnabled] = React.useState(null);
const [geofences, setGeofences] = React.useState('');
const [requesting, setRequesting] = React.useState(false);
React.useEffect(() => {
const getCurrentLocation = async () => {
const location = await getLocation();
setLocation({
lat: location.coords.latitude,
long: location.coords.longitude
})
}
getCurrentLocation();
}, []);
React.useEffect(() => {
const _getGeofenceState = async () => {
const state = await BackgroundGeolocation.getState();
setEnabled(state.enabled);
const geofences = await BackgroundGeolocation.getGeofences();
setGeofences(JSON.stringify(geofences, null, 2));
}
_getGeofenceState();
}, [requesting]);
const _handleGeofenceButtonPress = async () => {
setRequesting(true);
try {
if (enabled) {
await BackgroundGeolocation.stop();
await BackgroundGeolocation.removeGeofences();
} else {
await BackgroundGeolocation.addGeofence({
latitude: location.lat,
longitude: location.long,
notifyOnExit: true,
notifyOnEntry: true,
identifier: `TEST`,
radius: 200,
notifyOnDwell: false,
loiteringDelay: 0,
})
await BackgroundGeolocation.startGeofences();
}
} finally {
const geofences = await BackgroundGeolocation.getGeofences();
setGeofences(JSON.stringify(geofences, null, 2));
setRequesting(false);
}
};
const _handleAddGeofence = async () => {
try {
await BackgroundGeolocation.addGeofence({
radius: 1000,
notifyOnExit: true,
notifyOnDwell: true,
loiteringDelay: 900000,
latitude: location.lat,
longitude: location.long,
identifier: 'TEST-TERTIARY',
})
} finally {
const geofences = await BackgroundGeolocation.getGeofences();
setGeofences(JSON.stringify(geofences, null, 2));
}
};
if (location.lat && location.long && enabled !== null) {
return (
<Container flex={1} hPadding={16}>
<P1 label={`Latitude: ${location.lat}`} />
<P1 label={`Longitude: ${location.long}`} />
<Height />
<Height />
<PrimaryButton
requesting={requesting}
onPress={_handleGeofenceButtonPress}
label={!enabled ? 'Start Geofencing' : 'Stop Geofencing'}
/>
<Height />
<Height />
<PrimaryButton
label={'Add geofence'}
onPress={_handleAddGeofence}
/>
{
!!geofences
&&
<ScrollView>
<P1 label={geofences} />
</ScrollView>
}
</Container>
)
}
return (
null
);
}
export default GeofenceTestController;
Expected Behavior
The dwell event should have been emitted after 15 mins.
Actual Behavior
The dwell event was emitted as soon as the phone picked up location change
Steps to Reproduce
- Call ready function
- Add a geofence with loitering delay
- Start moving as soon as the geofence is added
Context
I am trying to implement infinite geofencing. When the user exits a primary geofence, a secondary geofence is created with a loitering delay and the dwell event is captured if he stays longer than 15 mins. If the user exits the secondary geofence, a new geofence is created every time. If the user enters the primary geofence, all his secondary geofences are removed.
Show me plugins logs where this occurs. See Wiki Debugging to learn how to use the .emailLog
method to retrieve plugin's log file.
{
activityRecognitionInterval = 10000;
activityType = 1;
authorization = {
};
autoSync = 1;
autoSyncThreshold = 0;
batchSync = 0;
debug = 0;
desiredAccuracy = "-1";
desiredOdometerAccuracy = 100;
didDeviceReboot = 0;
didLaunchInBackground = 0;
didRequestUpgradeLocationAuthorization = 1;
disableAutoSyncOnCellular = 0;
disableElasticity = 0;
disableLocationAuthorizationAlert = 1;
disableMotionActivityUpdates = 0;
disableStopDetection = 0;
distanceFilter = 10;
elasticityMultiplier = 1;
enableTimestampMeta = 0;
enabled = 0;
extras = {
};
geofenceInitialTriggerEntry = 1;
geofenceProximityRadius = 2000;
geofenceTemplate = "";
headers = {
};
heartbeatInterval = 60;
httpRootProperty = location;
httpTimeout = 60000;
iOSHasWarnedLocationServicesOff = 0;
isFirstBoot = 0;
isMoving = 0;
lastLocationAuthorizationStatus = 3;
locationAuthorizationAlert = {
cancelButton = Cancel;
instructions = "To use background location, you must enable '{locationAuthorizationRequest}' in the Location Services settings";
settingsButton = Settings;
titleWhenNotEnabled = "Background location is not enabled";
titleWhenOff = "Location services are off";
};
locationAuthorizationRequest = Always;
locationTemplate = "";
locationTimeout = 60;
locationsOrderDirection = ASC;
logLevel = 5;
logMaxDays = 3;
maxBatchSize = "-1";
maxDaysToPersist = 1;
maxRecordsToPersist = "-1";
method = POST;
minimumActivityRecognitionConfidence = 70;
odometer = 0;
params = {
};
pausesLocationUpdatesAutomatically = 1;
persistMode = 2;
preventSuspend = 1;
schedule = (
);
schedulerEnabled = 0;
showsBackgroundLocationIndicator = 0;
startOnBoot = 0;
stationaryRadius = 25;
stopAfterElapsedMinutes = "-1";
stopDetectionDelay = 0;
stopOnStationary = 0;
stopOnTerminate = 1;
stopTimeout = 5;
trackingMode = 0;
url = "";
useSignificantChangesOnly = 0;
}
2022-02-22 10:26:03.589 βΉοΈ+[LocationAuthorization run:onCancel:] status: 3
2022-02-22 10:26:03.589 πΎ-[TSLocationManager startMonitoringBackgroundFetch] BackgroundFetch: ON
2022-02-22 10:26:03.593 βΉοΈ-[TSLocationManager startMonitoringBackgroundFetch]_block_invoke Configured BackgroundFetch
2022-02-22 10:26:03.601
π<+27.72450793,+85.32326662> +/- 46.06m (speed -1.00 mps / course -1.00) @ 21/02/2022, 11:48:16 Nepal Time
2022-02-22 10:26:03.601
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSLocationManager locationManager:didUpdateLocations:] Enabled: 1 | isMoving: 0 | df: -1.0m | age: 81466.8s
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:03.601 βΉοΈ-[TSLocationManager locationManager:didUpdateLocations:] Received stale motionchange location. Retrying...
2022-02-22 10:26:03.607 β
-[SOMotionDetector startDetection]_block_invoke Enabled M7 MotionActivity updates
2022-02-22 10:26:03.609
π<+27.72460304,+85.32288508> +/- 45.00m (speed -1.00 mps / course -1.00) @ 22/02/2022, 10:25:59 Nepal Time
2022-02-22 10:26:03.609
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSLocationManager locationManager:didUpdateLocations:] Enabled: 1 | isMoving: 0 | df: -1.0m | age: 4.4s
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:03.609 β
-[TSLocationManager locationManager:didUpdateLocations:] Acquired motionchange position: <+27.72460304,+85.32288508> +/- 45.00m (speed -1.00 mps / course -1.00) @ 22/02/2022, 10:25:59 Nepal Time
2022-02-22 10:26:03.609 π΅-[TSLocationManager startMonitoringStationaryRegion:radius:] Radius: 1000
2022-02-22 10:26:03.610 π΅-[TSLocationManager beginHeartbeat] 60
2022-02-22 10:26:03.610 π΄-[TSLocationManager stopUpdatingLocation]
2022-02-22 10:26:03.610 π΅-[TSLocationManager calculateMedianLocationAccuracy:] Median location accuracy: 45.0
2022-02-22 10:26:03.611 β
-[BackgroundTaskManager createBackgroundTask] 29
2022-02-22 10:26:03.612
π<+27.72460304,+85.32288508> +/- 45.00m (speed -1.00 mps / course -1.00) @ 22/02/2022, 10:26:03 Nepal Time
2022-02-22 10:26:03.612
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSLocationManager locationManager:didUpdateLocations:] Enabled: 1 | isMoving: 0 | df: 10.0m | age: 0.0s
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:03.612 π΅-[TSLocationManager calculateMedianLocationAccuracy:] Median location accuracy: 45.0
2022-02-22 10:26:03.612
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSLocationManager createMotionTypeChangedHandler]_block_invoke | on_foot/100 | isMoving: 1
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:03.787
π<+27.72460304,+85.32288508> +/- 45.00m (speed -1.00 mps / course -1.00) @ 22/02/2022, 10:26:03 Nepal Time
2022-02-22 10:26:03.787
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSGeofenceManager evaluateProximity:] Found 1 / 1 within 2000 m
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:03.792 πΎ-[TSGeofenceManager startMonitoringGeofence:] TEST
2022-02-22 10:26:03.800 πΎ-[TSGeofenceManager requestLocation]
2022-02-22 10:26:03.811 βΉοΈ+[LocationAuthorization run:onCancel:] status: 3
2022-02-22 10:26:13.808 π΅-[TSGeofenceManager locationManager:didUpdateLocations:] <+27.72469780,+85.32288736> +/- 13.91m (speed 0.70 mps / course 320.33) @ 22/02/2022, 10:26:13 Nepal Time
2022-02-22 10:26:13.809
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSGeofenceManager fireGeofenceEvent:] π’ENTER Geofence: TEST
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:13.819 β
-[TSGeofenceManager fireGeofenceEvent:] INSERT: 80440884-E630-4926-9E6D-E2445088757E
2022-02-22 10:26:13.819
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSHttpService flush:]
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:13.819
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSHttpService finish:error:] Success: 0
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:13.821 β
-[BackgroundTaskManager createBackgroundTask] 30
2022-02-22 10:26:14.829
π<+27.72469780,+85.32288736> +/- 13.91m (speed 0.70 mps / course 320.33) @ 22/02/2022, 10:26:13 Nepal Time
2022-02-22 10:26:14.829
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSGeofenceManager evaluateProximity:] Found 1 / 1 within 2000 m
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:14.834 π΅-[TSGeofenceManager evaluateProximity:delay:]_block_invoke Re-evaluation timer fired
2022-02-22 10:26:14.835 β
-[BackgroundTaskManager stopBackgroundTask:]_block_invoke 30 OF (
29,
30
)
2022-02-22 10:26:16.422 βΉοΈ-[GeofenceDAO doInsert:geofence:] TEST-TERTIARY
2022-02-22 10:26:16.637
π<+27.72469780,+85.32288736> +/- 13.91m (speed 0.70 mps / course 320.33) @ 22/02/2022, 10:26:13 Nepal Time
2022-02-22 10:26:16.637
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSGeofenceManager evaluateProximity:] Found 2 / 2 within 2000 m
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:16.640 πΎ-[TSGeofenceManager startMonitoringGeofence:] TEST-TERTIARY
2022-02-22 10:26:16.653 πΎ-[TSGeofenceManager requestLocation]
2022-02-22 10:26:16.677 βΉοΈ+[LocationAuthorization run:onCancel:] status: 3
2022-02-22 10:26:26.635 π΅-[TSGeofenceManager locationManager:didUpdateLocations:] <+27.72470335,+85.32277465> +/- 13.30m (speed 0.89 mps / course 260.02) @ 22/02/2022, 10:26:26 Nepal Time
2022-02-22 10:26:26.638 β
-[BackgroundTaskManager createBackgroundTask] 31
2022-02-22 10:26:26.638 πΎ-[TSGeofenceEvent startLoiteringAt:callback:] Geofence DWELL start: TEST-TERTIARY (900 s)
2022-02-22 10:26:56.968 βΉοΈ-[TSDBLogger db_save] Log committed
2022-02-22 10:27:03.555 π΅-[TSLocationManager onHeartbeat] Heartbeat
2022-02-22 10:27:03.557 π΅-[TSLocationManager startMotionTriggerTimer] Motion-trigger timer engaged: Query location-state will trigger in 10 seconds...
2022-02-22 10:27:13.557 πΎ-[LocationManager requestLocation] ONESHOT
2022-02-22 10:27:23.563
π<+27.72404340,+85.32217098> +/- 30.01m (speed 1.05 mps / course 156.20) @ 22/02/2022, 10:27:22 Nepal Time
2022-02-22 10:27:23.563 π΄-[LocationManager stopUpdatingLocation] OFF
2022-02-22 10:27:23.564
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[LocationManager locationManager:didUpdateLocations:] Sample 1 of 1
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:27:23.570
π<+27.72404340,+85.32217098> +/- 30.01m (speed 1.05 mps / course 156.20) @ 22/02/2022, 10:27:22 Nepal Time
2022-02-22 10:27:23.570
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSGeofenceManager evaluateProximity:] Found 2 / 2 within 2000 m
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:27:23.574 π΅-[TSLocationManager setPace:] 0
2022-02-22 10:27:23.578 πΎ-[TSLocationManager startUpdatingLocation] Location-services: ON
2022-02-22 10:27:23.591 βΉοΈ+[LocationAuthorization run:onCancel:] status: 3
2022-02-22 10:27:23.591 β
-[BackgroundTaskManager stopBackgroundTask:]_block_invoke 29 OF (
29,
31
)
2022-02-22 10:27:23.599
π<+27.72404340,+85.32217098> +/- 30.01m (speed 1.05 mps / course 156.20) @ 22/02/2022, 10:27:22 Nepal Time
2022-02-22 10:27:23.599
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSLocationManager locationManager:didUpdateLocations:] Enabled: 1 | isMoving: 0 | df: -1.0m | age: 1.0s
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:27:23.600 β
-[TSLocationManager locationManager:didUpdateLocations:] Acquired motionchange position: <+27.72404340,+85.32217098> +/- 30.01m (speed 1.05 mps / course 156.20) @ 22/02/2022, 10:27:22 Nepal Time
2022-02-22 10:27:23.600 π΅-[TSGeofenceManager didBecomeStationary:] TSGeofenceManager became stationary with outstanding loitering timers. Firing all loitering geofences
2022-02-22 10:27:23.600
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSGeofenceManager fireGeofenceEvent:] π’DWELL Geofence: TEST-TERTIARY
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:27:23.601 β
-[TSGeofenceManager fireGeofenceEvent:] INSERT: 552EB2F1-CC7B-4154-B309-445DD409118C
2022-02-22 10:27:23.601
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSHttpService flush:]
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:27:23.601
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSHttpService finish:error:] Success: 0
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:27:23.602 π΅-[TSLocationManager startMonitoringStationaryRegion:radius:] Radius: 1000
2022-02-22 10:27:23.602 π΄-[TSLocationManager stopUpdatingLocation]
2022-02-22 10:27:23.602 π΅-[TSLocationManager calculateMedianLocationAccuracy:] Median location accuracy: 45.0
2022-02-22 10:27:23.603
π<+27.72404340,+85.32217098> +/- 30.01m (speed 1.05 mps / course 156.20) @ 22/02/2022, 10:27:22 Nepal Time
2022-02-22 10:27:23.603
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSGeofenceManager evaluateProximity:] Found 2 / 2 within 2000 m
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:27:23.607
π<+27.72404340,+85.32217098> +/- 30.01m (speed 1.05 mps / course 156.20) @ 22/02/2022, 10:27:23 Nepal Time
2022-02-22 10:27:23.607
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSLocationManager locationManager:didUpdateLocations:] Enabled: 1 | isMoving: 0 | df: 10.0m | age: 0.0s
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:27:23.607 π΅-[TSLocationManager calculateMedianLocationAccuracy:] Median location accuracy: 37.5
2022-02-22 10:27:23.609
π<+27.72404340,+85.32217098> +/- 30.01m (speed 1.05 mps / course 156.20) @ 22/02/2022, 10:27:23 Nepal Time
2022-02-22 10:27:23.609
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSGeofenceManager evaluateProximity:] Found 2 / 2 within 2000 m
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:27:23.610 β
-[BackgroundTaskManager stopBackgroundTask:]_block_invoke 31 OF (
31
)
2022-02-22 10:27:26.969
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSLocationManager stop]
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:13.809
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSGeofenceManager fireGeofenceEvent:] π’ENTER Geofence: TEST
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
2022-02-22 10:26:16.640 πΎ-[TSGeofenceManager startMonitoringGeofence:] TEST-TERTIARY
2022-02-22 10:27:23.600
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β -[TSGeofenceManager fireGeofenceEvent:] π’DWELL Geofence: TEST-TERTIARY
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
So here we can see that the loitering delay was set to 900s but it was fired after less than 1 min after start monitoring for the geofence TEST-TERTIARY
TSGeofenceManager became stationary with outstanding loitering timers. Firing all loitering geofences
The plugin is designed to do this. If it did not fire dwell
events when the plugin becomes stationary, it could not fire them at all.
Try this: create a geofence several hundred meters away from your current location. Go outside and walk into it with the plugin configured with debug: true
(so you can hear and see debug notifications).
Well i was walking the whole time and i didnt let the screen turn off. Do you find any possible reasons why the TSGeofenceMamanger became stationary ?
Also it seemed that the dwell event was fired after the phone detected location change or something (the location icon was shown in the statusbar before the event was fired).
Actually the use case is to implement infinite geofencing and then track the location of the user on dwell after 15 mins. While implementing this as well i got the same result. The dwell event was fired in less time if the device is moving but it fires on time if the device is stationary.
any updates on this @christocracy ? were you guys able to replicate the issue ?
were you guys able to replicate the issue ?
Yes. There is a logic problem in geofencing-only mode .startGeofences()
with dwell
events. I have no estimate on fix date.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. You may also mark this issue as a "discussion" and I will leave this open.
@christocracy any updates on this ?