02 – Initialization & common configurations

Previously, we’ve learned how to create a simple app from the ground app in our Quickstart Guides. In this guide, we will dive-in in the most common configuration steps you must follow to accomplish a successful Situm integration.

Setup native projects #

We have several frameworks that you can use, but each one has different configurations that need to be done before initializing our SDK. Take a look at the “Setup native projects” section in our Quickstart Guides to learn what native Android and iOS files you need to configure for each framework.

Importing Situm SDK #

SDK Initialization #

The first step is to import & initialize Situm SDK. This does not start positioning nor retrieves any resource from Situm Platform: it just allocates the required resources for the SDK to run.

The following snippet shows you how to do it in Flutter and React Native (we recommend to do this as soon as possible on your application’s lifecycle). In Cordova the SDK initializes itself after the import, so you don’t need to take further actions.

// main.dart
import 'package:situm_flutter/sdk.dart';
...

class _MyComponent extends StatefulWidget {
  const _MyComponent();

  @override
  State<_MyComponent> createState() => __MyComponentState();
}

class __MyComponentState extends State<_MyComponent> {

  @override
  void initState() {
    SitumSdk().init();
    ...

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}
//App.js
import SitumPlugin from '@situm/react-native';
...

const App = () => {

  //Initialize Situm SDK
  SitumPlugin.init();

  ...
}
 
export default App;
// index.js
document.addEventListener("deviceready", onDeviceReady, false);

function onDeviceReady() {
  // In Cordova there is no init() method,
  // you can directly authenticate with setApiKey().
  cordova.plugins.Situm.setApiKey("SITUM_EMAIL", "SITUM_API_KEY");

  ...
}

Credentials #

After calling the init() method, you can authenticate with your APIKEY (see docs for Flutter, React Native and Cordova) as follows:

//You may use your API_KEY
SitumSdk().setApiKey("SITUM_API_KEY");
//You may use your API_KEY
SitumPlugin.setApiKey("SITUM_API_KEY")
#APIKEY based authentication
cordova.plugins.Situm.setApiKey("SITUM_EMAIL", "SITUM_API_KEY")

Please note! These init() and setApiKey() are the first methods you must call before retrieving your POIs, retrieving your geofences, starting positioning, starting navigation…

Configuring the positioning #

There are many ways you may want to configure our SDK to locate users inside your building. Maybe your building has some outdoor zones that cannot be configured with bluetooth beacons, then you may want to prioritize the use of the GPS sensor. Maybe your building is calibrated with both wifi signals and bluetooth beacons, then you must use both wifi and bluetooth sensors.

There are many ways you can configure our positioning system. Take a look at the geolocation mode that best fits your use case, and then configure your positioning configuration before continuing.

Request the permissions #

Situm positioning system uses the device sensors data to compute geolocation, so you must request the appropriate permissions in Android and iOS.

Android #

In Android, you will need to declare the ACCESS_FINE_LOCATION in your AndroidManifest.xml and request it. If your building is calibrated with BLE beacons, you will also need to request BLUETOOTH_SCAN & BLUETOOTH_CONNECT. Finally, you can optionally request the POST_NOTIFICATIONS permission to display to the user the Situm foreground service notification.

PermissionDescription
ACCESS_FINE_LOCATIONRequired to positioning with every geolocation mode Situm provides.
BLUETOOTH_SCANTo scan BLE in Android 12 and above.
BLUETOOTH_CONNECTTo turn BLE ON/OFF in Android 12 and above.
POST_NOTIFICATIONS (OPTIONAL)Allows to push our foreground service notification inside the notification drawer in Android 13 and above.

If not granted, user won’t be able to know that we are running on the background. Nevertheless, notices pertaining to these foreground services will still be visible in the Task Manager, irrespective of the user’s decision on the notification permission. See Android docs for more info.

iOS #

As in Android, iOS apps running Situm will need certain permissions. These permissions can be configured from XCode tab “Settings/Info”, by creating the following keys:

PermissionDescription
NSLocationAlwaysAndWhenInUseUsageDescription. In XCode: “Privacy – Location Always and When In Use Usage Description”.Required to positioning with every geolocation mode Situm provides.
NSLocationWhenInUseUsageDescription. In XCode: “Privacy – Location When In Use UsageRequired to positioning with every geolocation mode Situm provides.

You will also need to add a description to each key, which will be shown to the user at the time the app request each specific permission. For example, to ask for Location usage you can add the key “NSLocationWhenInUseUsageDescription” with the description “Location is required to find out where you are”

When to request permissions #

After declaring the necessary permissions and importing our SDK in your project, you will need to ask for permission to the user. You should request these permissions right before starting positioning and locating the user in your building. Here are a couple of examples:

