Skip to main content

Android SDK

TgoRTC Android (Kotlin) SDK for real-time audio/video communication based on LiveKit.

Installation

Add the JitPack repository to your build.gradle.kts (Project):

allprojects {
repositories {
maven { url = uri("https://jitpack.io") }
}
}

Add the dependency in your build.gradle.kts (Module):

dependencies {
implementation("com.github.TgoRTC:TgoRTCSDK:1.0.0")
}

Latest version:

Dependencies

The SDK automatically includes the following core dependency:

  • io.livekit:livekit-android:2.23.1

Quick Start

1. Initialize SDK

import com.tgo.rtc.TgoRTC
import com.tgo.rtc.entity.TgoOptions

val options = TgoOptions().apply {
debug = true
mirror = false
}

TgoRTC.instance.init(applicationContext, options)

2. Create Room Info and Join

import com.tgo.rtc.entity.TgoRoomInfo
import com.tgo.rtc.entity.TgoRTCType
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch

val scope = MainScope()

val roomInfo = TgoRoomInfo(
roomName = "room-name",
token = "your-token",
url = "http://your-server",
loginUID = "local-user-id",
creatorUID = "creator-user-id"
)

roomInfo.maxParticipants = 4
roomInfo.rtcType = TgoRTCType.VIDEO
roomInfo.timeout = 30

scope.launch {
TgoRTC.instance.roomManager.joinRoom(
roomInfo,
micEnabled = true,
cameraEnabled = true
)
}

3. Listen to Connection Status

import com.tgo.rtc.entity.TgoConnectStatus

val connectListener = { roomName: String, status: TgoConnectStatus, reason: String ->
println("Room $roomName: $status - $reason")

when (status) {
TgoConnectStatus.CONNECTING -> println("Connecting...")
TgoConnectStatus.CONNECTED -> println("Connected to room")
TgoConnectStatus.DISCONNECTED -> println("Disconnected from room")
}
}

TgoRTC.instance.roomManager.addConnectListener(connectListener)
TgoRTC.instance.roomManager.removeConnectListener(connectListener)

Note: The current Android SDK does not expose separate RECONNECTING or RECONNECTED enum values. RoomEvent.Reconnecting is currently reported as TgoConnectStatus.CONNECTING by TgoRoomManager.

4. Get Participants

val local = TgoRTC.instance.participantManager.getLocalParticipant()
val localOrNull = TgoRTC.instance.participantManager.getLocalParticipantOrNull()

val remotes = TgoRTC.instance.participantManager.getRemoteParticipants()
val joinedRemotes = TgoRTC.instance.participantManager.getJoinedRemoteParticipants()

val all = TgoRTC.instance.participantManager.getAllParticipants()
val joined = TgoRTC.instance.participantManager.getJoinedParticipants()
val joinedCount = TgoRTC.instance.participantManager.getJoinedParticipantCount()

TgoRTC.instance.participantManager.addNewParticipantListener { participant ->
println("New participant joined: ${participant.uid}")
}

5. Media Control and Events

Media control is only available for local participants.

import com.tgo.rtc.entity.TgoConnectionQuality
import com.tgo.rtc.entity.TgoVideoInfo

val participant = TgoRTC.instance.participantManager.getLocalParticipant()

scope.launch {
participant.setMicrophoneEnabled(true)
}

scope.launch {
participant.setCameraEnabled(true)
}

scope.launch {
participant.setScreenShareEnabled(true)
}

participant.switchCamera()

val micEnabled = participant.getMicrophoneEnabled()
val cameraEnabled = participant.getCameraEnabled()
val screenShareEnabled = participant.getScreenShareEnabled()
val cameraPosition = participant.getCameraPosition()
val isSpeaking = participant.getIsSpeaking()
val audioLevel = participant.getAudioLevel()
val createdAt = participant.getCreatedAt()
val isJoined = participant.isJoined()

val onMicChange: (Boolean) -> Unit = { enabled ->
println("Microphone: ${if (enabled) "on" else "off"}")
}

val onCameraChange: (Boolean) -> Unit = { enabled ->
println("Camera: ${if (enabled) "on" else "off"}")
}

val onScreenShareChange: (Boolean) -> Unit = { enabled ->
println("Screen share: ${if (enabled) "on" else "off"}")
}

val onSpeakingChange: (Boolean, Float) -> Unit = { speaking, level ->
println("Speaking: $speaking, Level: $level")
}

val onConnQualityChange: (TgoConnectionQuality) -> Unit = { quality ->
println("Connection quality: $quality")
}

val onJoined: () -> Unit = {
println("Participant joined")
}

val onLeave: () -> Unit = {
println("Participant left")
}

val onTrackPublished: () -> Unit = {
println("Track published")
}

val onTrackUnpublished: () -> Unit = {
println("Track unpublished")
}

val onVideoInfoChange: (TgoVideoInfo) -> Unit = { info ->
println("Video info: ${info.resolutionString}, ${info.bitrateString}")
}

participant.addMicrophoneStatusListener(onMicChange)
participant.addCameraStatusListener(onCameraChange)
participant.addScreenShareStatusListener(onScreenShareChange)
participant.addSpeakingListener(onSpeakingChange)
participant.addConnQualityListener(onConnQualityChange)
participant.addJoinedListener(onJoined)
participant.addLeaveListener(onLeave)
participant.addTrackPublishedListener(onTrackPublished)
participant.addTrackUnpublishedListener(onTrackUnpublished)
participant.addVideoInfoListener(onVideoInfoChange)

participant.removeMicrophoneStatusListener(onMicChange)
participant.removeCameraStatusListener(onCameraChange)
participant.removeScreenShareStatusListener(onScreenShareChange)
participant.removeSpeakingListener(onSpeakingChange)
participant.removeConnQualityListener(onConnQualityChange)
participant.removeJoinedListener(onJoined)
participant.removeLeaveListener(onLeave)
participant.removeTrackPublishedListener(onTrackPublished)
participant.removeTrackUnpublishedListener(onTrackUnpublished)
participant.removeVideoInfoListener(onVideoInfoChange)

6. Render Video Track

Add TgoVideoRenderer in your layout XML:

<com.tgo.rtc.track.TgoVideoRenderer
android:id="@+id/videoRenderer"
android:layout_width="match_parent"
android:layout_height="match_parent" />

Initialize in your Activity or Fragment:

import com.tgo.rtc.track.TgoRendererType
import com.tgo.rtc.track.TgoVideoRenderer
import com.tgo.rtc.track.TgoVideoScaleType
import io.livekit.android.room.track.Track

val renderer = findViewById<TgoVideoRenderer>(R.id.videoRenderer)

renderer.init()
renderer.setParticipant(participant)
renderer.setMirror(true)
renderer.setRendererType(TgoRendererType.TEXTURE_VIEW)
renderer.setScaleType(TgoVideoScaleType.FILL)
renderer.setTrackSource(Track.Source.CAMERA)

7. Audio Management

import com.tgo.rtc.entity.TgoAudioDevice
import com.tgo.rtc.entity.TgoAudioDeviceType

val devices = TgoRTC.instance.audioManager.getAudioOutputDevices()
val selected = TgoRTC.instance.audioManager.getSelectedDevice()

val deviceListener: (List<TgoAudioDevice>, TgoAudioDevice?) -> Unit = { available, current ->
println("Available devices: $available")
println("Current device: $current")
}

TgoRTC.instance.audioManager.addDeviceChangeListener(deviceListener)

selected?.let { TgoRTC.instance.audioManager.selectDevice(it) }
TgoRTC.instance.audioManager.selectDeviceByType(TgoAudioDeviceType.SPEAKER)

TgoRTC.instance.audioManager.toggleSpeakerphone()
TgoRTC.instance.audioManager.setSpeakerphoneOn(true)

val isSpeakerOn = TgoRTC.instance.audioManager.isSpeakerOn()
val hasBluetooth = TgoRTC.instance.audioManager.isBluetoothConnected()
val hasWiredHeadset = TgoRTC.instance.audioManager.isWiredHeadsetConnected()
val canSwitchSpeaker = TgoRTC.instance.audioManager.canSwitchSpeakerphone()

TgoRTC.instance.audioManager.removeDeviceChangeListener(deviceListener)

8. Leave Room

TgoRTC.instance.roomManager.leaveRoom()

API Reference

TgoRTC

PropertyTypeDescription
instanceTgoRTCSingleton instance
optionsTgoOptionsSDK configuration
roomManagerTgoRoomManagerRoom management
participantManagerTgoParticipantManagerParticipant management
audioManagerTgoAudioManagerAudio management

TgoRoomManager

MethodDescription
joinRoom(roomInfo, micEnabled, cameraEnabled)Join a room (suspend)
leaveRoom()Leave current room
addConnectListener(listener)Add connection status listener
removeConnectListener(listener)Remove connection status listener
addVideoInfoListener(listener)Add video info listener
removeVideoInfoListener(listener)Remove video info listener
isCalling()Whether a call is active

TgoParticipantManager

MethodDescription
getLocalParticipantOrNull()Get local participant, returns null if unavailable
getLocalParticipant()Get local participant
getRemoteParticipants(includePending)Get remote participants
getAllParticipants(includePending)Get all participants
getJoinedParticipants()Get joined participants
getJoinedRemoteParticipants()Get joined remote participants
getJoinedParticipantCount()Get joined participant count
inviteParticipant(roomName, uids)Invite participants by UID
removePendingParticipants(roomName?, uids)Remove pending participants who have not joined
addNewParticipantListener(listener)Listen for new participants
removeNewParticipantListener(listener)Remove new participant listener

