02 – Location cache (quick positioning restart)

In wayfinding applications, you may not want to keep your application positioning all the time. Imagine this situation:  the user opens the map and you start positioning,  then she closes it and you a stop, but just after a few seconds, she opens the app again and you need to start positioning. 

The problem is that each time Situm SDK will need to start positioning from scratch after each re-start, therefore requiring a few seconds each time to provide an accurate location. For the user, this makes no sense: after all, she was perfectly located a few seconds ago, and she didn’t move!

To solve this issue, Situm SDK provides an option that can be activated using the method LocationRequest.Builder.useLocationsCache (Android) or SITLocationRequest.useLocationsCache (iOS). In essence, this option saves the last know location in the smartphone’s cache and uses it at a hint when you start positioning, provided that this last known location is not older than 30 seconds.

Expected behaviour #

If the user did not move significantly since the last stop, Situm SDK will provide a first accurate location almost immediately. Otherwise, behaviour may change as described in the following table.

User moved from last stored locationExpected behaviour
0 meters – 5 metersAn accurate location will be provided immediately
10 meters-20 metersAn approximate location will be provided immediately (error = 10-20 meters). It will regain the usual accuracy after a few seconds, specially if the user moves
20-50 metersA not so accurate location will be provided immediately (error = 20-50 meters). Situm SDK will probably try to geolocate the user again from scratch, resulting in a behaviour similar to what’s expected when this option is not active.

The user may also change her orientation since the last know location. This table describes what to expect in this case:

User orientation changed from last stored locationSmartphone has a working compass (calibrated)Expected behaviour
User does not change orientation or turns right/left less than 45 degreesYesAn accurate orientation will be provided quickly.
NoOrientation will be accurate enough very quickly (+-45 degrees of maximum error).
OtherwiseYesAn inaccurate orientation (error over +-45 degrees) will be provided at first. Situm SDK will re-compute an accurate orientation in a few seconds.
NoAn inaccurate orientation (error over +-45 degrees) will be provided at first. In order to achieve better accuracy, user may have to walk around.

How to use it: code example #

The following code example shows how to use this method. In this example, we create two buttons to Start and Stop the positioning system (just for the sake of the example). The buttons are defined in your activity_main.xml file:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- Start Button -->
    <Button
        android:id="@+id/button_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginStart="10dp"
        android:layout_marginTop="10dp"
        android:text="Start"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <!-- Stop Button -->
    <Button
        android:id="@+id/button_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:layout_marginEnd="10dp"
        android:text="Stop"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Then, in your MainActivity.java

package com.example.situmsdkbasicapp;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;


import es.situm.sdk.SitumSdk;
import es.situm.sdk.location.LocationListener;
import es.situm.sdk.location.LocationRequest;
import es.situm.sdk.location.LocationStatus;
import es.situm.sdk.model.location.Location;
import es.situm.sdk.error.Error;



public class MainActivity extends AppCompatActivity {

    private static final String TAG = MainActivity.class.getSimpleName();
    private Button buttonStart, buttonStop;

    private LocationListener locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            Log.i(TAG, "onLocationChanged() called with: location = [" + location + "]");
        }

        @Override
        public void onStatusChanged(@NonNull LocationStatus status) {
            Log.i(TAG, "onStatusChanged() called with: status = [" + status + "]");
        }

        @Override
        public void onError(@NonNull Error error) {
            Log.e(TAG, "onError() called with: error = [" + error.getMessage() + "]" + " and code = ["+error.getCode() + "]");
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //Initializes Situm SDK
        SitumSdk.init(this);

        //Creates the LocationRequest with the Locations Cache activated
        final LocationRequest locationRequest = new LocationRequest.Builder().useLocationsCache(true).build();

        //Start Button: starts positioning
        buttonStart = (Button) findViewById(R.id.button_start);
        buttonStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!SitumSdk.locationManager().isRunning()) SitumSdk.locationManager().requestLocationUpdates(locationRequest, locationListener);
            }
        });

        //Stop Button: stops positioning
        buttonStop = (Button) findViewById(R.id.button_stop);
        buttonStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (SitumSdk.locationManager().isRunning()) SitumSdk.locationManager().removeUpdates(locationListener);
            }
        });
    }
}

