An Android SDK that provides integration with BabylAI chat functionality, supporting multiple themes and languages.
- 🚀 Easy integration with BabylAI chat
- 🌓 Support for light and dark themes
- 🎨 Advanced Theme Customization - Custom brand colors for light and dark themes
- 🖼️ Custom Logo Support - Replace header logo with your brand logo
- 🌍 Dynamic Language Switching - Runtime language change (English and Arabic with RTL)
- 📬 Message receiving callback for custom notification handling
⚠️ Comprehensive Error Handling - Global and view-specific error callbacks- ⚡ Quick access to active chats
- 🏗️ Environment-based configuration (Production/Development)
- 🔒 Secure, predefined API endpoints
- 📱 Jetpack Compose UI components
- 🎨 Material Design 3 theming with automatic color generation
The BabylAI Android SDK is published to Maven Central for easy integration. Simply add the dependency to your app-level build.gradle.kts:
dependencies {
implementation("io.github.aau-iq:babylai-android-sdk:1.1.18")
}That's it! Maven Central is already configured by default in Android projects. No additional repository configuration needed.
android {
defaultConfig {
minSdk = 24 // Required by BabylAI SDK
}
}Option 2: GitHub Releases Repository
Add the GitHub repository to your settings.gradle.kts:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url = uri("https://raw.githubusercontent.com/AAU-IQ/BabylAI-Android/main/releases")
metadataSources {
mavenPom()
artifact()
}
content { includeGroup("iq.aau.babylai.android") }
}
}
}Add the dependency:
dependencies {
implementation("iq.aau.babylai.android:babylaisdk:1.0.61-beta3")
}Option 3: Direct AAR Download
- Download the latest AAR from releases/latest/BabylAISDK-release.aar
- Place it in your app's
libs/directory - Add to your
build.gradle.kts:
dependencies {
implementation(files("libs/BabylAISDK-release.aar"))
}First, initialize BabylAI with the appropriate environment configuration and set up the token callback:
import iq.aau.babylai.android.babylaisdk.BabylAI
import iq.aau.babylai.android.babylaisdk.config.EnvironmentConfig
import iq.aau.babylai.android.babylaisdk.config.BabylAIEnvironment
import iq.aau.babylai.android.babylaisdk.config.ThemeConfig
import iq.aau.babylai.android.babylaisdk.core.enums.BabylAILocale
import iq.aau.babylai.android.babylaisdk.core.errors.BabylAIError
import androidx.core.graphics.toColorInt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Create environment configuration
val config = EnvironmentConfig.production(enableLogging = false) // or EnvironmentConfig.development()
// Initialize BabylAI with environment configuration and custom theming
BabylAI.shared.initialize(
context = this,
config = config,
locale = BabylAILocale.ENGLISH, // or BabylAILocale.ARABIC
userInfo = mapOf(
"name" to "John Doe",
"email" to "[email protected]",
"phone" to "+1234567890"
),
themeConfig = ThemeConfig(
primaryColor = "#4A6741".toColorInt(), // Elegant forest green for light theme
secondaryColor = "#D4AF37".toColorInt(), // Sophisticated gold for light theme
primaryColorDark = "#81C784".toColorInt(), // Soft sage green for dark theme
secondaryColorDark = "#F9D71C".toColorInt(), // Warm amber for dark theme
headerLogoRes = R.drawable.your_custom_logo, // Optional: Your brand logo
logoSymbolRes = R.drawable.your_logo_icon // Optional: Small icon for chat avatars
),
onErrorReceived = { error ->
// Optional: Handle global errors
println("❌ SDK Error [${error.errorCode}]: ${error.userFriendlyMessage}")
}
)
// IMPORTANT: You MUST set up a token callback for the package to work
BabylAI.shared.setTokenCallback {
// Example implementation to get a token
return@setTokenCallback getToken() // Return your access token as string
}
// Optional: Set up global error handling callback
BabylAI.shared.setOnErrorReceived { error: BabylAIError ->
println("❌ SDK Error [${error.errorCode}]: ${error.userFriendlyMessage}")
// Handle errors globally - show notifications, log to analytics, etc.
}
// Optional: Change language dynamically after initialization
BabylAI.shared.setLocale(BabylAILocale.ARABIC) // Switch to Arabic with RTL support
}
}
⚠️ Important: You must callBabylAI.shared.initialize()andBabylAI.shared.setTokenCallback()before using any other BabylAI functionality. Failure to do so will result in authentication errors when trying to launch the chat interface.
The package supports two environments:
- Production: Uses production API endpoints, logging disabled by default
- Development: Uses development API endpoints, logging enabled by default
You can create environment configurations using factory methods:
// Production environment (logging disabled by default)
val productionConfig = EnvironmentConfig.production()
// Production environment with logging enabled
val productionConfigWithLogging = EnvironmentConfig.production(enableLogging = true)
// Development environment (logging enabled by default)
val developmentConfig = EnvironmentConfig.development()
// Development environment with custom timeouts
val customDevConfig = EnvironmentConfig.development(
enableLogging = true,
connectionTimeout = 60000,
receiveTimeout = 30000
)The BabylAI SDK supports dynamic language switching without requiring re-initialization. You can change the language at runtime and the SDK will update all text content and layout direction accordingly.
// Switch to Arabic with RTL support
BabylAI.shared.setLocale(BabylAILocale.ARABIC)
// Switch back to English with LTR support
BabylAI.shared.setLocale(BabylAILocale.ENGLISH)
// Get current locale
val currentLocale = BabylAI.shared.getLocale()@Composable
fun LanguageSwitcher() {
var isArabic by remember { mutableStateOf(false) }
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Text("Arabic Language")
Switch(
checked = isArabic,
onCheckedChange = { enabled ->
isArabic = enabled
// Update SDK language dynamically
BabylAI.shared.setLocale(
if (enabled) BabylAILocale.ARABIC else BabylAILocale.ENGLISH
)
}
)
}
}-
English (BabylAILocale.ENGLISH):
- Left-to-right (LTR) layout direction
- English text content and labels
- Western number formatting
-
Arabic (BabylAILocale.ARABIC):
- Right-to-left (RTL) layout direction
- Arabic text content and labels
- Arabic/Eastern number formatting
- Proper RTL text alignment
- Language changes take effect immediately in active SDK views
- The locale setting persists across SDK sessions
- RTL layout automatically adjusts all UI components, icons, and navigation
- No re-initialization required when switching languages
Here's a simple example of how to integrate BabylAI in your Android app:
import iq.aau.babylai.android.babylaisdk.BabylAI
import iq.aau.babylai.android.babylaisdk.BabylAITheme
import androidx.compose.runtime.Composable
import androidx.navigation.NavController
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<Button>(R.id.openChatButton).setOnClickListener {
// Show chat interface
// You can use the composable directly in your Compose UI
}
}
}
@Composable
fun BabylAIChatScreen(
navController: NavController,
isDirect: Boolean = false,
isDarkMode: Boolean = false
) {
// Handle back navigation using system back gesture
androidx.activity.compose.BackHandler {
navController.popBackStack()
}
// Get the BabylAI viewer composable
val currentTheme = if (isDarkMode) BabylAITheme.DARK else BabylAITheme.LIGHT
val viewerComposable = BabylAI.shared.viewer(
theme = currentTheme,
isDirect = isDirect,
screenId = "YOUR_SCREEN_ID",
onMessageReceived = { message ->
println("📨 Received message: $message")
},
onDismiss = {
// Handle SDK back navigation - go back to home screen
navController.popBackStack()
}
)
// Display the SDK view - it will take full screen
viewerComposable()
}For a more complete implementation with theme and language switching:
import androidx.compose.runtime.*
import iq.aau.babylai.android.babylaisdk.BabylAI
import iq.aau.babylai.android.babylaisdk.BabylAITheme
@Composable
fun BabylAIExample() {
var showChat by remember { mutableStateOf(false) }
var showActiveChat by remember { mutableStateOf(false) }
Column {
Button(onClick = { showChat = true }) {
Text("Launch BabylAI")
}
Button(onClick = { showActiveChat = true }) {
Text("Launch Active Chat")
}
}
if (showChat) {
BabylAI.shared.viewer(
theme = BabylAITheme.LIGHT,
isDirect = false,
screenId = "YOUR_SCREEN_ID",
onMessageReceived = { message ->
// Handle new message notifications
println("New message: $message")
},
onDismiss = { showChat = false }
)
}
if (showActiveChat) {
BabylAI.shared.presentActiveChat(
theme = BabylAITheme.DARK,
screenId = "YOUR_SCREEN_ID",
onMessageReceived = { message ->
// Handle messages for active chat
println("Active chat message: $message")
},
onDismiss = { showActiveChat = false }
)
}
}For better state management with ViewModels:
class ChatViewModel : ViewModel() {
private val _showChat = MutableStateFlow(false)
val showChat: StateFlow<Boolean> = _showChat.asStateFlow()
fun openChat() {
_showChat.value = true
}
fun closeChat() {
_showChat.value = false
}
fun handleNewMessage(message: String) {
// Handle incoming messages from BabylAI
viewModelScope.launch {
// Update UI, show notifications, etc.
println("Received: $message")
}
}
}
@Composable
fun ChatScreen(viewModel: ChatViewModel = viewModel()) {
val showChat by viewModel.showChat.collectAsState()
if (showChat) {
BabylAI.shared.viewer(
theme = BabylAITheme.LIGHT,
isDirect = false,
screenId = "YOUR_SCREEN_ID",
onMessageReceived = { message ->
viewModel.handleNewMessage(message)
},
onDismiss = { viewModel.closeChat() }
)
}
}BabylAI.shared.initialize(context: Context, config: EnvironmentConfig, locale: BabylAILocale, userInfo: Map<String, Any>?, themeConfig: ThemeConfig?, onErrorReceived: ((BabylAIError) -> Unit)?): Initialize BabylAI with environment configuration and optional theme customizationBabylAI.shared.setTokenCallback(callback: suspend () -> String): Set a callback function that will be called when the token needs to be refreshedBabylAI.shared.setOnErrorReceived(callback: (BabylAIError) -> Unit): Set a global error callback to handle all SDK errorsBabylAI.shared.setLocale(locale: BabylAILocale): Change the SDK language dynamically without re-initializationBabylAI.shared.getLocale(): BabylAILocale: Get the currently selected SDK languageBabylAI.shared.getViewerComposable(theme: BabylAITheme = BabylAITheme.LIGHT, isDirect: Boolean = false, screenId: String, onMessageReceived: ((String) -> Unit)? = null, onBack: () -> Unit = {}) -> @Composable () -> Unit: Get the BabylAI chat interface as a Compose composableBabylAI.shared.makeView(theme: BabylAITheme, userInfo: Map<String, Any>, screenId: String, onMessageReceived: ((String) -> Unit)? = null, onErrorReceived: ((BabylAIError) -> Unit)? = null) -> @Composable: Create the main SDK viewBabylAI.shared.viewer(theme: BabylAITheme = BabylAITheme.LIGHT, isDirect: Boolean = false, screenId: String, onMessageReceived: ((String) -> Unit)? = null, onErrorReceived: ((BabylAIError) -> Unit)? = null, onDismiss: () -> Unit = {}) -> @Composable: Create the SDK viewer with token validation wrapperBabylAI.shared.presentActiveChat(theme: BabylAITheme, screenId: String, onMessageReceived: ((String) -> Unit)? = null, onErrorReceived: ((BabylAIError) -> Unit)? = null, onDismiss: () -> Unit = {}) -> @Composable: Present the active chat directly
EnvironmentConfig.production(enableLogging: Boolean = false, connectionTimeout: Int = 30_000, receiveTimeout: Int = 15_000): Production environment configurationEnvironmentConfig.development(enableLogging: Boolean = true, connectionTimeout: Int = 30_000, receiveTimeout: Int = 15_000): Development environment configuration
BabylAITheme.LIGHT: Light themeBabylAITheme.DARK: Dark themeThemeConfig(primaryColor, secondaryColor, primaryColorDark, secondaryColorDark, headerLogoRes): Comprehensive theme customization with separate light/dark colors and custom logo support
BabylAILocale.ENGLISH: English languageBabylAILocale.ARABIC: Arabic language (with RTL support)
The token callback is essential for authentication with the BabylAI service. The callback should:
- Make an API request to get a fresh token
- Parse the response correctly (the token is at the root level with key "token")
- Return the token as a string
- Handle errors appropriately
Example response structure:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 900
}The package automatically handles token expiration by:
- Detecting 401 (Unauthorized) or 403 (Forbidden) HTTP errors
- Automatically calling your token callback to get a fresh token
- Storing the new token for subsequent requests
This ensures that your users won't experience disruptions when their token expires during a session.
| Parameter | Type | Description |
|---|---|---|
| theme | BabylAITheme | UI theme (.LIGHT or .DARK) |
| locale | BabylAILocale | Language (.ENGLISH or .ARABIC) |
| themeConfig | ThemeConfig? | Optional theme customization with brand colors and logo |
| isDirect | Boolean | Whether to open active chat directly |
| onMessageReceived | ((String) -> Unit)? | Callback for handling new messages |
| onErrorReceived | ((BabylAIError) -> Unit)? | Callback for handling view-specific errors |
| onBack | () -> Unit | Callback for back navigation |
The package provides a callback for handling new messages through the onMessageReceived parameter. You can implement your own notification system or message handling logic. Here's an example of how you might handle new messages:
BabylAI.shared.viewer(
screenId = "YOUR_SCREEN_ID",
onMessageReceived = { message ->
// Implement your preferred notification system
// For example, using NotificationManager
// or any other notification approach
showCustomNotification(message)
}
)In addition to the global error callback, individual views can also handle errors locally:
BabylAI.shared.viewer(
theme = BabylAITheme.LIGHT,
screenId = "YOUR_SCREEN_ID",
onMessageReceived = { message ->
// Handle new messages
handleNewMessage(message)
},
onErrorReceived = { error ->
// Handle errors specific to this view instance
handleViewError(error)
}
)Note: View-specific error callbacks will be called in addition to the global error callback, giving you flexibility to handle errors at both global and local levels.
- Android Studio 4.0+
- Android API Level 24+
- Kotlin 1.8+
- Jetpack Compose (for composable integration)
For a complete integration example, see BabylAI-Android-Example.
For any issues or feature requests, please contact the package maintainers or submit an issue on the repository.
Copyright © 2025 BabylAI
This software is provided under a custom license agreement. Usage is permitted only with explicit authorization from BabylAI. This software may not be redistributed, modified, or used in derivative works without written permission from BabylAI.
All rights reserved.