Skip to content

Android Troubleshooting Guide

This guide addresses Android-specific issues and solutions when integrating the Squad SDK.

Installation Issues

Gradle Integration

Issue: Dependency Resolution

Error: Failed to resolve: com.withsquad.sdk:squadline:1.0.0

Solutions:

  1. Check repositories in settings.gradle:
dependencyResolutionManagement {
    repositories {
        mavenCentral()
    }
}
  1. Force dependency refresh:
./gradlew clean build --refresh-dependencies

Version Conflicts

Issue: Dependency Version Conflicts

Error: Duplicate class found

Solutions:

  1. Add resolution strategy:
configurations.all {
    resolutionStrategy {
        force 'com.withsquad.sdk:squadline:1.0.0'
    }
}
  1. Check dependency tree:
./gradlew app:dependencies

Build Issues

ProGuard/R8

Issue: ProGuard Optimization Failures

Error: Class not found after ProGuard optimization

Solutions:

  1. Add ProGuard rules:
-keep class com.withsquad.sdk.** { *; }
-keepclassmembers class com.withsquad.sdk.** { *; }
  1. Check mapping file:
build/outputs/mapping/release/mapping.txt

Architecture Issues

Issue: ABI Compatibility

Error: Unable to load native library

Solutions:

  1. Configure ABI filters:
android {
    defaultConfig {
        ndk {
            abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
        }
    }
}

WebView Issues

WebView Loading

Issue: Content Loading Failures

Error: WebView failed to load content

Solutions:

  1. Configure WebView properly:
webView.settings.apply {
    javaScriptEnabled = true
    domStorageEnabled = true
    mediaPlaybackRequiresUserGesture = false
}

webView.webViewClient = object : WebViewClient() {
    override fun onReceivedError(
        view: WebView?,
        request: WebResourceRequest?,
        error: WebResourceError?
    ) {
        // Handle error
    }
}
  1. Handle SSL errors:
webView.webViewClient = object : WebViewClient() {
    override fun onReceivedSslError(
        view: WebView?,
        handler: SslErrorHandler?,
        error: SslError?
    ) {
        if (BuildConfig.DEBUG) {
            handler?.proceed()
        } else {
            handler?.cancel()
        }
    }
}

JavaScript Bridge

Issue: Bridge Communication Failures

Error: JavaScript interface not working

Solutions:

  1. Verify bridge setup:
class SquadJSInterface(private val context: Context) {
    @JavascriptInterface
    fun postMessage(message: String) {
        // Handle message
    }
}

webView.addJavascriptInterface(SquadJSInterface(context), "SquadAndroid")
  1. Debug bridge messages:
webView.evaluateJavascript(
    "(function() { return window.SquadBridge != null; })();"
) { result ->
    Log.d("SquadSDK", "Bridge available: $result")
}

Audio Issues

AudioManager

Issue: Audio Configuration

Error: Failed to initialize audio system

Solutions:

  1. Configure audio settings:
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
audioManager.mode = AudioManager.MODE_IN_COMMUNICATION
audioManager.isSpeakerphoneOn = false
  1. Handle audio focus:
private val audioFocusRequest = AudioFocusRequest.Builder(
    AudioManager.AUDIOFOCUS_GAIN
).run {
    setAudioAttributes(AudioAttributes.Builder().run {
        setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
        setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
        build()
    })
    setAcceptsDelayedFocusGain(true)
    setOnAudioFocusChangeListener { focusChange ->
        // Handle focus change
    }
    build()
}

Permissions

Issue: Microphone Access

Error: Missing RECORD_AUDIO permission

Solutions:

  1. Check permissions:
private fun checkAudioPermission() {
    if (ContextCompat.checkSelfPermission(
        context,
        Manifest.permission.RECORD_AUDIO
    ) != PackageManager.PERMISSION_GRANTED) {
        requestAudioPermission()
    }
}

private fun requestAudioPermission() {
    ActivityCompat.requestPermissions(
        activity,
        arrayOf(Manifest.permission.RECORD_AUDIO),
        PERMISSION_REQUEST_CODE
    )
}

Memory Management

Memory Leaks

Issue: Memory Leaks

Error: Memory leak detected

Solutions:

  1. Handle activity lifecycle:
override fun onDestroy() {
    webView.clearCache(true)
    webView.clearHistory()
    webView.destroy()
    super.onDestroy()
}
  1. Monitor memory:
class MemoryMonitor {
    fun logMemoryInfo(context: Context) {
        val runtime = Runtime.getRuntime()
        val usedMemInMB = (runtime.totalMemory() - runtime.freeMemory()) / 1048576L
        Log.d("MemoryMonitor", "Used memory: $usedMemInMB MB")
    }
}

Debug Tools

Logging

  1. Enable SDK logging:
SquadSDK.setLogLevel(LogLevel.DEBUG)
  1. Add debug interceptor:
class DebugInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        Log.d("SquadSDK", "Request: ${request.url}")
        return chain.proceed(request)
    }
}

Performance Monitoring

Monitor WebView performance:

webView.setWebViewClient(object : WebViewClient() {
    override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
        startTime = System.currentTimeMillis()
    }

    override fun onPageFinished(view: WebView, url: String) {
        val loadTime = System.currentTimeMillis() - startTime
        Log.d("SquadSDK", "Page load time: $loadTime ms")
    }
})

Configuration Changes

Handle configuration changes properly:

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)
    // Handle configuration change
    webView.requestLayout()
}

Support

When contacting support, provide:

  • Android Studio version
  • Android OS version
  • Device model
  • SDK version
  • Error logs
  • Steps to reproduce
  • Sample project (if possible)
  • ProGuard mapping file (if applicable)