Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Help Wanted]: Optimal Configuration for Background Location Tracking (Accuracy Similar to Strava/AllTrails) #304

Open
3 tasks done
chrisbiscuit opened this issue Feb 3, 2025 · 8 comments

Comments

@chrisbiscuit
Copy link

chrisbiscuit commented Feb 3, 2025

Required Reading

  • Confirmed

Plugin Version

6.0.3

Mobile operating-system(s)

  • iOS
  • Android

What do you require assistance about?

Optimal Configuration for Background Location Tracking (Accuracy Similar to Strava/AllTrails Mobile Apps)

Issue Description

We are using your Capacitor geolocation plugin and are trying to optimize our configuration to achieve tracking accuracy similar to mobile apps like Strava or AllTrails (not their companion devices like watches).

Current Issue

Our app tracks walks, but we’ve noticed that when a user is stationary for about 15 minutes and then starts moving again, the app stops recording new coordinates in the background. Later, when the app is reopened, tracking resumes, but we see a long straight line on the map from the last recorded location to the new one.

Screenshot 1: Our app (with tracking gap and straight line)

Image

Screenshot 2: AllTrails (tracking properly in the background)

Image

Desired Behavior

We would like the app to continue tracking movement even when in the background, ensuring a complete and accurate route is recorded without gaps.

Questions

  1. What settings would you recommend to achieve real-time, uninterrupted tracking similar to Strava or AllTrails?
  2. Are there any additional configurations (e.g., motion-detection, pauses, location update intervals) that would prevent the tracking from stopping when stationary?
  3. Is there a way to ensure that when the app is in the background, it continues receiving location updates without interruption?

[Optional] Plugin Code and/or Config

export const GEO_CONFIG_INIT: Config = {
  desiredAccuracy: BackgroundGeolocation.DESIRED_ACCURACY_HIGH,
  locationAuthorizationRequest: 'WhenInUse',
  debug: false,
  showsBackgroundLocationIndicator: true,
  backgroundPermissionRationale: {
    title: 'Background location tracking',
    message: 'We need to track your location in the background to accurately track your walk',
  },
  notification: {
    title: 'X tracking',
    text: 'Tracking your walk',
  },
  activityType: BackgroundGeolocation.ACTIVITY_TYPE_FITNESS,
  startOnBoot: true,
  logMaxDays: 1,
  logLevel: BackgroundGeolocation.LOG_LEVEL_DEBUG,
  stopOnTerminate: false,
  heartbeatInterval: 60,
  maxDaysToPersist: 2,
};

[Optional] Relevant log output

@christocracy
Copy link
Member

mobile apps like Strava or AllTrails

Those apps have a [Start Tracking] button, like a "Jogging App" would do.

You can do the same using the method .changePace(true) to manually toggle the plugin into the moving state.

await BackgroundGeoloction.start();
await BackgroundGeolocaiton.changePace(true);

@christocracy
Copy link
Member

Config.stopTimeout still applies. When stopTimeout expires, the plugin will automatically call .changePace(false) upon itself. Eg: the user sits down for lunch.

It's up to you to configure stopTimeout as-desired (default is 5 min).

@chrisbiscuit
Copy link
Author

Thanks for your response. Our app tracks walks when the user clicks a "Start" button and we already use BackgroundGeolocation.start() and BackgroundGeolocation.changePace(true) when a user begins their walk.

To clarify our issue occurs when:

  1. A user starts a walk, and tracking works fine.
  2. The user sits stationary for say 15–20 minutes, and the app stops logging locations in the background.
  3. When the user resumes walking (without interacting with the app), tracking doesn’t record the resumed movement in real-time. Later, when the user opens the app to stop the walk, there’s a gap in the recorded route. This gap appears as a straight line between the last logged point (before the stationary period) and the next logged point (when the app resumes tracking).

We want the app to continue logging locations in the background after extended stationary periods, ensuring the route is complete without gaps. Tracking should seamlessly resume when the user starts moving again.

Does the plugin support that? If so, how can we configure it for this behaviour?

@christocracy
Copy link
Member

You're free to set stopTimeout as high as you wish in order to prevent the plugin entering the stationary state. The default is 5 minutes.

It's up to you to present the user with a [Stop Workout] button.

@chrisbiscuit
Copy link
Author

Thanks. I have a couple of follow-up questions:

  1. Do you recommend using heartbeatInterval to keep the app alive during extended stationary periods?
    I've also tried the following:
 BackgroundGeolocation.onHeartbeat(async () => {
        await BackgroundGeolocation.getCurrentPosition({
          samples: 1,
          persist: true,
        });
      });
  1. Your documentation mentions:

"⚠️ Setting a value > 15 min is not recommended, particularly for Android."

What happens if we set stopTimeout to a value greater than 15 minutes? Will it cause issues on Android and if so, what are the best practices to avoid those issues?

@christocracy
Copy link
Member

Do you recommend using heartbeatInterval to keep the app alive during extended stationary periods?

No.

What happens if we set stopTimeout to a value greater than 15 minutes?

It obviously consumes more energy keeping location services ON. If that’s what you want, that’s fine.

@chrisbiscuit
Copy link
Author

Thanks. I’ve been exploring how to use DistanceFilter with Elasticity for different activities and had some additional questions:

Context:

I would like to track location updates with the following requirements:

  1. For on_foot activity:
    • Precise tracking every 5 meters, disabling elasticity for consistent updates.
  2. For in_vehicle or on_bicycle activities:
    • Use the plugin's elasticity calculations with a DistanceFilter and ElasticityMultiplier.

Example:

Here is an example of what I'm considering based on your documentation for DistanceFilter:

BackgroundGeolocation.onActivityChange((event) => {
  let config = {};

  if (event.activity === 'on_foot') {
    config = {
      distanceFilter: 5, // Fixed distance for walking
      elasticityMultiplier: 0, // Disable elasticity
    };
  } else if (event.activity === 'in_vehicle' || event.activity === 'on_bicycle') {
    config = {
      distanceFilter: 30, // Base distance for elasticity
      elasticityMultiplier: 1.0,
    };
  } else if (event.activity === 'in_vehicle' && event.confidence > 75) {
    // Example for highway speed (27 m/s)
    config = {
      distanceFilter: 50, // Initial filter
      elasticityMultiplier: 1.0, // Elastic adjustment
    };
  }

  BackgroundGeolocation.setConfig(config);
});

Questions:

  1. Is it feasible to dynamically update DistanceFilter and ElasticityMultiplier based on detected activity using onActivityChange?
  2. Are there any best practices or potential pitfalls when dynamically changing these settings during activity changes?

@christocracy
Copy link
Member

  1. Yes. But see api docs Config.disableElasticity
  2. no. It’s fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants