TroubleShooting

Troubleshooting Guide

Common issues with the Kasookoo Android SDK and how to resolve them.


Table of Contents

  1. Installation Issues
  2. Build Errors
  3. Authentication Errors
  4. Connection Issues
  5. Call Issues
  6. Audio Issues
  7. Push Notification Issues
  8. Performance Issues
  9. Debugging Tools

Installation Issues

"Could not find com.kasookoo:sdk-android"

Cause: Maven repository not added or sync failed.

Solutions:

  1. Verify Maven repository in settings.gradle.kts:

    maven {
        url = uri("https://maven.kasookoo.ai/releases")
    }
  2. Click Sync Project with Gradle Files (toolbar refresh icon)

  3. File → Invalidate Caches & Restart

  4. Try CLI sync:

    ./gradlew clean
    ./gradlew build --refresh-dependencies

"Manifest merger failed"

Cause: Conflicting permissions or services from different libraries.

Solutions:

  1. Check error message for the specific conflict

  2. Use tools:replace in your manifest:

    <application
        tools:replace="android:icon,android:label"
        ... >
  3. Use tools:remove to remove conflicts:

    <service
        android:name="conflicting.service"
        tools:node="remove" />

"Failed to resolve: com.google.firebase:firebase-bom"

Solutions:

  1. Add Google Maven repository:

    repositories {
        google()
        mavenCentral()
    }
  2. Verify internet connection and Maven Central access

  3. Try using specific Firebase versions instead of BoM temporarily


Build Errors

"Duplicate class found in modules"

Cause: Multiple versions of the same dependency.

Solutions:

  1. Run dependency tree:

    ./gradlew :app:dependencies
  2. Exclude conflicting transitive dependencies:

    implementation("com.kasookoo:sdk-android:1.0.0") {
        exclude(group = "com.squareup.okhttp3")
    }
  3. Force specific versions:

    configurations.all {
        resolutionStrategy {
            force("com.squareup.okhttp3:okhttp:4.12.0")
        }
    }

"Cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 17"

Cause: Mixed JVM target versions.

Solution: Ensure all modules use JVM 17:

android {
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    
    kotlinOptions {
        jvmTarget = "17"
    }
}

Build fails with R8/ProGuard errors

Cause: Code minification removing SDK classes.

Solution: Add ProGuard rules in proguard-rules.pro:

-keep class com.kasookoo.sdk.** { *; }
-keep interface com.kasookoo.sdk.** { *; }
-dontwarn com.kasookoo.sdk.**

-keep class io.livekit.android.** { *; }
-dontwarn io.livekit.android.**

-keep class org.webrtc.** { *; }
-dontwarn org.webrtc.**

"Class XYZ not found"

Solutions:

  1. Clean build: Build → Clean Project
  2. Rebuild: Build → Rebuild Project
  3. Invalidate caches: File → Invalidate Caches & Restart

Authentication Errors

"Invalid publishable key"

Symptoms: KasookooError.InvalidKey thrown during initialize()

Causes:

  • Wrong key format
  • Expired key
  • Wrong environment

Solutions:

  1. Verify key format:

    • Sandbox: starts with pk_test_
    • Production: starts with pk_live_
  2. Check key in Kasookoo Dashboard:

    • Make sure key isn't revoked
    • Match environment to key type
  3. Use correct environment in config:

    KasookooConfig(
        publishableKey = "pk_test_...",
        environment = Environment.SANDBOX
    )

"Session expired" / 401 Unauthorized

Symptoms: API calls fail after working initially

Causes:

  • Session TTL exceeded (default 10 minutes)
  • Token refresh failed
  • Backend session invalidated

Solutions:

  1. SDK should auto-refresh. Check Logcat for refresh attempts.

  2. Re-connect explicitly:

    lifecycleScope.launch {
        sdk.disconnect()
        sdk.connect()
    }
  3. Re-initialize if needed:

    lifecycleScope.launch {
        sdk.destroy()
        sdk.initialize(config)
        sdk.connect()
    }

"User identification failed"

Causes:

  • Invalid email format
  • Backend rejected user data
  • User type mismatch

Solutions:

  1. Validate email before sending:

    if (!email.contains("@")) return
  2. Use valid ParticipantType:

    • CUSTOMER, AGENT, DRIVER, BOT, ADMIN
  3. Check Logcat for specific rejection reason.


Connection Issues

"Failed to connect to backend"

Symptoms: connect() throws network exception

Causes:

  • No internet connection
  • Firewall blocking traffic
  • Backend down
  • Invalid base URL

Solutions:

  1. Check internet connection:

    adb shell ping -c 4 sdk.kasookoo.ai
  2. Verify environment URL:

    // Sandbox
    environment = Environment.SANDBOX  // → https://sdk-sandbox.kasookoo.ai
    
    // Production
    environment = Environment.PRODUCTION  // → https://sdk.kasookoo.ai
  3. Check status.kasookoo.ai for outages

  4. Check firewall — allow these domains:

    • *.kasookoo.ai
    • *.livekit.cloud
    • *.googleapis.com (Firebase)

