Install the Chat Widget in an Android app
The Front Android SDK enables you to add Front Chat to your native Android apps for real-time, chat-based support. Complete the steps in this guide to get started.
The Front Android SDK is in beta
We encourage you to report issues and provide feedback on our GitHub repo.
Install the Front SDK
// build.gradle.kts
dependencies {
implementation("com.frontapp:frontsdk:0.0.0-alpha.1")
}
// build.gradle
dependencies {
implementation "com.frontapp:frontsdk:0.0.0-alpha.1"
}
Update AndroidManifest.xml
Add the INTERNET
permission and windowSoftInputMode
to adjustResize
.
<manifest
...
<uses-permission android:name="android.permission.INTERNET"/>
<application
...
<activity android:windowSoftInputMode="adjustResize">
</activity>
</application>
...
</manifest>
Configure Front Chat
-
Go to Settings > Channels in Front.
-
Search for or click on the channel you are using for Front Chat.
-
Open the Installation tab and identify the
chatID
within the Widget code snippet. -
Configure an instance of
FrontChatConfig
.import com.frontapp.frontsdk.FrontChatConfig val config = FrontChatConfig( chatId = "<chatId from step above>" )
-
If you are using the Verified Users feature, add the appropriate parameters. Refer to Identify users for more information.
import com.frontapp.frontsdk.FrontChatConfig import com.frontapp.frontsdk.Contact import com.frontapp.frontsdk.CustomFieldValue val config = FrontChatConfig( chatId = "<chatId from step 1 above>", email = "<user email>", userHash = "<user hash generated by your backend using the verification secret", name = "<user name>", customFields = mapOf( "custom_field_1" to CustomFieldValue.StringValue("value_1") ), contact = Contact( email = "<user email>", customFields = mapOf( "custom_field_1" to CustomFieldValue.StringValue("value_1") ) ) )
Present the FrontChatView
Refer to the code snippets below for an introduction to presenting the FrontChatView
in your project. For full working code examples, visit our GitHub repo.
The FrontChatView
view can be used like any other @Composable
view. Here, we’ll present it as a modal sheet when the “Open Chat” button is tapped.
import ...
class MainActivity : ComponentActivity() {
private var isShowingFrontChat by mutableStateOf(false)
private val chatId = "your chat_id"
@SuppressLint("SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FrontSdkExampleComposeTheme {
MainScreen()
}
}
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (isShowingFrontChat) {
isShowingFrontChat = false
} else {
finish()
}
}
})
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen() {
Box(modifier = Modifier.fillMaxSize()) {
LaunchFrontChatButton()
AnimatedFrontChatView()
}
}
@Composable
fun LaunchFrontChatButton() {
// A simple button to launch FrontChatView
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = { isShowingFrontChat = true }) {
Text("Open Chat")
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AnimatedFrontChatView() {
AnimatedVisibility(
visible = isShowingFrontChat,
enter = fadeIn() + slideInVertically(initialOffsetY = { it }),
exit = fadeOut() + slideOutVertically(targetOffsetY = { it }),
) {
Box(
modifier = Modifier.fillMaxSize()
) {
FrontChatView(config = FrontChatConfig(chatId = chatId))
}
}
}
}

Handle loading state and errors
When you run the examples above, you’ll notice there’s a loading state before the UI comes into view. This is due to the current implementation relying on a webview that loads the same code as Front Chat for web.
Below we have code samples to show how to customize the loading state and handle errors due to things like network issues that cause FrontChatView
to fail to load. For working examples, visit the GitHub repo.
- Add an instance of
FrontChatViewModel
as an instance variable.class MainActivity : ComponentActivity() { private val viewModel = FrontChatViewModel() ... }
- Use the
loadingStatus
property ofFrontChatViewModel
to display different UI as appropriate.class MainActivity: ComponentActivity() { ... @Composable fun MainScreen() { val didEncounterUnrecoverableError by viewModel.didEncounterUnrecoverableError.observeAsState(false) val loadingStatus by viewModel.loadingStatus.observeAsState(LoadingStatus.IDLE) Box(modifier = Modifier.fillMaxSize()) { if (loadingStatus == LoadingStatus.FAILED_LOADING) { // Example of how to handle failed loading FailedToLoadDialog() } else if (didEncounterUnrecoverableError == true) { // Example of how to handle an exception from the webview that FrontChatView uses UnrecoverableExceptionDialog() } else { LaunchFrontChatButton() AnimatedFrontChatView() } } } @Composable fun FailedToLoadDialog() { AlertDialog( title = { Text(text = "Error") }, text = { Text(text = "Failed to load the chat.") }, onDismissRequest = { isShowingFrontChat = false }, confirmButton = { TextButton( onClick = { viewModel.reset(); isShowingFrontChat = false } ) { Text("Ok") } } ) } @Composable fun UnrecoverableExceptionDialog() { AlertDialog( title = { Text(text = "Error") }, text = { Text(text = viewModel.unrecoverableErrorMessage.value ?: "An unknown error occurred.") }, onDismissRequest = { viewModel.reset() isShowingFrontChat = false }, confirmButton = { TextButton( onClick = { viewModel.reset() viewModel.restart() } ) { Text("Start new chat") } }, dismissButton = { TextButton( onClick = { isShowingFrontChat = false viewModel.reset() } ) { Text("Dismiss") } } ) } }
Reference for FrontChatViewModel
properties
FrontChatViewModel
propertiesName | Type | Description |
---|---|---|
| FrontChatViewLoadingStatus | An enum with possible values:
|
| Error? | An instance of Error returned by the webview on navigation failure. Corresponds to |
| Bool | Set to |
| String? | A human readable message populated when |
Updated 8 days ago