  • As soon as the app opens: You can request this permissions at the very first moment the user enters the app. This way, you will be able to request location updates from the device as soon as posible. Keep in mind that the users of your app may not understand why his device location is required at this moment.
  • When displaying the map: Once the user opens our Map Viewer for wayfinding, you may want to locate him inside your building and, beforehand, requesting the permissions.

Please note! Please follow our Quick Start Guides and learn in more detail how to request the permissions for each framework in their code snippets section (Android, iOS, Flutter, React Native, Cordova, Capacitor). Remember to install the required packages specified in the guides code snippets.

Enable the sensors #

Situm does require the location and bluetooth sensors of your device enabled to work properly.

NOTE: (Android) Our SDK is able to enable the bluetooth sensor of the user’s device in Android < 13, you may want to implement this feature by setting the “Auto enable BLE during positioning” to true in your positioning configuration.

NOTE: (iOS) By disabling the bluetooth in the iOS control center, our SDK will keep working fine. Only make sure you have enabled the bluetooth sensor in the system preferences as we show in the image.

The users may have these sensors disabled, so detect this issue in your app and notify about these requirement to the users. Make sure you are aware of the status of these sensors to provide a well-built user experience.

Handling errors #

In case all is configured correctly and the user is within the building, you can start positioning and receiving the location of the user by the onLocationUpdate() method.

However, something might fail after starting positioning. To be able to diagnose the issue, you’ll also need to listen to the errors and statuses thrown by the onLocationError() and onLocationStatus() callbacks. So implement the following method before calling requestLocationUpdates() to correctly listen and notify all the positioning troubles your app might face:

// Implement these callbacks before calling SitumPlugin.requestLocationUpdates()
SitumSdk().onLocationUpdate((location) {
  debugPrint("""onLocationUpdate()>:
    buildingIdentifier=${location.buildingIdentifier},
    floorIdentifier=${location.floorIdentifier},
    coordiantes=${location.coordinate.latitude.toStringAsFixed(5)}, ${location.coordinate.longitude.toStringAsFixed(5)}
  """);
});
SitumSdk().onLocationStatus((status) {
  debugPrint("onLocationStatus()> $status");
});
SitumSdk().onLocationError((err) {
  debugPrint("ERR> onLocationError()> ${err.message}");
});
// Implement these callbacks before calling SitumPlugin.requestLocationUpdates()
SitumPlugin.onLocationUpdate(location => {
  console.log(
      `onLocationUpdate()>:\n` +
      `  \tbuildingIdentifier=${location.position?.buildingIdentifier},\n` +
      `  \tfloorIdentifier=${location.position?.floorIdentifier},\n` +
      `  \tcoordinates=${location.position?.coordinate.latitude.toFixed(
        5,
      )},${location.position?.coordinate.longitude.toFixed(5)}\n`
  );
});
SitumPlugin.onLocationStatus(status => {
  console.log(
    `onLocationStatus()> ${JSON.stringify(status.statusName)}`,
  );
});
SitumPlugin.onLocationError(err => {
  console.error(`ERR> onLocationError()> ${JSON.stringify(err)}`);
});
cordova.plugins.Situm.onLocationUpdate((location) => {
  console.info(
    "onLocationUpdate() > \n" +
      "\tbuildingIdentifier=" + location.buildingIdentifier + ",\n " +
      "\tfloorIdentifier=" + location.floorIdentifier + ",\n " +
      "\tcoordinates=" + location.coordinate.latitude.toFixed(5) +
      ", " + location.coordinate.longitude.toFixed(5)
  );
});
cordova.plugins.Situm.onLocationStatus((status) => {
  console.info("onLocationStatus() > " + status);
});
cordova.plugins.Situm.onLocationError((err) => {
  console.error("ERR > onLocationError() > " + err);
});
CallbackDescriptionDocumentation
onLocationUpdate()This callback returns back the user location, only if:

1. Your project is correctly configured.
2. Your positioning configuration fits the requirements of your building.
3. The user’s device is physically inside the building (or simulating its location inside it).
Android, iOS, Flutter, React Native, Cordova
onLocationStatus()This callback notifies the current status of the positioning system.

The most common ones are STARTING, CALCULATING, STOPPED and USER_NOT_IN_BUILDING.
Android, iOS, Flutter, React Native, Cordova
onLocationError()This callback notifies the posible errors that our SDK might face while trying to locate the user.

We explain the most common errors in the “Why didn’t work?” section of this guide.
Android, iOS, Flutter, React Native, Cordova

All together #

Finally, now you can start locating the users of your app in your building. You can do it by calling requestLocationUpdates(). In the following code snippet we demonstrate you all the steps of this guide together, so you can copy & paste it in your files:

import 'dart:io';
import 'package:flutter/material.dart';
// Remember that you need to install the permission_handler package
// to execute this code snippet
import 'package:permission_handler/permission_handler.dart';
import 'package:situm_flutter/sdk.dart';
import 'package:situm_flutter/wayfinding.dart';

// Input here your API key ...
const situmApiKey = "YOUR_APIKEY";
// ... and the building you want visualize
const buildingIdentifier = "YOUR_BUILDING_IDENTIFIER";

// Make logs more visible
var white = '\x1B[0m';
var green = '\x1B[32m';
var red = '\x1B[31m';

void initializeSitum(MapViewController controller, BuildContext context) async {
  var situmSdk = SitumSdk();
  situmSdk.init();
  situmSdk.setApiKey(situmApiKey);
  situmSdk.setConfiguration(ConfigurationOptions(useRemoteConfig: true));

  setPositioningCallbacks(situmSdk, context);

  await requestPermissions().then((_) {

    situmSdk.requestLocationUpdates(LocationRequest(
        buildingIdentifier: buildingIdentifier, useDeadReckoning: false));

  }).catchError((err) {
    debugPrint(
        "$red ERR> requestPermission()> ${err.toString()} $white");
  });
}

void setPositioningCallbacks(SitumSdk situmSdk, BuildContext context) {
  situmSdk.onLocationUpdate((location) {
    debugPrint("""$green onLocationUpdate()>:
      buildingIdentifier=${location.buildingIdentifier},
      floorIdentifier=${location.floorIdentifier},
      coordiantes=${location.coordinate.latitude.toStringAsFixed(5)}, ${location.coordinate.longitude.toStringAsFixed(5)}
    $white""");
  });
  situmSdk.onLocationStatus((status) {
    debugPrint("$green onLocationStatus()> $status $white");
  });
  situmSdk.onLocationError((err) {
    debugPrint("$red ERR> onLocationError()> ${err.message} $white");
  });
}

/// Example of a function that request permissions and check the result:
Future<bool> requestPermissions() async {
  var permissions = <Permission>[
    Permission.locationWhenInUse,
  ];
  if (Platform.isAndroid) {
    permissions.addAll([
      Permission.bluetoothConnect,
      Permission.bluetoothScan,
    ]);
  }
  Map<Permission, PermissionStatus> statuses = await permissions.request();
  return statuses.values.every((status) => status.isGranted);
}
// 1. Import our plugin
import SitumPlugin, {requestPermission} from '@situm/react-native';

// Call this method whenever you want to start positioning
const initializeSitum = async () => {
    // 2. Remember to initialize our SDK and authenticate
    SitumPlugin.init();
    SitumPlugin.setApiKey('YOUR_APIKEY');
    SitumPlugin.setUseRemoteConfig(true);

    // 3. Listen to all the possible errors & statuses
    SitumPlugin.onLocationStatus(status => {
      console.log(
        `onLocationStatus()> ${status.statusName}`,
      );
    });
    SitumPlugin.onLocationError(err => {
      console.error(`ERR> onLocationError()> ${JSON.stringify(err)}`);
      alert(`${err.message}`);
    });
    // 4. Request the permissions to the user,
    // then request location updates.
    //
    // WARNING! this requestPermission() request both location and bluetooth permissions in Android.
    // In case you don't use beacons in your building, create your custom method without the bluetooth permissions
    await requestPermission()
        .then(() => {
            SitumPlugin.requestLocationUpdates();
        })
        .catch(err => {
            console.error(`ERR> requestPermission()> ${JSON.stringify(err)}`);
        });
}
document.addEventListener("deviceready", onDeviceReady, false);

// Set here your credentials
const YOUR_SITUM_EMAIL = 'YOUR_EMAIL';
const YOUR_SITUM_API_KEY = 'YOUR_APIKEY';
const YOUR_BUILDING_IDENTIFIER = 'YOUR_BUILDING_IDENTIFIER';

// Make logs more visible
var white = "\x1B[0m";
var green = "\x1B[32m";
var red = "\x1B[31m";

function onDeviceReady() {
  // 1. Authenticate in our SDK.
  cordova.plugins.Situm.setApiKey(YOUR_SITUM_EMAIL, YOUR_SITUM_API_KEY);

  // 2. Set onLocationUpdate(), onLocationStatus() and onLocationError() the callbacks.
  cordova.plugins.Situm.onLocationUpdate((location) => {
    console.info(
      `${green}onLocationUpdate() > \n` +
        "\tbuildingIdentifier=" + location.buildingIdentifier + ",\n " +
        "\tfloorIdentifier=" + location.floorIdentifier + ",\n " +
        "\tcoordinates=" + location.coordinate.latitude.toFixed(5) + 
        ", " + location.coordinate.longitude.toFixed(5)
    );
  });
  cordova.plugins.Situm.onLocationStatus((status) => {
    console.info(`${green}onLocationStatus() > ` + status);
  });
  cordova.plugins.Situm.onLocationError((err) => {
    console.error(`${red}ERR > onLocationError() > ` + err);
  });

  // 3. Ask the user for permission before positioning.
  _requestPermissions(
    () => {
      cordova.plugins.Situm.requestLocationUpdates({
        buildingIdentifier: YOUR_BUILDING_IDENTIFIER,
      });
    },
    (errorMessage) => {
      console.error("ERR> ", JSON.stringify(errorMessage));
    }
  );
}

// WARNING! Remember to install the cordova.plugins.diagnostic npm package
// Permission request logic.
function _requestPermissions(successCb, errorCb) {
  var isAndroid =
    navigator.userAgent.match(/Android/i) &&
    navigator.userAgent.match(/Android/i).length > 0;
  var isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent);