TgoParticipant

Media Control Methods (Local Only)

MethodDescription
setMicrophoneEnabled(enabled)Enable/disable microphone (suspend)
setCameraEnabled(enabled)Enable/disable camera (suspend)
setScreenShareEnabled(enabled)Enable/disable screen share (suspend)
switchCamera()Switch front/back camera

Status Methods

MethodDescription
getMicrophoneEnabled()Get microphone status
getCameraEnabled()Get camera status
getScreenShareEnabled()Get screen share status
getCameraPosition()Get camera position (front/back)
getAudioLevel()Get current audio level (0.0 - 1.0)
getIsSpeaking()Check if currently speaking
getVideoTrack(source)Get video track
getCreatedAt()Get participant wrapper creation time
isJoined()Whether the participant has joined

Event Listener Methods

MethodDescription
addMicrophoneStatusListener(listener)Listen for microphone status changes
addCameraStatusListener(listener)Listen for camera status changes
addSpeakerStatusListener(listener)Listen for speaker status changes
addScreenShareStatusListener(listener)Listen for screen share status changes
addSpeakingListener(listener)Listen for speaking status and volume
addCameraPositionListener(listener)Listen for camera position changes
addConnQualityListener(listener)Listen for connection quality changes
addJoinedListener(listener)Listen for participant join
addLeaveListener(listener)Listen for participant leave
addTrackPublishedListener(listener)Listen for track published events
addTrackUnpublishedListener(listener)Listen for track unpublished events
addVideoInfoListener(listener)Listen for video info changes
remove...Listener(listener)Remove corresponding listener

Properties

PropertyDescription
uidParticipant UID
isLocalWhether this is the local participant

TgoVideoRenderer (View)

MethodDescription
init()Initialize renderer
init(room)Initialize renderer with a specific Room
setParticipant(participant)Set participant to render
setVideoTrack(track)Set video track directly
setMirror(mirror)Set mirror mode
setRendererType(type)Set renderer type (SurfaceView/TextureView)
setScaleType(type)Set video scale type (FILL/FIT)
setTrackSource(source)Set track source (CAMERA/SCREEN_SHARE)
release()Release resources

TgoAudioManager

MethodDescription
addDeviceChangeListener(listener)Listen for output device changes
removeDeviceChangeListener(listener)Remove device change listener
getAudioOutputDevices()Get available output devices
getSelectedDevice()Get currently selected output device
selectDevice(device)Select a specific output device
selectDeviceByType(type)Select an output device by type
isWiredHeadsetConnected()Whether a wired headset is connected
isBluetoothConnected()Whether a Bluetooth audio device is connected
isSpeakerOn()Whether speaker output is currently selected
setSpeakerphoneOn(on)Set speakerphone state
toggleSpeakerphone()Toggle speakerphone
canSwitchSpeakerphone()Whether speakerphone switching is supported

Enums

TgoConnectStatus

enum class TgoConnectStatus {
CONNECTING,
CONNECTED,
DISCONNECTED
}

TgoRTCType

enum class TgoRTCType {
AUDIO,
VIDEO
}

TgoConnectionQuality

enum class TgoConnectionQuality {
UNKNOWN,
EXCELLENT,
GOOD,
POOR,
LOST
}

TgoCameraPosition

enum class TgoCameraPosition {
FRONT,
BACK
}

TgoRoomInfo Class

Configuration class for room connections.

PropertyDescription
roomNameRoom name
tokenLiveKit token
urlLiveKit server URL
loginUIDCurrent user ID
creatorUIDRoom creator ID
maxParticipantsMax participants (default 2)
rtcTypeCall type (default AUDIO)
isP2PWhether P2P mode is enabled (default true)
uidListParticipant UID list
timeoutJoin timeout in seconds (default 30)

Configuration Options

class TgoOptions {
var mirror: Boolean = false
var debug: Boolean = true
}

Platform Configuration

Permissions

Add the following permissions in AndroidManifest.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" />
<uses-permission android:name="android.permission.BLUETOOTH" />

For Android 12 (API 31) and above, if using Bluetooth headphones, you also need:

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

Handling Pending Participants

The current Android SDK does not expose participant-level timeout callbacks like participant.addTimeoutListener(...). Instead, TgoRoomManager checks pending participants based on roomInfo.timeout and removes expired entries through TgoParticipantManager.removePendingParticipants(...). If your business logic already knows which invited users did not answer, you can also remove them manually:

TgoRTC.instance.participantManager.removePendingParticipants(
roomName = roomInfo.roomName,
uids = listOf("user_b", "user_c")
)