"Token refresh failed repeatedly"

Symptoms: App keeps disconnecting

Causes:

  • Clock skew (device time wrong)
  • Backend changed JWT signing key
  • Network instability

Solutions:

  1. Verify device time is correct (Settings → Date & Time → Automatic)

  2. Reset SDK state:

    lifecycleScope.launch {
        sdk.destroy()
        sdk.initialize(config)
    }
  3. If issue persists, contact support with logs.

"CleartextTrafficException"

Cause: App tries to use HTTP instead of HTTPS.

Solutions:

  1. Use HTTPS endpoints only (Kasookoo enforces HTTPS by default)
  2. If you must allow cleartext for debugging:
    <!-- AndroidManifest.xml -->
    <application
        android:usesCleartextTraffic="true"
        ... >

⚠️ Never use cleartext in production.


Call Issues

"Call fails immediately after start()"

Symptoms: Call goes from INITIATING to FAILED

Causes:

  • Invalid callee
  • Backend rejected call
  • Insufficient permissions

Solutions:

  1. Check error details:

    lifecycleScope.launch {
        sdk.events
            .filter { it.name == EventName.CALL_FAILED }
            .collect { event ->
                Log.e("Call", "Error: ${event.data["errorMessage"]}")
            }
    }
  2. Verify callee has required info (name, email)

  3. Check publishable key scopes include webrtc

"Invalid state transition: X → Y"

Symptoms: Call state machine error

Causes:

  • Calling end() on already-ended call
  • Calling accept() on outgoing call
  • Race condition

Solutions:

  1. Check call state before action:

    if (call.state != CallState.ENDED && call.state != CallState.FAILED) {
        sdk.call.end(callId = call.id)
    }
  2. Use SDK events to know when actions are valid

"LiveKit connection failed"

Symptoms: Call reaches CONNECTING then fails

Causes:

  • LiveKit token expired
  • Network blocking WebRTC
  • LiveKit cloud issues

Solutions:

  1. Verify network allows WebRTC:

    • UDP 50000-60000 outbound
    • TCP 443 outbound
    • TURN servers reachable
  2. Test on different network (cellular vs WiFi)

  3. Check LiveKit status


Audio Issues

"Call connects but no audio"

Symptoms: State is CONNECTED but can't hear/be heard

Causes:

  • Microphone permission denied
  • Audio focus not granted
  • Bluetooth routing issue
  • Emulator (limited audio support)

Solutions:

  1. Check microphone permission:

    if (ContextCompat.checkSelfPermission(
            this, 
            Manifest.permission.RECORD_AUDIO
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        requestPermissions.launch(arrayOf(Manifest.permission.RECORD_AUDIO))
    }
  2. Test on real device — emulator has limited audio

  3. Check audio mode:

    val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
    Log.d("Audio", "Mode: ${audioManager.mode}")
    Log.d("Audio", "Speaker: ${audioManager.isSpeakerphoneOn}")
  4. Force speaker output:

    audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
    audioManager.isSpeakerphoneOn = true

"Audio cuts in and out / poor quality"

Causes:

  • Weak network signal
  • Bandwidth constraints
  • Background tasks consuming CPU

Solutions:

  1. Test on stable WiFi
  2. Close other apps using camera/microphone
  3. Check network speed (need 100 kbps+ stable)
  4. Update to latest LiveKit version

"Echo / feedback during call"

Causes:

  • Both devices' speakers near each other
  • Echo cancellation not working

Solutions:

  1. Use headphones on at least one device during testing
  2. Increase distance between devices
  3. Lower speaker volume
  4. Verify echo cancellation is enabled in audio session

"Bluetooth headphones not working"

Solutions:

  1. Add BLUETOOTH_CONNECT permission (Android 12+):

    <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
  2. Request runtime permission:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        requestPermissions.launch(arrayOf(Manifest.permission.BLUETOOTH_CONNECT))
    }

Push Notification Issues

"FCM token not generated"

See Push Notifications Guide.

"Push received but no ConnectionService UI"

Causes:

  • Payload format incorrect
  • Phone account not registered
  • MANAGE_OWN_CALLS permission missing

Solutions:

  1. Verify payload includes:

    {
      "data": {
        "type": "incoming_call",
        "call_id": "...",
        "room_name": "...",
        "caller_name": "..."
      }
    }
  2. Register phone account at app startup (see Push Notifications Guide)

  3. Verify permissions in Manifest

"Push works in foreground but fails in background"

Causes:

  • Battery optimization killing app
  • Doze mode interfering
  • Manufacturer-specific app management

