# Android

This quick-start outlines how to integrate the Monterosa Interaction SDK in your Android app to enable real-time interactions. The SDK allows for easy implementation of interactive features such as live polls, quizzes, and more. Setting up requires both actions in your app and updates in the Monterosa Interaction Cloud platform.&#x20;

***

### Before you begin

{% hint style="success" %}
You can request access to the Android SDK via <support@monterosa.co> or your account manager. This will provide you with a username and token.
{% endhint %}

### Step by step guide

{% stepper %}
{% step %}

#### Add Maven Configuration

In your project's `settings.gradle.kts` or `settings.gradle` file, add the Maven repository configuration to access the Android SDK.

{% tabs %}
{% tab title="Kotlin " %}

<pre class="language-kotlin"><code class="lang-kotlin">dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
        maven {
            url = uri("https://gitlab.com/api/v4/projects/38419902/packages/maven")
            credentials(HttpHeaderCredentials::class.java) {
                name = "Deploy-Token"
                // Replace with package token from the Welcome Pack
<strong>                value = "&#x3C;package token>" 
</strong>            }
            authentication {
                val header by registering(HttpHeaderAuthentication::class)
            }
        }
    }
}
</code></pre>

{% endtab %}

{% tab title="Groovy" %}

<pre class="language-groovy"><code class="lang-groovy">dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
    repositories {
        maven {
            url "https://gitlab.com/api/v4/projects/38419902/packages/maven"
            credentials(HttpHeaderCredentials) {
                name 'Deploy-Token'
                // Replace with package token from the Welcome Pack
<strong>                value '&#x3C;package token>'
</strong>            }
            authentication {
                header(HttpHeaderAuthentication)
            }
        }
    }
}
</code></pre>

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

#### Add the Embed SDK

To embed an experience, add the necessary dependencies to your module-level Gradle file (`build.gradle.kts` or `build.gradle`). Include the Identify dependency for SSO integration.

{% tabs %}
{% tab title="Kotlin" %}

```kotlin
plugins {
    id("kotlin-parcelize")
}

dependencies {
    val sdkVersion = "0.16.19"
    
    // Add the Core dependency
    implementation("co.monterosa.sdk:core:$sdkVersion")
    
    // Add the dependency for embedding experiences
    implementation("co.monterosa.sdk:launcherkit:$sdkVersion")
    
    // Optional - Integration with SSO
    implementation("co.monterosa.sdk:identifykit:$sdkVersion")
}
```

{% endtab %}

{% tab title="Groovy" %}

```groovy
plugins {
    id 'kotlin-parcelize'
}

dependencies {
    def sdkVersion = '0.16.19'
    
    // Add the Core dependency
    implementation 'co.monterosa.sdk:core:$sdkVersion'
    
    // Add the dependency for embedding experiences
    implementation 'co.monterosa.sdk:launcherkit:$sdkVersion'
    
    // Optional - Integration with SSO
    implementation 'co.monterosa.sdk:identifykit:$sdkVersion'
}
```

{% endtab %}
{% endtabs %}

And finally, add the following rule to your `proguard-rules.pro` file :

```
# Monterosa SDK rules
-keep class co.monterosa.sdk.** { *; }
-dontwarn java.lang.management.**
-dontwarn androidx.window.extensions.**
-dontwarn androidx.window.extensions.embedding.**
-dontwarn androidx.window.sidecar.**
```

{% hint style="info" %}
You may need to invalidate Anroid Studio's cache if this error is raised:

> Gradle sync (*Failed to resolve: co.monterosa.sdk:{kit}:X.Y.Z* and *Failed to resolve: co.monterosa.sdk:{kit}:X.Y.Z*).

To invalidate the cache you'll need to delete the cache folder, which is located at:

On Windows: %USERPROFILE%.gradle\caches&#x20;

On Mac/UNIX: \~/.gradle/caches/&#x20;

You can browse to these directory and manually delete it or run on your terminal:

`rm -r $HOME/.gradle/caches/`

After that use the `Invalidate Caches / Restart` option of Android Studio.
{% endhint %}
{% endstep %}

