---
schema_version: "1"
id: db319ad47fbd7fccaeaf660f1f4082860d74db8d08a428bfed3ef22e1b2d22db
title: Build a Core SDK App for Android
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/service-cloud/messaging-in-app/guides/android-core-sdk.md
canonical_url: https://developer.salesforce.com/docs/service/messaging-in-app/guide/android-core-sdk.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: d769c7b7194680e2f2ae4550de76b95f3df25fb40bec52a8ef260b7000a9407c
products:
  - Enhanced In-App Chat
  - Service Cloud Developer Content
---
# Build a Core SDK App for Android

The Core SDK allows you to call all the necessary In-App Messaging APIs directly from your app. With the Core SDK, you’re in full control over the entire user experience—you tell the API when to send a message and the API tells you when a message is received.

This article applies to the following implementations:

| UI SDK | Core SDK |
| :----: | :------: |
|        |    ✅    |


If you want to use our ready-made user interface and user experience, use the [UI SDK](https://developer.salesforce.com/docs/service/messaging-in-app/guide/android-ui-sdk.md) instead.

**important:** Use the Core SDK with the Kotlin programming language since this SDK was designed to use [Kotlin flows](https://developer.android.com/kotlin/flow). We don't recommend that you access the Core SDK using Java code.

## Create a Configuration

Create a [`CoreConfiguration`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-core-configuration/index.html) object using the config file that you previously downloaded from your org, or you can manually add the values from within this config file.

### OPTION 1: Configure Using the Config File

Once you've added the `config.json` file to your project, you can reference it from the code.

```kotlin
val config = CoreConfiguration.fromFile(myContext,"configFile.json")
```

**note:** To learn how to download the config file from your org, see [Configure an Enhanced In-App Chat Deployment](https://help.salesforce.com/s/articleView?id=service.miaw_deployment_mobile.htm) in Salesforce Help. This file contains the Service API URL, the org ID, and the API name for the deployment. For example:

```
{
  "OrganizationId": "00ZZZ0000000Zzz",
  "DeveloperName": "MyMessagingForInAppDeployment",
  "Url": "https://zzzz.my.api.url.salesforce-scrt.com"
}
```


### OPTION 2: Configure Manually with Config Info

If you don't want to use the `config.json` file in your project, you can configure the SDK manually using the Service API URL, the org ID, and the API name for the deployment.

```kotlin
val url = URL("URL_TO_MY_SERVICE_API")
val config = CoreConfiguration(url, "ORG_ID", "API_NAME_OF_DEPLOYMENT")
```

## Get the Core Client Object

Get the [`CoreClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-core-client/index.html) from the [`CoreClientFactory`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-core-client-factory/index.html?query=interface%20CoreClientFactory) using the configuration object.

```kotlin
​​val coreClient = CoreClient.Factory.create(myContext, config)
```

## Start the Core Instance

Start the core instance using the correct scope. To learn more about scopes, see [Coroutines](https://developer.android.com/kotlin/coroutines) and [Kotlin flows](https://developer.android.com/kotlin/flow) in the Android documentation.

```kotlin
// Example of some coroutine code to get the scope.
// See Android documentation for more info.
private val supervisorJob = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.Main + supervisorJob)

// Start listening for events using the correct scope
coreClient.start(scope)
```

## Create a Conversation Client

Create a [`ConversationClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-conversation-client/index.html) from the [`CoreClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-core-client/index.html) object.

**tip:** This example creates a random UUID for the conversation ID. However, if you want this conversation to persist even after the app is restarted, be sure to use the same conversation ID. Also, if you want to see this same conversation across multiple devices, in addition to using the same conversation ID, turn on user verification, which is described in the _Enhance the Experience_ section.

**note:** Don't use user IDs or other IDs as the `ConversationID`. Conversation IDs establish a permanent link with a user and are only available to the user who created it. Using a different existing ID instead of a unique ID can result in access issues or errors while developing or testing your Enhanced Chat integration. To pass existing IDs required for your flow, [use the Pre-chat feature](https://help.salesforce.com/s/articleView?id=service.miaw_custom_prechat_2.htm).


```kotlin
val uuid = UUID.randomUUID()
val conversationClient = coreClient.conversationClient(uuid)
```

## Handle a Pre-Chat Form

In order to get the pre-chat fields before a conversation, call the `retrieveRemoteConfiguration` method from your [`CoreClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-core-client/index.html) object. The returned remote configuration object contains a form with an array of fields. Each pre-chat field has the properties necessary for you to build your pre-chat form. After you present the pre-chat form to the user, fill in the `userInput` field for each pre-chat field object. Then submit the pre-chat fields from the `submitRemoteConfiguration` method on the [`ConversationClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-conversation-client/index.html) object.

**important:** IMPORTANT: The `submitPreChatData` method is deprecated in SDK version 1.4. If you want to use new features in version 1.4 and later, submit pre-chat fields using the `submitRemoteConfiguration` method.

```kotlin
// Get the remote config object, which contains the pre-chat form
val remoteConfig = coreClient.retrieveRemoteConfiguration()

(remoteConfig as? Result.Success)?.data?.forms?.get(0)?.let { form ->
  val field = form.formFields[0]

  // Use the PreChatField attributes to render the form in your UI
  val label = field.labels.display
  val type: PreChatFieldType = field.type
  // ...
  val isRequired: Boolean = field.required

  // Set the userInput value to what the end user entered in your form
  field.userInput = "Sample User Input"

  // Validate user input
  if (field.validate() != PreChatErrorType.None) {
    // Display error to end user
  } else {
    // Pass the completed form to the conversation client
    val conversationClient = coreClient.conversationClient(uuid)
    conversationClient.submitRemoteConfiguration(form.formFields)

    // Start new conversation to submit the prechat form
    conversationClient.sendMessage("Hello, I submitted my form and need some assistance…")
  }
}
```

To learn about hidden pre-chat fields, see [Hidden Pre-Chat for Android](https://developer.salesforce.com/docs/service/messaging-in-app/guide/android-pre-chat.md).

## Send Messages

Send a message with the `sendMessage` method on the [`ConversationClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-conversation-client/index.html) object.

```kotlin
conversationClient.sendMessage("It worked!")
```

**note:** If you see the `Exception Failed (417)` error on sending a message, it’s because you set the **Pre-Chat Display Frequency** to **Every Session** in the [Pre-Chat Settings](https://help.salesforce.com/s/articleView?id=service.miaw_custom_prechat_2.htm) and a new session is being created. To fix this, call the [`submitRemoteConfiguration` method on the `ConversationClient` object](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-conversation-client/index.html) with your pre-chat values.

## Listen for Conversation Activity

You can listen for conversation activity with the [`ConversationClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-conversation-client/index.html) object and by using Android's Paging library. To learn about paged data, see [Load and display paged data](https://developer.android.com/topic/libraries/architecture/paging/v3-paged-data) in the Android documentation.

For example, to listen for conversation entries, use the `conversationEntriesPaged` method.

```kotlin
val conversationEntries =
    conversationClient.conversationEntriesPaged()
        .filterIsInstance<Result.Success<PagingData<ConversationEntry>>>().map {
            it.data
        }
```

Use your `PagingDataAdapter` class to listen to the latest events.

```kotlin
conversationEntries.collectLatest {
    myPagingAdapter.submitData(it)
}
```

Your `ViewHolder` class can extract information from the conversation entry.

```kotlin
// Extract the text from a conversation entry
private fun getText(item: ConversationEntry?): String =
    when (val payload = item?.payload) {
    is EntryPayload.MessagePayload ->

        when (val content = payload.abstractMessage.content) {
        is StaticContentFormat.TextFormat -> content.text

            // Handle other message formats (e.g. QuickRepliesFormat, RichLinkFormat)
            else -> content.formatType.toString()
        }

    // Handle other entry types (e.g. ParticipantChangedPayload, AcknowledgeReadPayload)
    else -> payload?.entryType.toString()
}
```

**tip:** When you receive conversation entries from various flows, they’re delivered as [`ConversationEntry`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/data/com.salesforce.android.smi.network.data.domain.conversationEntry/-conversation-entry/index.html) objects. In addition to the `payload`, you can inspect the [`entryType`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/data/com.salesforce.android.smi.network.data.domain.conversationEntry/-conversation-entry/entry-type.html?query=abstract%20val%20entryType:%20ConversationEntryType) (for example, `Message`) when deciding how to process the message. The `payload` is an instance of the [`EntryPayload`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/data/com.salesforce.android.smi.network.data.domain.conversationEntry.entryPayload/-entry-payload/index.html) class and it contains, in addition to the payload itself, a `content` field that describes the message format.

## Listen for Transient Events

To listen for transient events that come from the network, such as typing indicator feedback and network connectivity info, use [Kotlin flows](https://developer.android.com/kotlin/flow) on [`ConversationClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-conversation-client/index.html) and [`CoreClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-core-client/index.html).

To monitor conversation events on the [`ConversationClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-conversation-client/index.html) instance, use the following properties:

- `conversation`: To observe the current conversation.
- `events`: To listen for events specific to this conversation.

To monitor general events on the [`CoreClient`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/core/com.salesforce.android.smi.core/-core-client/index.html) instance, use the following properties:

- `networkConnectivityState`: To determine the network state.
- `events`: To listen for general events (including events from all conversations).

For example, to listen for typing events in a particular conversation, filter on the `events` property.

```kotlin
// Listen for progress/typing indicator events
val events =
    conversationClient.events.filterIsInstance<ConversationEvent.ProgressIndicator>()
```

When you receive events, you can extract information from the contents and pass it to the UI.

```kotlin
events.collectLatest {
    // Grab the status text of the event
    val text = "Typing Event: ${it. conversationEntry.entryType}"

    // Display the text
    Toast.makeText(requireContext(), text, Toast.LENGTH_SHORT).show()
}
```

## Handle Participant Roles

The [`Participant`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/data/com.salesforce.android.smi.network.data.domain.participant/-participant/index.html) interface has a `role` field of type string that maps to a participant role type. `Participant` maps to the `sender` field of the [`ConversationEntry`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/data/com.salesforce.android.smi.network.data.domain.conversationEntry/-conversation-entry/index.html) object.

| Participant Role Type | Description                                                                                                                                                                                                                                                                                                                                     |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `system`              | Set for all [`ParticipantChangedOperation`](https://salesforce-async-messaging.github.io/messaging-in-app-android/sdk/data/com.salesforce.android.smi.network.data.domain.conversationEntry.entryPayload.event/-participant-changed-operation/index.html?query=enum%20ParticipantChangedOperation%20:%20Enum%3CParticipantChangedOperation%3E). |
| `user`                | Set for all conversation entries sent by a user.                                                                                                                                                                                                                                                                                                |
| `agent`               | Set for all conversation entries sent by a rep.                                                                                                                                                                                                                                                                                                 |
| `chatbot`             | Set for all conversation entries sent by a chatbot.                                                                                                                                                                                                                                                                                             |

## Enhance the Experience

You can enhance your users' experience by adding push notifications, passing information to Salesforce about a verified user, sending hidden pre-chat fields, adjusting chat button visibility based on business hours, and more.


For enhanced features, see [Enhance the Experience for Android](https://developer.salesforce.com/docs/service/messaging-in-app/guide/android-enhance.md).

For more details about the Core SDK, see the [Android Reference Documentation](https://salesforce-async-messaging.github.io/messaging-in-app-android/).