Solutions:

  1. Use priority: "high" in FCM payload

  2. Request battery optimization exception:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        val pm = getSystemService(POWER_SERVICE) as PowerManager
        if (!pm.isIgnoringBatteryOptimizations(packageName)) {
            val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
            intent.data = Uri.parse("package:$packageName")
            startActivity(intent)
        }
    }
  3. For Chinese phones (Xiaomi, Huawei, etc.), guide users to add app to "Protected Apps"

"POST_NOTIFICATIONS permission denied"

Cause: User denied permission on Android 13+.

Solutions:

  1. Re-request with explanation:
    if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
        // Show dialog explaining why
        showRationaleDialog()
    } else {
        // Open app settings
        val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
        intent.putExtra(Settings.EXTRA_APP_PACKAGE, packageName)
        startActivity(intent)
    }

Performance Issues

"App memory keeps growing"

Causes:

  • Coroutine scopes not cancelled
  • Flow collectors not cancelled
  • Strong references in callbacks

Solutions:

  1. Use lifecycle-aware coroutines:

    class MyActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            
            lifecycleScope.launch {
                // Auto-cancelled on destroy
                sdk.events.collect { handleEvent(it) }
            }
        }
    }
  2. Use viewLifecycleOwner.lifecycleScope in Fragments

  3. Use repeatOnLifecycle:

    lifecycleScope.launch {
        repeatOnLifecycle(Lifecycle.State.STARTED) {
            sdk.events.collect { handleEvent(it) }
        }
    }

"SDK uses too much battery"

Causes:

  • Long-running calls without proper cleanup
  • Background services running unnecessarily
  • Wake locks held too long

Solutions:

  1. End calls properly when user navigates away
  2. Don't hold wake locks beyond call duration
  3. Use foreground service only during active calls

"App launches slowly"

Causes:

  • SDK initialization blocking main thread
  • Too many synchronous operations on launch

Solutions:

  1. Initialize SDK off main thread:

    class MyApplication : Application() {
        override fun onCreate() {
            super.onCreate()
            
            CoroutineScope(Dispatchers.IO).launch {
                sdk = KasookooSDK(this@MyApplication)
                sdk.initialize(config)
            }
        }
    }
  2. Defer SDK init until needed:

    // Initialize when user logs in or makes first call

Debugging Tools

Enable Verbose Logging

val config = KasookooConfig(
    publishableKey = "...",
    organizationId = "...",
    logging = LoggingConfig(
        level = LogLevel.DEBUG,  // VERBOSE, DEBUG, INFO, WARNING, ERROR
        includeNetworkLogs = true,
        includeStateChanges = true
    )
)

Inspect Events in Real Time

lifecycleScope.launch {
    sdk.events.collect { event ->
        Log.d("SDK", "📨 ${event.name} - ${event.data}")
    }
}

Network Debugging with Charles/Proxyman

  1. Install Charles Proxy on Mac/PC
  2. Configure Android device to use Charles as proxy:
    • WiFi settings → Modify network → Proxy → Manual
    • Hostname: Your PC IP
    • Port: 8888
  3. Install Charles CA certificate on device:
    • Browse to chls.pro/ssl from device
    • Install certificate
  4. Configure network security config in Android app:
    <!-- res/xml/network_security_config.xml -->
    <network-security-config>
        <debug-overrides>
            <trust-anchors>
                <certificates src="user" />
            </trust-anchors>
        </debug-overrides>
    </network-security-config>

LiveKit Debugging

Enable LiveKit verbose logs:

import io.livekit.android.LiveKit
import io.livekit.android.LogLevel

LiveKit.setLogLevel(LogLevel.DEBUG)

Logcat Filtering

Filter Logcat for SDK logs:

adb logcat -s "KasookooSDK:V" "FCM:V" "Call:V"

Crash Reports

Set up crash reporting (Firebase Crashlytics recommended):

dependencies {
    implementation("com.google.firebase:firebase-crashlytics-ktx")
}

Getting Help

If you can't resolve an issue:

Information to Include

When reporting issues, please provide:

  1. SDK version (e.g., 1.0.0)
  2. Android version (e.g., Android 14, API 34)
  3. Device model (e.g., Samsung Galaxy S24)
  4. Android Studio version (e.g., Iguana 2023.2.1)
  5. Kotlin version (e.g., 2.0.0)
  6. Gradle version (e.g., 8.4)
  7. Steps to reproduce
  8. Expected behavior vs actual behavior
  9. Logcat output (with sensitive data redacted)
  10. Configuration code (with publishable key redacted)

Where to Get Help

Enterprise Support

Enterprise customers have access to:

  • Dedicated Slack channel
  • Priority response (4-hour SLA)
  • Direct engineering escalation
  • Video call support

Contact [email protected] to upgrade.


Did this page help you?