  if (isAndroid) {
    cordova.plugins.diagnostic.requestRuntimePermissions(
      function (permissions) {
        console.log("EXAMPLE> permissions statuses: ", permissions);
        successCb();
      },
      function (error) {
        errorCb(JSON.stringify(error));
      },
      [
        cordova.plugins.diagnostic.permission.ACCESS_FINE_LOCATION,
        cordova.plugins.diagnostic.permission.BLUETOOTH_CONNECT,
        cordova.plugins.diagnostic.permission.BLUETOOTH_SCAN,
      ]
    );
  } else if (isIOS) {
    cordova.plugins.diagnostic.getLocationAuthorizationStatus(
      (status) => {
        if (status == "authorized") {
          successCb();
        }
      },
      () => {
        // Do nothing
      }
    );

    cordova.plugins.diagnostic.requestLocationAuthorization(
      function (status) {
        switch (status) {
          case cordova.plugins.diagnostic.permissionStatus.NOT_REQUESTED:
            errorCb("Permission not requested");
            break;
          case cordova.plugins.diagnostic.permissionStatus.DENIED_ALWAYS:
            errorCb("Permission denied");
            break;
          case cordova.plugins.diagnostic.permissionStatus.GRANTED:
            console.log("Permission granted always");
            successCb();
            break;
          case cordova.plugins.diagnostic.permissionStatus.GRANTED_WHEN_IN_USE:
            console.log("Permission granted only when in use");
            successCb();
            break;
        }
      },
      function (error) {
        errorCb(JSON.stringify(error));
      },
      cordova.plugins.diagnostic.locationAuthorizationMode.ALWAYS
    );
  }
}

