transistorsoft / cordova-background-geolocation-lt

The most sophisticated background location-tracking & geofencing module with battery-conscious motion-detection intelligence for iOS and Android.
http://www.transistorsoft.com/shop/products/cordova-background-geolocation
Other
656 stars 277 forks source link

Geofencing and location updates #1418

Closed ageissel closed 6 days ago

ageissel commented 7 months ago

Your Environment

Expected Behavior

We recently added support to allow the user to configure a Geofence which acts as an automatic start / stop zone for recording a walk or cycle.

Manual start function is called as follows


      subscriptionLocation.current = driver.onLocation(_locationReceived);

      if(!driverStarted.current) driver.start()
        .then(()=>{ driverStarted.current = true; })
        .then(()=>driver.destroyLocations())
        .then(()=>setTrackingActive(true))
        .then(()=>updateTrackedLocations([ 'STARTED' ]))
        .then(()=>driver.resetOdometer())
        .then(()=>driver.changePace(true))
        .catch((reason)=>{
          if (process.env.NODE_ENV !== 'production') console.log('catch', reason);
        });

starting from geofence is equivalent, but requests 3x locations to check that activity.type !== in_vehicle before actively tracking locations

Whether from a manual start or when exiting a start/stop geofence, positions reported to onLocation are stored in memory, persisted to localStorage and converted to a GeoJSON structure and displayed on a leaflet.js map. This should continue until the user stops tracking or when entering a start/stop geofence.

When the app is resumed after an unload event, stored locations are retrieved and processed before regular tracking resumes, as follows:


        subscriptionLocation.current = driver.onLocation(_locationReceived);

        if(!driverStarted.current) driver.getLocations()
          .then((locations)=>{
            _locationReceived(locations);
            return driver.destroyLocations();
          })
          .then(()=>driver.start())
          .then(()=>{ driverStarted.current = true; })
          .then(()=>setTrackingActive(true))
          .then(()=>updateTrackedLocations([ 'STARTED' ]))
          // .then(()=>setDriverBooting(false))
          .then(()=>driver.changePace(true))
          .catch((reason)=>{
            if (process.env.NODE_ENV !== 'production') console.log('catch', reason);
          });

On iOS, this works consistently, for extended periods of time, resuming cleanly even if the App was unloaded from memory.

Actual Behavior

On Android, the app appears to resume, but it seems as if there are two competing location notification processes at play. When a new location is available, the entire route will briefly flash, before displaying only the position at which the app was resumed.

Internally, we rely on react useEffect(...) and useReducer(...) to manage subscription to the plugin, processing of the location and onward communication. I'm aware that a debug react build will always call useEffect (and other hooks) twice to highlight side-effects. However, both in debugging and in release, the iOS version behaves as expected, but on Android we see this duality.

We also tested a debug build using Lockito, and it seems to run as expected, but also have not seen the App unload in the same manner as when testing in the field.

Steps to Reproduce

The challenge is that it seems to be related to a release build. Debug builds appear to operate as intended, although we will also continue our attempts to isolate into a reproducible behaviour.

1. 2. 3. 4.

Context

We are mirroring our understanding of the state of the plugin through localStorage, calling startGeofence() if needed after the ready() call, and resuming (our definition) location tracking using start() if a previous session, otherwise waiting for the user to start a recording session or triggered by a geofence, as above.

More of a question, or validation - are we using the plugin correctly, specifically for the use case of manually starting a session and then potentially starting another session as a result of triggering a geofence event? Is there a possibility where two instances of the background service are active?

Help and suggestions very welcome. And thank you Chris for a very useful plugin.

Debug logs

Logs ``` PASTE_YOUR_LOGS_HERE ```
github-actions[bot] commented 2 weeks ago

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

github-actions[bot] commented 6 days ago

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