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
| Parameter | Type | Default | Description |
|---|---|---|---|
websiteToken | String | required | Website token for this agent, from your Lovina dashboard |
baseUrl | String | required | Base URL of your Lovina instance |
locale | String | "id" | Widget locale code (3 languages supported) |
colorScheme | String | "auto" | "light", "dark", or "auto" |
user | LovinaChatUser? | null | Pre-identified user |
theme | LovinaThemeConfig? | null | Theme color and layout overrides (hex String colors, not ARGB Ints) |
branding | LovinaBrandingConfig? | null | White-label branding overrides |
texts | Map<String, Any?>? | null | UI string overrides, keyed by translation key |
features | LovinaFeatureFlags? | null | Feature-flag overrides |
displayMode | String | "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
| Event | Description |
|---|---|
ChatEvent.Loaded | Widget finished loading. authToken available if user has a session. |
ChatEvent.MessageReceived | New message received. message contains the payload as a Map. |
ChatEvent.UnreadCountChanged | Unread count changed. Use count to update a badge. |
ChatEvent.Closed | Chat was closed by user or agent. |
ChatEvent.Error | An 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:
- Run
pnpm devin the SDK repo - Open
packages/android/in Android Studio - Set
baseUrl = "http://10.0.2.2:3001"(emulator to host mapping) - Run on emulator