After implementing these methods and executing this code in your app, you should be able to see logs with the location of the device:

Why it didn’t work? #

Here are the most common positioning troubles your app may face while locating the user inside your building:

ReasonCodesSolution
Location permission is not grantedAndroid: MISSING_LOCATION_PERMISSION
iOS:
11(kSITLocationErrorLocationAccuracy
AuthorizationStatusReducedAccuracy)
10(kSITLocationErrorLocationAuthStatusNotDetermined),
8 (kSITLocationErrorLocationDisabled)
Flutter: LOCATION_PERMISSION_DENIED
React Native: LOCATION_PERMISSION_DENIED
To fix this problem, remember to ask for the location permission before requesting location updates.

In case the user actively denied this permission, explain that we won’t be able to locate or guide him through the building without this permission.
Bluetooth permission is not grantedAndroid: MISSING_BLUETOOTH_PERMISSION
iOS: (iOS devices do no need the BLE permission)
Flutter: BLUETOOTH_PERMISSION_DENIED
React Native: BLUETOOTH_PERMISSION_DENIED
To fix this problem, remember to ask for the Bluetooth permission before requesting location updates.

In case the user actively denied this permission, explain that we won’t be able to locate or guide him through the building without this permission.
Location sensor was disabled by the userAndroid: LOCATION_DISABLED
Flutter: LOCATION_DISABLED
React Native: LOCATION_DISABLED
The user has disabled de Location sensor of his device.

Try to convice the user to enable it, so the positioning system works as expected.
Bluetooth sensor was disabled by the userAndroid: BLUETOOTH_DISABLED
iOS:
6 (kSITLocationErrorBluetoothIsOff)
Flutter: BLUETOOTH_DISABLED
React Native: BLUETOOTH_DISABLED
The user has disabled de Bluetooth sensor of his device.

Try to convice the user to enable it, so the positioning system is able to use beacons to locate the user.

User is out of the building

Android: USER_NOT_IN_BUILDING
iOS: kSITLocationUserNotInBuilding
Flutter: USER_NOT_IN_BUILDING
React Native:
USER_NOT_IN_BUILDING
The positioning system is working perfectly fine, but the user location is outside the building.

This status is only returned when using building mode.

NOTE: Unlike the errors received in onLocationError(), this status is returned by the onLocationStatus().

Other interesting guides #

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