Skip to main content

Android quickstart (Jetpack Compose)

Get started with LiveKit and Android using Jetpack Compose

Voice AI quickstart

To build your first voice AI app for Android, use the following quickstart and the starter app. Otherwise follow the getting started guide below.

Getting started guide

This guide uses the Android Components library for the easiest way to get started on Android.

If you are using the traditional view-based system, check out the Android quickstart.

Otherwise follow this guide to build your first LiveKit app with Android Compose.

SDK installation

LiveKit Components for Android Compose is available as a Maven package.

...
dependencies {
implementation "io.livekit:livekit-android-compose-components:<current version>"
}

See the releases page for information on the latest version of the SDK.

You'll also need JitPack as one of your repositories. In your settings.gradle file:

dependencyResolutionManagement {
repositories {
google()
mavenCentral()
//...
maven { url 'https://jitpack.io' }
}
}

Permissions

LiveKit relies on the RECORD_AUDIO and CAMERA permissions to use the microphone and camera. These permission must be requested at runtime, like so:

/**
* Checks if the RECORD_AUDIO and CAMERA permissions are granted.
*
* If not granted, will request them. Will call onPermissionGranted if/when
* the permissions are granted.
*/
fun ComponentActivity.requireNeededPermissions(onPermissionsGranted: (() -> Unit)? = null) {
val requestPermissionLauncher =
registerForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { grants ->
// Check if any permissions weren't granted.
for (grant in grants.entries) {
if (!grant.value) {
Toast.makeText(
this,
"Missing permission: ${grant.key}",
Toast.LENGTH_SHORT
)
.show()
}
}
// If all granted, notify if needed.
if (onPermissionsGranted != null && grants.all { it.value }) {
onPermissionsGranted()
}
}
val neededPermissions = listOf(Manifest.permission.RECORD_AUDIO, Manifest.permission.CAMERA)
.filter { ContextCompat.checkSelfPermission(this, it) == PackageManager.PERMISSION_DENIED }
.toTypedArray()
if (neededPermissions.isNotEmpty()) {
requestPermissionLauncher.launch(neededPermissions)
} else {
onPermissionsGranted?.invoke()
}
}

Connecting to LiveKit

Note that this example hardcodes a token we generated for you that expires in 2 hours. In a real app, you’ll need your server to generate a token for you.

// !! Note !!
// This sample hardcodes a token which expires in 2 hours.
const val wsURL = "<your LiveKit server URL>"
const val token = "<generate a token>"
// In production you should generate tokens on your server, and your frontend
// should request a token from your server.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requireNeededPermissions {
setContent {
RoomScope(
url = wsURL,
token = token,
audio = true,
video = true,
connect = true,
) {
// Get all the tracks in the room.
val trackRefs = rememberTracks()
// Display the video tracks.
// Audio tracks are automatically played.
LazyColumn(modifier = Modifier.fillMaxSize()) {
items(trackRefs.size) { index ->
VideoTrackView(
trackReference = trackRefs[index],
modifier = Modifier.fillParentMaxHeight(0.5f)
)
}
}
}
}
}
}
}

(For more details, you can reference the complete quickstart app.)

Next steps

The following resources are useful for getting started with LiveKit on Android.

Generating tokens

Guide to generating authentication tokens for your users.