Execution #

If you build & run this example, your application log should look like this:

2021-04-10 13:41:48.190 onStatusChanged() called with: status = [CALCULATING]
2021-04-10 13:41:51.196 onStatusChanged() called with: status = [STARTING]
2021-04-10 13:41:52.292 onLocationChanged() called with: location = [Location{provider='SITUM_PROVIDER', deviceId=724614936937, timestamp=1618054912258, position=Point{buildingIdentifier='-1', floorIdentifier='-1', cartesianCoordinate=CartesianCoordinate{x=0.00, y=0.00}, coordinate=Coordinate{latitude=43.356493, longitude=-8.413401}, isOutdoor=true}, quality=HIGH, accuracy=22.846, cartesianBearing=Angle{radians=0.00, degrees=0.00}, bearing=Angle{radians=0.00, degrees=0.00}, bearingQuality=HIGH, customFields={}}]

....

2021-04-10 13:42:02.034 onLocationChanged() called with: location = [Location{provider='SITUM_PROVIDER', deviceId=724614936937, timestamp=1618054921993, position=Point{buildingIdentifier='6541', floorIdentifier='13483', cartesianCoordinate=CartesianCoordinate{x=14.02, y=8.57}, coordinate=Coordinate{latitude=43.356419, longitude=-8.413083}, isOutdoor=false}, quality=HIGH, accuracy=2.5115864, cartesianBearing=Angle{radians=3.06, degrees=175.46}, bearing=Angle{radians=4.79, degrees=274.54}, bearingQuality=LOW, customFields={}}]

At this point, Situm SDK has converged to an accurate location in building 6541, floor 13483, latitude 43.356419 and longitude -8.413083. If you hit the Stop button, Situm SDK will stop but, if you hit the Start button again (before 30 seconds), the last known location will be used at startup again.

2021-04-10 13:42:02.280 onStatusChanged() called with: status = [STOPPED]
2021-04-10 13:42:04.630 onStatusChanged() called with: status = [CALCULATING]
2021-04-10 13:42:05.686 onStatusChanged() called with: status = [STARTING]
2021-04-10 13:42:07.691 onLocationChanged() called with: location = [Location{provider='SITUM_PROVIDER', deviceId=724614936937, timestamp=1618054927396, position=Point{buildingIdentifier='6541', floorIdentifier='13483', cartesianCoordinate=CartesianCoordinate{x=14.02, y=8.57}, coordinate=Coordinate{latitude=43.356419, longitude=-8.413083}, isOutdoor=false}, quality=LOW, accuracy=0.0, cartesianBearing=Angle{radians=3.06, degrees=175.46}, bearing=Angle{radians=4.79, degrees=274.54}, bearingQuality=LOW, customFields={}}]
...

Notice that the last know location is exactly repeated in the first geolocations provided by the SDK after the re-start, in just a few seconds. After a few seconds, the SDK starts integrating sensor data as usual and new locations will be computed. 

Subscribe to our newsletter

BASIC INFORMATION ON DATA PROTECTION

Data controller: SITUM TECHNOLOGIES, S.L.
Contact: Data controller: situm@situm.es
Responsible for protection: dpo@situm.es
Purpose and legal basis: To manage the sending of SITUM newsletters only with consent.
Legitimation: Express consent of the interested party.
Recipients: The data will not be passed on to third parties with the exception of legal obligations.
Retention period: As long as the interested party remains subscribed to the newsletter (a link to unsubscribe will be available in each newsletter sent by Situm).
Rights: The interested party may at any time revoke their consent, as well as exercise their rights of opposition, access, conservation, rectification, limitation, deletion of data and not be subject to a decision based only on automated data processing, by writing to SITUM at the addresses indicated.
Additional Information: You can consult additional and detailed information on Data Protection in our privacy policy.

Please, download your copy here

Thank you for downloading our whitepaper. Please do not hesitate to contact us if you would like to know more about how our solutions can help your business. Download whitepaper


Close window