{% step %}

#### Embed the Experience

After adding the required dependencies, you can begin embedding the experience into your app.

{% tabs %}
{% tab title="Compose" %}

```kotlin
// Configure Core in your Application or Activity
Core.configure(context, "<host>", "<project id>")

// Add Experience as a composable
@Composable
fun Experience() {
    AndroidView(
        modifier = modifier.fillMaxSize(),
        factory = { context ->
            val config = ExperienceConfiguration()
            
            Launcher
                .default
                .getExperience(
                    context = context,
                    configuration = config
                )
        }
    )
}
```

{% endtab %}

{% tab title="Views" %}

```kotlin
// Configure Core in your Application or Activity
Core.configure(context, "<host>", "<project id>")

// Configure and add Experience to root container
override fun onCreate(savedInstanceState: Bundle?) {
    val config = ExperienceConfiguration()

    val experienceView = Launcher.default.getExperience(
        context = context,
        configuration = config
    )
    
    rootContainer.addView(experienceView)
}
```

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

#### Listen to Experience State Changes

The `ExperienceViewListener` enables monitoring and handling of lifecycle state changes, messages, and errors in your Experience when necessary.

<pre class="language-kotlin" data-full-width="false"><code class="lang-kotlin">class ExperienceListener : ExperienceViewListener {
    // Override optional listeners here
}

Launcher.default.getExperience(
    context = context,
    configuration = config
).apply {
    // Attach the listener to your Experience
<strong>    listener = ExperienceListener()
</strong>}
...
</code></pre>

{% endstep %}

{% step %}

#### Get Logs from the Experience

Enable debugging logs from the Experience by activating logging in the Core package within your application class. Configure this setting based on the build type to prevent logs from appearing in the production app.

<pre class="language-kotlin"><code class="lang-kotlin">override fun onCreate() {
    super.onCreate()
<strong>    Core.enableLogging(true)
</strong>}
</code></pre>

{% endstep %}

{% step %}

#### Clean Up the Experience

To ensure proper cleanup and resource management, it's recommended to clean up the Experience when destroying the app state. There are two ways to achieve this:

1. Attach the Experience to the activity's lifecycle during initialisation.
2. Explicitly call the `destroy` function from the Experience.

While both methods are effective, some scenarios require an explicit destroy call, especially when the lifecycle is linked to instances that outlive the Experience.

{% tabs %}
{% tab title="Compose" %}

<pre class="language-kotlin"><code class="lang-kotlin">@Composable
fun Experience() {
    ...
    AndroidView(
        modifier = modifier.fillMaxSize(),
        factory = { context ->
            val config = ExperienceConfiguration()
            
            Launcher
                .default
                .getExperience(
                    context = context,
                    configuration = config
                )
        },
        onRelease = { experienceView -> 
<strong>            experienceView.destroy()
</strong>        }
    )
}
</code></pre>

{% endtab %}

{% tab title="Views" %}

<pre class="language-kotlin"><code class="lang-kotlin">...
private var experienceView: ExperienceView? = null

override fun onCreate(savedInstanceState: Bundle?) {
    val config = ExperienceConfiguration()
    
    experienceView = Launcher.default.getExperience(
        context = context,
        configuration = config
    )
    rootContainer.addView(experienceView)
    
    // Attach ExperienceView to Acitivity's lifecycle for Experience to 
    // internally manage clean up
<strong>    lifecycle.addObserver(experienceView)
</strong>}

// Or explicity call destroy from Activity's onDestroy function
override fun onDestroy() {
    super.onDestroy()
<strong>    experienceView?.destroy()
</strong><strong>    experienceView = null
</strong>}
</code></pre>

{% endtab %}
{% endtabs %}
{% endstep %}

{% step %}

#### Embed multiple Experiences

The SDK allows multiple Experiences to run simultaneously by creating unique Core instances for each. Every Experience receives a dedicated Core and Launcher instance.

**How Named Instances Work**\
By default, `Core.configure(...)` targets the shared `Core.default` instance. To isolate experiences, pass a unique name string.

