LevelChatDocs
Docs
Android SDK

Android SDK

Kotlin SDK on libwebrtc.

Production-grade Kotlin SDK for Android. Mirrors the @levelchat/web public API one-to-one — same class names, method names, event names, error codes — adapted to idiomatic Kotlin Coroutines + Flow.

2,799 LOC of Kotlin, 18 unit tests passing, 329 KB release AAR, MIT-licensed. Real WebRTC via io.github.webrtc-sdk:android.

Install

Add to app/build.gradle.kts:

Kotlin
dependencies {
  implementation("ai.levelchat:sdk-android:0.1.0")
}

If your project still uses Groovy:

groovy
dependencies {
  implementation 'ai.levelchat:sdk-android:0.1.0'
}

Permissions + foreground service

Required AndroidManifest.xml entries:

xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!-- For screen-share via MediaProjection: -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />

For screen-share you also need to declare a Service with android:foregroundServiceType="mediaProjection". See the example app under packages/sdk-android/example/.

Quickstart

Kotlin
import ai.levelchat.sdk.LevelChat
import ai.levelchat.sdk.JoinRoomOptions
import ai.levelchat.sdk.RoomEvent
import kotlinx.coroutines.flow.collect

// In production the token comes from YOUR BACKEND.
val token = fetchTokenFromYourBackend()

val client = LevelChat(context = applicationContext)
val room = client.joinRoom(JoinRoomOptions(token = token))

// Events are a SharedFlow — collect in your ViewModel.
viewModelScope.launch {
  room.events.collect { event ->
    when (event) {
      is RoomEvent.ParticipantJoined -> Log.d("LC", "${event.participant.identity} joined")
      is RoomEvent.TrackPublished    -> Log.d("LC", "track ${event.track.id}")
      is RoomEvent.Error             -> Log.e("LC", event.error.code)
      else -> Unit
    }
  }
}

Public API

  • class LevelChat — entrypoint; one instance per process.
  • class Room — state machine, connect / leave / publish / subscribe.
  • SharedFlow<RoomEvent> — typed event surface (sealed class hierarchy).
  • StateFlow<RoomState> — reactive state for Jetpack Compose collection.

Modules: Errors, Logger, Events, Constants, Region, Quality, Encryption, Devices, Signaling, Peer, Track, Publication, Subscription, Participant, Room, AudioSession, Lifecycle, ScreenShare.

Audio session

Auto-configured for voice calls: AudioManager.MODE_IN_COMMUNICATION + AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE. The AudioSession.UNMANAGED escape hatch is available for Telecom/ConnectionService-integrated apps that already drive routing themselves.

Lifecycle

Built-in ProcessLifecycleOwner.DefaultLifecycleObserver integration. Local video pauses on background; opt out via LevelChatConfig.autoPauseOnBackground = false.

License

The SDK itself is MIT-licensed — embed in any app, commercial or personal, no royalties. The LevelChat server is BUSL-licensed and requires a paid commercial license for production use beyond the trial threshold. See Licensing.