In this Section, we provide an Android step-by-step guide to build your first Situm app using Android. For more advanced use cases, please take a look at the rest of the Situm SDK documentation and to our Android code examples.
Import Situm SDK in your project dependencies #
First of all, you will need to include Situm SDK as part of your project dependencies. To do this, add the maven repository either to your project’s build.gradle file (for Gradle versions <=6) or to your settings.gradle file (for Gradle versions >7).
//Add this to your Project's "build.gradle" file
allprojects {
repositories {
maven { url "https://repo.situm.es/artifactory/libs-release-local" }
}
}
//Add this to your Project's settings.gradle
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url = uri("https://repo.situm.com/artifactory/libs-release-local")
}
}
}
Then add the Situm SDK library dependency into the section dependencies of your application’s build.gradle file. Please specify your desired SDK version (see Changelog for details). It’s important to add the transitive = true property to download the Situm SDK dependencies.
// build.gradle of your app
...
dependencies {
...
//Change X.Y.Z with the SDK version you want
implementation ('es.situm:situm-sdk:X.Y.Z@aar') {
transitive = true
}
}
// build.gradle.kts of your app
...
dependencies {
...
//Change X.Y.Z with the SDK version you want
implementation ("es.situm:situm-sdk:X.Y.Z@aar") {
isTransitive = true
}
}
// Remember to add the following in your 'app/build.gradle.kts' too:
// dependencies {
// ...
// implementation(libs.situm.sdk) {
// isTransitive = true
// }
// }
[versions]
...
situmSdk = "X.Y.Z"
[libraries]
...
situm-sdk = { group = "es.situm", name = "situm-sdk", version.ref = "situmSdk" }
[plugins]
...
Finally, make sure your gradle.properties (Project properties) contains these two lines:
android.useAndroidX=true android.enableJetifier=true
Run your first app! #
The following code contains a fully functional Android app. First, declare the ACCESS_FINE_LOCATION permission in your AndroidManifest.xml (you can omit this step if you have configured Situm SDK not to use GPS):
//AndroidManifest.xml
<manifest>
...
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
...
</manifest>
Then, create a MapView on your activity_main.xml layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
...
<es.situm.sdk.wayfinding.MapView
android:id="@+id/exampleMapView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
...
</androidx.constraintlayout.widget.ConstraintLayout>
You won’t need this layout file when using Jetpack Compose.
Then, you may copy & paste the following snippet in your MainActivity.java/MainActivity.kt file (you may obtain your credentials as explained here, and your building ID as explained here):
//MainActivity.java
//...
//Step 1 - Importing Situm
import es.situm.sdk.SitumSdk;
//...
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
// Step 2 - Setting credentials and building identifier
// Input here your user credentials ...
private String USER = "YOUR_EMAIL";
private String APIKEY = "YOUR_APIKEY";
// ... and the building you want visualize
private String BUILDING_ID = "YOUR_BUILDING_ID";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Step 3 - Initialize SitumSDK
SitumSdk.init(this);
SitumSdk.configuration().setApiKey(USER, APIKEY);
// Step 4 - Positioning
// Establish remote configuration ...
SitumSdk.configuration().setUseRemoteConfig(true);
// ... let SitumSdk handle permission and sensor issues automatically ...
SitumSdk.userHelperManager().autoManage(true);
// ... and start positioning
LocationRequest locationRequest = new LocationRequest.Builder().build();
SitumSdk.locationManager().addLocationListener(locationListener);
SitumSdk.locationManager().requestLocationUpdates(locationRequest);
// Step 5 - Showing the building cartography using the MapView
// Attach the MapView instance to an XML view ...
MapView mapView = findViewById(R.id.exampleMapView);
// ... setup the MapView configuration ...
MapViewConfiguration configuration = new MapViewConfiguration.Builder()
.setProfile("")
.setBuildingIdentifier(BUILDING_ID).build();
// ... load the MapView ...
mapView.load(configuration, new MapView.MapViewCallback() {
@Override
public void onLoad(@NonNull MapViewController mapViewController) {
Log.d(TAG, "Map is ready! ");
// ... and interact with the MapViewController if needed
// For example:
// mapViewController.selectPoi("A-VALID-POI-IDENTIFIER");
}
@Override
public void onError(@NonNull Error error) {
}
});
}
// These callbacks will receive positioning, status and error updates
LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(@NonNull Location location) {
Log.d(TAG, "Location: " + location);
}
@Override
public void onStatusChanged(@NonNull LocationStatus locationStatus) {
Log.d(TAG, "Status: " + locationStatus);
}
@Override
public void onError(@NonNull Error error) {
Log.d(TAG, "Error: " + error);
}
};
}
//MainActivity.kt
//...
//Step 1 - Importing Situm
import es.situm.sdk.SitumSdk
//...
class MainActivity : AppCompatActivity() {
companion object {
private val TAG = MainActivity::class.java.simpleName
// Step 2 - Set here your Situm credentials and building identifier:
private const val USER = "YOUR_EMAIL"
private const val APIKEY = "YOUR_APIKEY"
private const val BUILDING_ID = "YOUR_BUILDING_ID"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Step 3 - Initialize Situm SDK
SitumSdk.init(this)
SitumSdk.configuration().setApiKey(USER, APIKEY)
// Step 4 - Positioning
// Establish remote configuration ...
SitumSdk.configuration().isUseRemoteConfig = true
// ... let SitumSdk handle permission and sensor issues automatically ...
SitumSdk.userHelperManager().autoManage(true)
// ... and start positioning
val locationRequest = LocationRequest.Builder().build()
SitumSdk.locationManager().addLocationListener(locationListener)
SitumSdk.locationManager().requestLocationUpdates(locationRequest)
// Step 5 - Showing the building cartography using the MapView
// Attach the MapView instance to an XML view ...
val mapView: MapView = findViewById(R.id.exampleMapView)
val configuration = MapViewConfiguration.Builder()
.setProfile("")
.setBuildingIdentifier(BUILDING_ID)
.build()
// ... load the MapView ...
mapView.load(configuration, object : MapView.MapViewCallback {
override fun onLoad(mapViewController: MapViewController) {
Log.d(TAG, "Map is ready!")
// ... and interact with the MapViewController if needed
// For example:
// mapViewController.selectPoi("A-VALID-POI-IDENTIFIER");
}
override fun onError(error: Error) {
Log.e(TAG, "MapView error: $error")
}
})
}
// These callbacks will receive positioning, status and error updates
private val locationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
Log.d(TAG, "Location: $location")
}
override fun onStatusChanged(locationStatus: LocationStatus) {
Log.d(TAG, "Status: $locationStatus")
}
override fun onError(error: Error) {
Log.d(TAG, "Error: $error")
}
}
}
//MainActivity.kt
//...
//Step 1 - Importing Situm
import es.situm.sdk.SitumSdk
//...
// Step 2 - Set here your Situm credentials and building identifier:
const val USER = "YOUR_EMAIL"
const val APIKEY = "YOUR_APIKEY"
const val BUILDING_ID = "YOUR_BUILDING_ID"
const val PROFILE = "YOUR_PROFILE"
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Step 3 - Initialize Situm SDK
SitumSdk.init(this@MainActivity)
SitumSdk.configuration().setApiKey(USER, APIKEY)
// Step 4 - Positioning
// Establish remote configuration ...
SitumSdk.configuration().isUseRemoteConfig = true
// ... let SitumSdk handle permission and sensor issues automatically ...
SitumSdk.userHelperManager().autoManage(true)
// ... and start positioning
val locationRequest = LocationRequest.Builder().build()
SitumSdk.locationManager().addLocationListener(locationListener)
SitumSdk.locationManager().requestLocationUpdates(locationRequest)
setContent {
QuickStartAndroidTheme {
Scaffold { paddingValues ->
MyMapView(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues),
mapViewCallback = object: MapView.MapViewCallback {
override fun onLoad(mapViewController: MapViewController) {
Log.d("Situm", "Map is ready!")
// ... and interact with the MapViewController if needed
// For example:
// mapViewController.selectPoi("A-VALID-POI-IDENTIFIER");
}
override fun onError(error: es.situm.sdk.error.Error) {
Log.d("Situm", "MapView error: $error")
}
}
)
}
}
}
}
// These callbacks will receive positioning, status and error updates
private val locationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
Log.d("Situm", "Location: $location")
}
override fun onStatusChanged(locationStatus: LocationStatus) {
Log.d("Situm", "Status: $locationStatus")
}
override fun onError(error: es.situm.sdk.error.Error) {
Log.d("Situm", "Error: $error")
}
}
}
@Composable
fun MyMapView(modifier: Modifier = Modifier, mapViewCallback: MapView.MapViewCallback) {
// Step 5 - Showing the building cartography using the MapView
return AndroidView(
modifier = modifier,
factory = { context ->
MapView(context, attrs = null).apply {
val mapViewConfiguration = MapViewConfiguration.Builder()
.setProfile(PROFILE)
.setBuildingIdentifier(BUILDING_ID)
.build()
// ... load the MapView ...
this.load(mapViewConfiguration, mapViewCallback)
}
}
)
}
When you run this example, you should see something like this:

Code explanation: step-by-step #
Step 1 – Importing Situm #
The 1st thing the example does is to import the SitumSDK package. You may take a look at the Javadoc, although Android Studio will suggest the right imports.
Step 2 – Setting credentials and building identifier #
Right after the import, we set:
- User credentials (email and APIKEY).
- Building identifier. Identifier of the building whose cartography will be shown. It should be the same as the one where you’ll perform positioning.
You may obtain your credentials as explained here, and your building ID as explained here.
Step 3 – Initialize SitumSDK #
In Android, it’s important to initialize SitumSDK by calling SitumSdk.init() method. Right away, you might set the credentials defined in the previous step by calling SitumSdk.configuration().setApiKey().
Instead of this, you can configure your credentials in the AndroidManifest.xml as follows:
//AndroidManifest.xml
...
<application >
...
<meta-data
android:name="es.situm.sdk.API_USER"
android:value="YOUR_EMAIL" />
<meta-data
android:name="es.situm.sdk.API_KEY"
android:value="YOUR_APIKEY" />
...
</application>
Step 4 – Positioning #
Then, you can start positioning.
Setting up the remote configuration #
First, we recommend you to set up the SDK so it uses the Remote Configuration. This allows you to configure positioning parameters (e.g. whether tu use BLE or not, whether to locate in a certain building or detect it automatically, etc.).
We do not recommend this, but as an alternative you may hard-code the positioning parameters in your application (see below)
Requesting permissions #
Your app must also ask for the following permissions (check our documentation for more details): ACCESS_FINE_LOCATION, BLUETOOTH_SCAN and BLUETOOTH_CONNECT.
This example asks for permissions in a naive way, in order to simplify the example. Please follow Android guidelines on this matter.
Starting positioning #
To start positioning, you will need to call the requestLocationUpdates() method, which receives:
- The LocationRequest, which may contain the positioning configuration parameters.
- Any configuration that you set-up here will overwrite the corresponding Remote Configuration (if you’ve enabled it).
- An implementation of the LocationListener, which will contain three callback methods that will be called every time a new result is produced:
- onLocationChanged. It will receive every new location produced.
- onStatusChanged. It will receive every status change produced inside the SDK.
- onError. It will receive any error that the SDK informs.
At this point, Situm SDK will start computing your geolocation. Your application log should show something like this:

Step 5 – Showing the building cartography using the MapView #
Then, the example shows the cartography of the selected building. You may see that the SitumSdk library exposes three main classes to this extent:
- MapView. The widget that you should add to your view hierarchy.
- MapViewConfiguration. Object that allows you to configure the MapView before you load it in the view. You need to at least set the building identifier. Among other things you can also configure the profile if you have one. You can learn more about them here.
- MapViewController. Allows you to communicate with the map after the MapView has been loaded: methods and callbacks are available to perform actions and listen to events (e.g. listen to POI selections, intercept navigation options, etc.)
Visualize the user’s position on the map #
Once the positioning has started, the MapView will automatically start drawing the user’s position on the map. Otherwise, please check that you’ve configured the Remote Configuration properly in Situm Dashboard.
Troubleshooting #
Graddle missconfigurations #
Under some Gradle versions or specific configurations you may see this error when you compile Situm SDK.
Duplicate class androidx.lifecycle.ViewModelLazy found in modules lifecycle-viewmodel-2.5.1-runtime (androidx.lifecycle:lifecycle-viewmodel:2.5.1) and lifecycle-viewmodel-ktx-2.2.0-runtime (androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0)
If this is the case, introduce this in your app’s build.gradle
dependencies {
...
//Change this version with the most recent stable version from https://developer.android.com/jetpack/androidx/releases/lifecycle
def lifecycle_version = "2.5.1".
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
...
}
Multiprocess not supported (do not confuse it with multi-thread) #
Situm SDK is not compatible with Android multi-process. For optimal performance and stability, ensure that all components using the Situm SDK are configured to run in a single process. More info here.