```kotlin
Core.configure(context, host, projectId, name = "my-experience")
```

Retrieve it later with

```kotlin
Core.core("my-experience")
```

Clean up when done

```kotlin
Core.purgeCore("my-experience")
```

**Bind Named Instance to Launcher**\
Finally, Launcher uses `from(core)` to bind them to a specific Core.

{% tabs %}
{% tab title="Compose" %}

<pre class="language-kotlin"><code class="lang-kotlin">@Composable
fun MultiExperienceScreen() {

    // Experience A
    AndroidView(
        modifier = Modifier
            .fillMaxWidth()
            .weight(1f),
        factory = { context ->
<strong>            Core.configure(context, "&#x3C;host>", "&#x3C;project-id-A>", name = "experience-a")
</strong>
            val config = ExperienceConfiguration(eventId = "&#x3C;event-id-A>")
<strong>            Launcher
</strong><strong>                .from(Core.core("experience-a"))
</strong><strong>                .getExperience(context, config)
</strong>        },
        onRelease = { experienceView ->
            experienceView.destroy()
<strong>            Core.purgeCore("experience-a")
</strong>        }
    )

    // Experience B
    AndroidView(
        modifier = Modifier
            .fillMaxWidth()
            .weight(1f),
        factory = { context ->
<strong>            Core.configure(context, "&#x3C;host>", "&#x3C;project-id-B>", name = "experience-b")
</strong>
            val config = ExperienceConfiguration(eventId = "&#x3C;event-id-B>")
<strong>            Launcher
</strong><strong>                .from(Core.core("experience-b"))
</strong><strong>                .getExperience(context, config)
</strong>        },
        onRelease = { experienceView ->
            experienceView.destroy()
<strong>            Core.purgeCore("experience-b")
</strong>        }
    )
}
</code></pre>

{% endtab %}

{% tab title="Views" %}

<pre class="language-kotlin"><code class="lang-kotlin">class MultiExperienceActivity : AppCompatActivity() {
    private var experienceViewA: ExperienceView? = null
    private var experienceViewB: ExperienceView? = null
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        // Experience A
<strong>        Core.configure(this, "&#x3C;host>", "&#x3C;project-id-A>", name = "experience-a")
</strong>        val configA = ExperienceConfiguration(eventId = "&#x3C;event-id-A>")
<strong>        experienceViewA = Launcher.from(Core.core("experience-a"))
</strong>            .getExperience(this, configA)
            .also { view ->
                containerA.addView(view)
                lifecycle.addObserver(view)
            }
    
        // Experience B
<strong>        Core.configure(this, "&#x3C;host>", "&#x3C;project-id-B>", name = "experience-b")
</strong>        val configB = ExperienceConfiguration(eventId = "&#x3C;event-id-B>")
<strong>        experienceViewB = Launcher.from(Core.core("experience-b"))
</strong>            .getExperience(this, configB)
            .also { view ->
                containerB.addView(view)
                lifecycle.addObserver(view)
            }
    }

    override fun onDestroy() {
        super.onDestroy()
    
        experienceViewA?.destroy()
        experienceViewA = null
<strong>        Core.purgeCore("experience-a")
</strong>    
        experienceViewB?.destroy()
        experienceViewB = null
<strong>        Core.purgeCore("experience-b")
</strong>    }
}
</code></pre>

{% endtab %}
{% endtabs %}
{% endstep %}
{% endstepper %}

### Next Steps

The next sections will guide you in customising your experience, expanding capabilities, enhancing communication, and integrating seamlessly with your identity provider.

* [configure-your-app](https://products.monterosa.co/mic/developer-guide/embedding-experiences/android/configure-your-app "mention")
* [communicate-with-embedded-apps](https://products.monterosa.co/mic/developer-guide/embedding-experiences/android/communicate-with-embedded-apps "mention")
* [android-behaviours](https://products.monterosa.co/mic/developer-guide/embedding-experiences/android/android-behaviours "mention")
* [integrate-with-an-identity-provider](https://products.monterosa.co/mic/developer-guide/embedding-experiences/android/integrate-with-an-identity-provider "mention")
