Skip to main content

Overview

This guide covers complete installation of the Stringboot Android SDK, including analytics integration for A/B testing. Follow all steps to unlock the full capabilities of dynamic strings, translations, and experiments.
A/B Testing Setup is Included: This guide includes analytics handler and device ID configuration required for experiments. These are core features, not optional add-ons.

Step 1: Add Maven Repository

Add Maven Central to your project’s settings.gradle.kts:
settings.gradle.kts
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()  // Stringboot SDK is hosted on Maven Central
    }
}

Step 2: Add SDK Dependency

In your app’s build.gradle.kts:
build.gradle.kts
dependencies {
    implementation("com.stringboot:stringboot-android-sdk:1.2.0")
}
All transitive dependencies (Room, Retrofit, OkHttp, Coroutines) are included automatically. Latest Version: Check Maven Central

Step 3: Sync Project

Click Sync Now in Android Studio or run:
./gradlew build

Step 4: Secure API Credentials

Security Best Practice: Never hardcode API tokens in source code or manifest files.

Add to gradle.properties

Create or edit gradle.properties in your project root and add to .gitignore:
gradle.properties
# Add these lines
STRINGBOOT_API_URL=https://api.stringboot.com
STRINGBOOT_API_TOKEN=your_api_token_here

Configure Build Script

In app/build.gradle.kts, configure manifest placeholders:
build.gradle.kts
android {
    defaultConfig {
        // Read from gradle.properties or environment variables
        val apiUrl = project.findProperty("STRINGBOOT_API_URL")?.toString()
            ?: System.getenv("STRINGBOOT_API_URL")
            ?: error("STRINGBOOT_API_URL not configured. Add to gradle.properties")

        val apiToken = project.findProperty("STRINGBOOT_API_TOKEN")?.toString()
            ?: System.getenv("STRINGBOOT_API_TOKEN")
            ?: error("STRINGBOOT_API_TOKEN not configured. Add to gradle.properties")

        // Make available to AndroidManifest.xml
        manifestPlaceholders["STRINGBOOT_API_URL"] = apiUrl
        manifestPlaceholders["STRINGBOOT_API_TOKEN"] = apiToken
    }
}

Step 5: Configure AndroidManifest.xml

Add required permissions and SDK configuration:
AndroidManifest.xml
<application
        <!-- Stringboot SDK Configuration -->
        <meta-data
            android:name="com.stringboot.api_url"
            android:value="${STRINGBOOT_API_URL}" />
        <meta-data
            android:name="com.stringboot.api_token"
            android:value="${STRINGBOOT_API_TOKEN}" />
        <meta-data
            android:name="com.stringboot.default_locale"
            android:value="en" />
        <meta-data
            android:name="com.stringboot.cache_size"
            android:value="1000" />
</application>

Step 6: Analytics Handler (Required for A/B Testing)

Why Analytics Integration is Required

The analytics handler enables:
  • Experiment tracking: Know which users see which variants
  • Results analysis: Measure impact of string changes
  • Data-driven decisions: Use analytics platforms for statistical analysis
  • Firebase Analytics
  • Mixpanel
  • Amplitude
  • Custom Analytics

Add Firebase Dependency

build.gradle.kts
dependencies {
    implementation("com.stringboot:stringboot-android-sdk:1.2.0")
    implementation("com.google.firebase:firebase-analytics-ktx:21.5.0")
}

Implement Analytics Handler

StringbootApplication.kt
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import com.stringboot.sdk.analytics.StringbootAnalyticsHandler
import com.stringboot.sdk.models.ExperimentAssignment

class StringbootApplication : Application() {

    private lateinit var firebaseAnalytics: FirebaseAnalytics

    override fun onCreate() {
        super.onCreate()

        // Initialize Firebase
        firebaseAnalytics = Firebase.analytics

        // Create analytics handler
        val analyticsHandler = object : StringbootAnalyticsHandler {
            override fun onExperimentsAssigned(experiments: Map<String, ExperimentAssignment>) {
                experiments.forEach { (key, assignment) ->
                    // Set user property for each experiment
                    firebaseAnalytics.setUserProperty(
                        "stringboot_exp_$key",
                        assignment.variantName
                    )

                    StringbootLogger.i("Experiment: $key β†’ ${assignment.variantName}")
                }
            }
        }

        // Initialize Stringboot with analytics
        StringbootExtensions.autoInitialize(
            context = this,
            analyticsHandler = analyticsHandler
        )
    }
}

Step 7: Device ID Configuration (Required for A/B Testing)

Why Device ID is Required

  • Consistent assignments: Same device always gets same variant
  • Cross-session persistence: Experiments persist across app restarts
  • Accurate results: Users don’t switch between variants randomly
  • Auto-Generated (Default)
  • Firebase Installation ID
  • Custom Device ID
By default, the SDK generates a persistent UUID per app installation:
StringbootApplication.kt
class StringbootApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        // SDK automatically generates and persists a UUID
        StringbootExtensions.autoInitialize(
            context = this,
            analyticsHandler = analyticsHandler
            // providedDeviceId not specified - SDK generates UUID
        )
    }
}
Characteristics:
  • Persists across app launches
  • Unique per app installation
  • Automatically managed by SDK
  • Use this unless you have a specific reason to use custom ID

