Indoor and/or outdoor positioning is probably the most basic, and at the same time the most important functionality you want to achieve with Situm. 


The following code snippet shows you how to get a basic indoor/outdoor positioning application up & running.   For simplicity, we have bundled everything together in the MainActivity.


public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();

    //First, declare a LocationListener. This will receive the computed geolocations, status changes and errors
    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 + "]");
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //Initialize Situm SDK
        SitumSdk.init(this);

        //Ask for runtime permissions (ACCESS_FINE_LOCATION)
        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},0);

        //Build the LocationRequest with default parameters
        LocationRequest locationRequest = new LocationRequest.Builder().build();

        //Start positioning! -> Geolocations will be passed to the locationListener callbacks
        SitumSdk.locationManager().requestLocationUpdates(locationRequest, locationListener);

    }
}


As you can see, a few classes work together in order to compute the smartphone geolocation.  The LocationManager  is the main entity handling all the positioning tasks. Its most important method is the requestLocationUpdates, which will receive an instance of a  LocationRequest and a LocationListener implementation. After that, positioning will start.


On the one hand, the LocationRequest allows you to configure the positioning parameters: Building vs Global, whether or not to use WiFi or BLE, etc.  In this example, no parameters are configured (therefore the default configuration will be used). On the other,  the LocationListener interface allows you to receive and respond to all the generated geolocations, as well as to other useful information (status and errors).


In order to stop the positioning,  just call the method removeUpdates. You may want to check if positioning is actually running before you stop it, by calling the isRunning method.



Running the code


If you build & execute the previous code, your application will produce a log similar to the following one.  


Initialization


2021-02-06 00:49:14.441 2592-2592/com.example.androidtestapp I/MainActivity: onStatusChanged() called with: status = [CALCULATING]

2021-02-06 00:49:15.535 2592-2592/com.example.androidtestapp I/MainActivity: onStatusChanged() called with: status = [STARTING]

Take a moment to examine what's going on. At first, the onStatusChanged method is called to inform that the Situm SDK is in status "CALCULATING". Then, it is called again to inform that is is in status "STARTING". 


First Outdoor geolocations


After a few moments, the positioning will start. Behind the scenes, Situm will try to detect if you are within a building that has been configured with Situm technology.  Meanwhile,  Situm will compute your outdoor geolocations. If you open the RealTime Panel, you should see your geolocation on the world!


 

If you inspect the log lines, you will see very interesting information.

2021-02-06 00:49:16.567 2592-2592/com.example.androidtestapp I/MainActivity: onLocationChanged() called with: location = [Location{provider='SITUM_PROVIDER', deviceId=356655406358, timestamp=1612568956544, position=Point{buildingIdentifier='-1', floorIdentifier='-1', cartesianCoordinate=CartesianCoordinate{x=0,00, y=0,00}, coordinate=Coordinate{latitude=43,356441, longitude=-8,413430}, isOutdoor=true}, quality=HIGH, accuracy=20.287, cartesianBearing=Angle{radians=0.00, degrees=0.00}, bearing=Angle{radians=0.51, degrees=29.44}, bearingQuality=HIGH, customFields={}}]


Let's examine this line in detail:

  1. The location provider is SITUM_PROVIDER. This is just an internal parameter.
  2. The deviceId is the identifier of the device that is running the application.
  3. The timestamp is the current Unix Timestamp, in milliseconds since since Jan 01 1970 (UTC).
  4. Position is an object that represents the smartphone location. In this case:
    1. buildingIdentifier and floorIdentifier are equals to "-1". This means that the user is not within a known building or floor, therefore the location is an outdoor location.
    2. cartesianCoordinate should be the cartesian location within a building's floorplan, but since we are dealing with an outdoor location, it is equals to {x=0.00, y=0.00} (default value).  
    3. coordinate is equals to {latitude=43.356441, longitude=-8.413430}. This are the location coordinates in WSG 84 format.
    4. isOutdoor=true. Again, this indicates that we are dealing with an outdoor location.
  5. Although quality is HIGH, you should not pay attention to this: this parameter refers to the quality of indoor locations, and as we have seen, this is an outdoor location.
  6. Accuracy is 20.287. This is the approximate error radius within which the smartphone location is. When producing outdoor locations (like this one), this number is provided by the smartphone GPS provider.
  7. cartesianBearing should be the cartesian orientation with respect to the bulding's axis, but since we are dealing with an outdoor location, it is equals to {radians=0.00, degrees=0.00}.
  8. bearing is the orientation with respect to the Earth North. In this case, it is equals to {radians=0.51, degrees=29.44}.
  9. Although bearingQuality is HIGH, you should not pay attention to this: this parameter refers to the quality of the cartesianBearing, and as we have seen, this value is not available since we are dealing with an outdoor location.
  10. customFields is JSON dictionary that may contain key-value tuples. It is empty in this case. 


First Outdoor geolocations

If you are inside of a building where you have configured Situm technology, at some point Situm will detect it and start computing your indoor geolocation. If you open the RealTime Panel, you will see see your indoor geolocation within the building.



 Again, you may inspect the log lines.

2021-02-06 01:14:47.319 2592-2592/com.example.androidtestapp I/MainActivity: onLocationChanged() called with: location = [Location{provider='SITUM_PROVIDER', deviceId=356655406358, timestamp=1612570486718, position=Point{buildingIdentifier='6541', floorIdentifier='13483', cartesianCoordinate=CartesianCoordinate{x=17,50, y=10,20}, coordinate=Coordinate{latitude=43,356433, longitude=-8,413040}, isOutdoor=false}, quality=HIGH, accuracy=0.70591295, cartesianBearing=Angle{radians=1.66, degrees=95.19}, bearing=Angle{radians=6.19, degrees=354.81}, bearingQuality=HIGH, customFields={}}]


You may notice that:

  1. Position is now an indoor geolocation:
    1. buildingIdentifier is assigned to "6541", which corresponds to the building identifier where the user is. 
    2. floorIdentifier is assigned to "13483", which corresponds to the floor identifier where the user is.
    3. cartesianCoordinate now specifies the specific 2D location of the user within the building in cartesian coordinates. coordinate specifies that same location, but converted to the WSG84 latitude-longitude.
    4. isOutdoor now indicates that the user is not outdoors.
  2. Quality is HIGH. Now you may take it into account, since it represents the indoor location quality (and we are dealing with an indoor location).
  3. Accuracy is 0.70591295. This is the approximate error radius within which the smartphone location is. When producing indoor locations (like this one), this number is computed by Situm system.  
  4. cartesianBearing is {radians=1.66, degrees=95.19}, representing the cartesian orientation with respect to the bulding's axis.
  5. bearing is the orientation with respect to the Earth North. In this case, it is equals to {radians=6.19, degrees=354.81}.
  6. bearingQuality is HIGH. Now you may take it into account, since it represents the cartesianBearing quality (and we are dealing with an indoor location).




That's it! You have developed an application that is able to track your indoor & outdoor smartphone's location, anywhere in the world.