Skip to main content

Quick Start: Android

Embed the Lovina chat widget in your Android app using a Kotlin WebView wrapper. Minimum SDK: Android 7.0 (API 24).

Step 1: Install from the Nexus registry

Add Lovina's private Maven registry in settings.gradle.kts (credentials go in your global ~/.gradle/gradle.properties — see the full installation guide):

// settings.gradle.kts → dependencyResolutionManagement.repositories
maven {
url = uri("https://packages.ailovina.com/repository/maven-releases/")
credentials {
username = providers.gradleProperty("lovinaNexusUsername").orNull
password = providers.gradleProperty("lovinaNexusPassword").orNull
}
}

Then add the dependency in your module app/build.gradle.kts:

dependencies {
implementation("com.lovina:chat-sdk:{version}")
}

Transitive AndroidX and coroutines dependencies are resolved automatically. Prefer to vendor the raw AAR instead? See manual AAR install.

Step 2: Add the Widget to Your Layout

<com.lovina.chatsdk.LovinaChatWidget
android:id="@+id/lovina_chat"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Step 3: Configure in Your Activity

import com.lovina.chatsdk.*

class ChatActivity : AppCompatActivity() {

private lateinit var chatWidget: LovinaChatWidget

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_chat)

chatWidget = findViewById(R.id.lovina_chat)

chatWidget.onEvent = { event ->
when (event) {
is ChatEvent.Loaded -> Log.d("Chat", "Widget loaded")
is ChatEvent.MessageReceived -> Log.d("Chat", "Message: ${event.message}")
is ChatEvent.UnreadCountChanged -> updateBadge(event.count)
is ChatEvent.Closed -> finish()
is ChatEvent.Error -> Log.e("Chat", "Error [${event.code}]: ${event.message}")
}
}

chatWidget.configure(
LovinaChatConfig(
websiteToken = "your-website-token",
baseUrl = "https://chat-prod.ailovina.com"
)
)
}

override fun onDestroy() {
chatWidget.destroy()
super.onDestroy()
}
}

That is all you need -- the widget handles WebView setup, network monitoring, and session persistence automatically.

Configuration Options

ParameterTypeDefaultDescription
websiteTokenStringrequiredWebsite token for this agent, from your Lovina dashboard
baseUrlStringrequiredBase URL of your Lovina instance
localeString"id"Widget locale code (3 languages supported)
colorSchemeString"auto""light", "dark", or "auto"
userLovinaChatUser?nullPre-identified user
themeLovinaThemeConfig?nullTheme color and layout overrides (hex String colors, not ARGB Ints)
brandingLovinaBrandingConfig?nullWhite-label branding overrides
textsMap<String, Any?>?nullUI string overrides, keyed by translation key
featuresLovinaFeatureFlags?nullFeature-flag overrides
displayModeString"fullscreen""popup", "sidebar", or "fullscreen"

Pre-identified Users

Associate chat sessions with known users from your system:

val config = LovinaChatConfig(
websiteToken = "your-token",
baseUrl = "https://chat-prod.ailovina.com",
user = LovinaChatUser(
identifier = "user-12345",
name = "Jane Doe",
email = "jane@example.com",
phoneNumber = "+6281234567890",
identifierHash = "hmac-hash-for-verification",
customAttributes = mapOf("plan" to "premium")
)
)

Theming and White-Label Branding

Apply a custom brand color (hex string, not Color int) and branding:

val config = LovinaChatConfig(
websiteToken = "your-token",
baseUrl = "https://chat-prod.ailovina.com",
theme = LovinaThemeConfig(primaryColor = "#6366F1"),
branding = LovinaBrandingConfig(brandName = "Acme Support", poweredBy = false)
)

See the Configuration page for the full set of theme, branding, texts, and features options.

Event Handling

EventDescription
ChatEvent.LoadedWidget finished loading. authToken available if user has a session.
ChatEvent.MessageReceivedNew message received. message contains the payload as a Map.
ChatEvent.UnreadCountChangedUnread count changed. Use count to update a badge.
ChatEvent.ClosedChat was closed by user or agent.
ChatEvent.ErrorAn error occurred. Check code and message.

Session Management

Sessions are persisted automatically via SharedPreferences. To clear a session:

chatWidget.clearSession()
chatWidget.reload()

Lifecycle

Always call destroy() when the hosting Activity or Fragment is destroyed:

override fun onDestroy() {
chatWidget.destroy()
super.onDestroy()
}

Development Setup

To test against your local dev server:

  1. Run pnpm dev in the SDK repo
  2. Open packages/android/ in Android Studio
  3. Set baseUrl = "http://10.0.2.2:3001" (emulator to host mapping)
  4. Run on emulator

Next Steps