Step 8: Complete SDK Initialization

Here’s the complete Application class with all components:
StringbootApplication.kt
package com.yourapp

import android.app.Application
import androidx.lifecycle.ProcessLifecycleOwner
import com.google.firebase.analytics.FirebaseAnalytics
import com.google.firebase.analytics.ktx.analytics
import com.google.firebase.ktx.Firebase
import com.stringboot.sdk.StringProvider
import com.stringboot.sdk.StringbootExtensions
import com.stringboot.sdk.analytics.StringbootAnalyticsHandler
import com.stringboot.sdk.models.ExperimentAssignment
import com.stringboot.sdk.utils.StringbootLogger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

class StringbootApplication : Application() {

    private val applicationScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
    private lateinit var firebaseAnalytics: FirebaseAnalytics

    override fun onCreate() {
        super.onCreate()

        // Initialize Firebase Analytics
        firebaseAnalytics = Firebase.analytics

        // Create analytics handler for experiments
        val analyticsHandler = object : StringbootAnalyticsHandler {
            override fun onExperimentsAssigned(experiments: Map<String, ExperimentAssignment>) {
                experiments.forEach { (key, assignment) ->
                    // Set user property in Firebase
                    firebaseAnalytics.setUserProperty(
                        "stringboot_exp_$key",
                        assignment.variantName
                    )

                    StringbootLogger.i("πŸ“Š Experiment: $key β†’ ${assignment.variantName}")
                }
            }
        }

        // Auto-initialize SDK from manifest configuration
        val success = StringbootExtensions.autoInitialize(
            context = this,
            providedDeviceId = null,  // Let SDK generate UUID (or provide custom)
            analyticsHandler = analyticsHandler
        )

        if (success) {
            StringbootLogger.i("βœ… Stringboot initialized successfully")

            // Preload current language for instant access
            runBlocking {
                val locale = StringProvider.deviceLocale()
                StringProvider.preloadLanguage(locale, maxStrings = 500)
                StringbootLogger.i("πŸ“¦ Preloaded $locale strings into memory")
            }

            // Refresh from network in background
            applicationScope.launch {
                val locale = StringProvider.deviceLocale()
                StringProvider.refreshFromNetwork(locale)
                StringbootLogger.i("πŸ”„ Background sync complete for $locale")
            }
        } else {
            StringbootLogger.w("⚠️ Stringboot auto-initialization failed")

            // Fallback: offline-only mode
            try {
                StringProvider.initialize(
                    context = this,
                    cacheSize = 1000,
                    api = null  // No network access
                )
                StringbootLogger.i("βœ… Stringboot initialized in offline mode")
            } catch (e: Exception) {
                StringbootLogger.e("❌ Fallback initialization failed: ${e.message}", e)
            }
        }
    }
}

Step 9: Verify Setup

Test SDK Initialization

  1. Run your app with debug logging enabled
  2. Check Logcat for Stringboot initialization messages:
I/Stringboot: βœ… Stringboot initialized successfully
I/Stringboot: πŸ“¦ Preloaded en strings into memory
I/Stringboot: πŸ”„ Background sync complete for en

Test String Retrieval

Add a test in your MainActivity:
MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Test string retrieval
        val testString = StringProvider.get("welcome_message", "en")
        Log.i("StringbootTest", "String value: $testString")

        // Should NOT see "??welcome_message??" (means string loaded)
    }
}

Test Experiment Assignment

If you have experiments running:
// Check device ID
val deviceId = StringProvider.getDeviceId()
Log.i("StringbootTest", "Device ID: $deviceId")

// Look for experiment logs
// I/Stringboot: πŸ“Š Experiment: cta-test β†’ variant-a

Verify Analytics Integration

  1. Check your analytics platform (Firebase/Mixpanel/Amplitude)
  2. Look for user properties like stringboot_exp_cta_test
  3. Value should be variant name: control, variant-a, etc.

Common Setup Issues

Cause: API token not in gradle.propertiesSolution:
  1. Create gradle.properties in project root (next to settings.gradle.kts)
  2. Add STRINGBOOT_API_TOKEN=your_token_here
  3. Add gradle.properties to .gitignore
  4. Sync project
Possible causes:
  1. No experiments running in dashboard
  2. Analytics handler not passed to autoInitialize()
  3. Device not assigned to any experiments
Solutions:
  • Create test experiment in dashboard
  • Verify analyticsHandler parameter is set
  • Check device ID is being sent with requests
Causes:
  1. API token invalid
  2. No network connectivity
  3. Strings not created in dashboard
Solutions:
  • Verify API token in dashboard
  • Check internet permission in manifest
  • Ensure strings exist for your app
Cause: Using non-persistent ID or regenerating UUIDSolution:
  • Use default SDK-generated UUID (it persists automatically)
  • If using custom ID, store it in SharedPreferences
  • Don’t generate new UUID on each launch

Next Steps

Now that setup is complete, learn how to use the three core features:

Additional Resources


Questions? Contact [email protected]