# Capture GPS Locations

GPS locations can be captured in the foreground (i.e. the user can see that the location is being captured), in the background using the [`capture-coordinates`](https://docs.journeyapps.com/reference/build/ui-components/all-ui-components/capture-coordinates) component or recorded over time as a [track](#recording-gps-tracks).

To use the `capture-coordinates` component, you need to define a field or variable with type [location](https://docs.journeyapps.com/reference/build/data-model-configuration/model/field#gps-location-location).

To record GPS tracks you need to define a field with type [track](https://docs.journeyapps.com/reference/build/data-model-configuration/model/field#gps-track-track).

### Capture a single GPS location

To capture a single GPS location in the foreground or background, please refer to the documentation on `capture-coordinates`:

{% content-ref url="../build/ui-components/all-ui-components/capture-coordinates" %}
[capture-coordinates](https://docs.journeyapps.com/reference/build/ui-components/all-ui-components/capture-coordinates)
{% endcontent-ref %}

### Accessing GPS Information from JavaScript/TypeScript or Format Strings

These properties of a GPS location variable or field can be accessed from JavaScript/TypeScript and [Format Strings](https://docs.journeyapps.com/reference/app-features/xml-format-strings), but cannot be modified:

* `latitude`
* `longitude`
* `altitude`
* `horizontal_accuracy`
* `vertical_accuracy`
* `timestamp`

{% hint style="warning" %}
**Limitation**

Capturing the `altitude` and/or `vertical_accuracy` is not supported on several platforms / devices, including Android devices. These devices will return `null` for these fields.
{% endhint %}

#### Example — Accessing GPS Information from JavaScript

```javascript
function update_coordinates() {
    if (view.current_location == null) {
        dialog("Location", "Unknown");
    } else {
        dialog("Location", "" + view.current_location.latitude + ", " + view.current_location.longitude);
    }
}
```

#### Example — Accessing GPS Information from Format Strings

```xml
<table>
    <info label="Latitude" bind="current_location.latitude" />
    <info label="Longitude" bind="current_location.longitude" />
    <info label="Horizontal Accuracy" bind="current_location.horizontal_accuracy" />
</table>
```

### Recording GPS Tracks

{% hint style="info" %}
**Version compatibility**

The GPS tracking feature was introduced in version **4.6** of the JourneyApps Container for Android and iOS.

A custom branded container is necessary for this feature. Please contact [JourneyApps Support](mailto:support@journeyapps.com) to request one.
{% endhint %}

GPS tracks are recorded to a data model field of type [track](https://docs.journeyapps.com/reference/build/data-model-configuration/model/field#gps-track-track).

The `Track.start({'highFrequency': true})` method will start a track in high-frequency update mode (maximum update rate of 10 seconds) and return the track ID which should be saved to a field of type [`track`](https://docs.journeyapps.com/reference/build/data-model-configuration/model/field#gps-track-track). Calling `Track.start({'highFrequency': false})` will record in low-frequency update mode (maximum update rate of 1 minute).

The `Track.stop()` method will stop the track recording.

The `Track.isTracking()` method will return a `boolean`, indicating if a track is in progress.

{% hint style="warning" %}
**Common background tracking issues**

Background tracking may not work in the following cases:

* The correct permissions to track location in the background have been disabled.
* If the app is "force-closed" or the OS has closed the app in the background. I.e. the app is no longer running in the background.
* The device has a form of battery saver mode enabled.
  {% endhint %}

{% hint style="info" %}
**A note on the location update rate**

The OS of the device determines how often locations GPS location updates are sent to JourneyApps.&#x20;

If the device's location has not changed, it might not report a new location. This is why the interval between locations on a track often varies and is not exactly 10 seconds or 1 minute.
{% endhint %}

#### Example — Recording GPS Tracks

The following example shows how to start and stop GPS track recording.

Data model XML:

{% code title="schema.xml" %}

```xml
<model name="session" label="Session">
    <field name="track_session" label="GPS Track" type="track"/>
    <field name="start_time" label="Start Time" type="datetime"/> <!-- informational -->
    <field name="high_frequency" label="High Frequency" type="boolean" /> <!-- informational -->
    <display>{start_time}</display>
</model>
```

{% endcode %}

View XML:

{% code title="main.view\.xml" %}

```xml
<view title="Track">
    <var name="session" type="session"/>
    
    <button label="Start Tracking" on-press="startTracking()"/>
    <button label="Stop Tracking" on-press="stopTracking"/>
    <button label="Is Tracking?" on-press="isTracking"/>
    
    <button label="Close" validate="false" on-press="dismiss()"/>
</view>
```

{% endcode %}

View JavaScript:

{% code title="" %}

```javascript
function startTracking() {
  var highFrequency = true; // set to false for low frequency tracking
  var t0 = new Date();
  view.session = DB.session.create({
      start_time: t0,  // informational
      high_frequency: highFrequency // informational
  });
  var opts = {
      'highFrequency': highFrequency
  };
  var trackId = Track.start(opts);
  view.session.track_session = trackId;
  view.session.save()
}

function stopTracking() {
    if (!Track.stop()) {
        dialog('error','unable to stop tracking');
    }
}

function isTracking() {
    var t = Track.isTracking();
    if (t === true) {
        dialog('tracking? yes');
    } else if t === false) {
        dialog('tracking? no');
    } else {
        dialog('','unknown');
    }
}
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.journeyapps.com/reference/app-features/gps-capturing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
