# Quickstart

This guide will help you quickly integrate the Stream Video Android SDK with our
library of built-in UI components via Jetpack Compose into your application using
the high-level `CallContent` component with Picture-in-Picture (PIP) support.

## Prerequisites

- Android SDK 24+ (Android 7.0)
- If you want to use Stream's built-in UI component library ensure that Jetpack Compose is already added in your app

## Add Stream library dependencies to your app-level `build.gradle.kts`

If you want to use Stream's built-in UI component library, use the following dependency in your app
Replace `x.x.x` with the latest version of our library which can be found [here](https://central.sonatype.com/artifact/io.getstream/stream-video-android-ui-Compose/versions).

```kotlin
dependencies {
  // Stream Video Android Compose UI
  implementation("io.getstream:stream-video-android-ui-compose:x.x.x")
}
```

In case you want to have your own UI and only want to use our core sdk, the dependency to be added is the following
Replace `x.x.x` with the latest version of our library which can be found [here](https://central.sonatype.com/artifact/io.getstream/stream-video-android-core/versions).

```kotlin
dependencies {
  // Stream Video Android Compose UI
  implementation("io.getstream:stream-video-android-core:x.x.x")
}
```

## Instantiating the SDK and joining a call

### Step 1 : Get your credentials

The first step is to get your credentials with which you can initialize the SDK and join a call.
For production, get these credentials from the dashboard. For testing, you can use the credentials from [our tutorial](https://getstream.io/video/sdk/android/tutorial/video-calling/).

- **`apiKey`**: Your Stream API key from the dashboard/playground
- **`userToken`**: JWT token for authentication. For production, it is recommended to generate using your backend.
- **`userId`**: A unique string identifier to identify the user joining the call.
- **`callId`**: An optional argument. It's convenient to specify an ID if the call is associated with an object in your database. For example, if you're building a ride-sharing app like Uber, you could use the ride ID as the call ID to easily align with your internal systems.

```kotlin
    // Step 1: Replace with your Stream credentials
    // Get these from: https://getstream.io/video/docs/android/playground/demo-credentials/
    val apiKey = "YOUR_API_KEY"
    val userToken = "YOUR_USER_TOKEN"
    val userId = "YOUR_USER_ID"
    val callId = "YOUR_CALL_ID"
```

### Step 2 : Creating a User

Now that you have these credentials, you need to create an instance of `User` like the following, where the `role` corresponds to one of the roles defined in your app in the dashboard

```kotlin
    // Step 2: Create a user
    val user = User(
      id = userId,
      name = "Your Name", // Display name in the UI
      image = "https://your-image-url.com/avatar.jpg", // Optional avatar
      role = "admin", // User role for the call
    )
```

### Step 3 : Creating a VideoClient

The next step is to Create the `client` using `StreamVideoBuilder` which initializes the SDK.
For this you would need the following things:

- **`context`**: Typically your `application` context should be passed here
- **`geo`**: Choose the closest region for better performance:
  - `GEO.GlobalEdgeNetwork` - Global edge network (recommended)
  - `GEO.US` - US region
  - `GEO.EU` - European region
  - `GEO.Asia` - Asian region
- **`apiKey`**: Your Stream API key from the dashboard
- **`user`**: User information for the call
- **`userToken`**: JWT token for authentication

```kotlin
    // Step 3: Initialize StreamVideo client
    val client = StreamVideoBuilder(
      context = applicationContext,
      apiKey = apiKey,
      geo = GEO.GlobalEdgeNetwork, // Choose appropriate geo region
      user = user,
      token = userToken,
    ).build()
```

### Step 4 : Getting the Call instance and joining it

Now the only step remaining to join the call, is to create a call by calling the `client`'s `call` method which which will either retrieve an existing Call instance or create a new one if it does not already exist
Note that the `join` method is a `suspend` method so it needs to be called from either a coroutine scope or a suspend method in Kotlin

```kotlin
      // Step 4: Request permissions and join the call
      val call = client.call(type = "default", id = callId)
      LaunchCallPermissions(call = call) {
        call.join(create = true) // Creates call if it doesn't exist
      }
```

Here **`default`** is The call type. There are 4 built-in call types and you can also create your own. The call type controls permissions and which features are enabled.

### Step 5 : Rendering video on UI

Now that we have joined the call, the only thing remaining is to show the Call content on the UI including your local video and the videos from other participants in the call.
For this we have a `CallContent` composable that can be used directly in your ComponentActivity

```kotlin
    setContent {
      // Step 4: Request permissions and join the call
      val call = client.call(type = "default", id = callId)
      LaunchCallPermissions(call = call) {
        call.join(create = true) // Creates call if it doesn't exist
      }

      // Step 5: Apply VideoTheme and render the call UI
      VideoTheme {
        CallContent(
          modifier = Modifier.fillMaxSize(),
          call = call,
          pictureInPictureConfiguration = PictureInPictureConfiguration(enable = true), // Enable PIP support
          onBackPressed = { finish() }, // Handle back button
          onCallAction = { callAction -> // Handles call control actions (mute, camera flip, etc.)
            // Handle call actions
            when (callAction) {
              is FlipCamera -> call.camera.flip() // Switch between front/back camera
              is ToggleCamera -> call.camera.setEnabled(callAction.isEnabled) // Enable/disable camera
              is ToggleMicrophone -> call.microphone.setEnabled(callAction.isEnabled) // Mute/unmute microphone
              is LeaveCall -> finish() //  End the call
              else -> Unit
            }
          },
        )
      }
    }
```

## Advanced Features

### Customization Options

- **Custom UI**: Use low-level components like `ParticipantVideo` and `FloatingParticipantVideo` from our UI component libraries
- **Theming**: Customize `VideoTheme` colors and styles
- **Call Types**: Use different call types for different use cases
- **Advanced Features**: Add screen sharing, recording, etc.

### UI Components

The goal of the `stream-video-android-ui-Compose` library is to make it easy to build any type of video/calling experience. You have several options for the UI:

- Build your own UI components using the state as demonstrated above
- Use our library of built-in components
- Mix and match between your own and built-in components

You can customize the built-in components using theming and modifiers. Compose is flexible, but there are limits, so if you get stuck with the built-in components, you can always work around it by building your own.

### Rendering Video

The call's state is available in [`call.state`](/video/docs/android/guides/call-and-participant-state/) and you'll often work with `call.state.participants`.
Here's a basic Compose example of how to render the video of all participants:

```kotlin
val participants by call.state.participants.collectAsState()
participants.forEach {
  val videoTrack = it.videoTrack // contains the video track
  val userName = it.userNameOrId // the user name

  ..
}
```

As shown in the example above, `participants (ParticipantState)` contains all essential information to render videos, such as audio/video tracks, user information, audio/video enabled status, etc. You can simply render the video track with our Compose components like the sample below:

```kotlin
ParticipantVideo(
  modifier = Modifier
    .fillMaxSize()
    .clip(RoundedCornerShape(16.dp)),
  call = call,
  participant = participant
)
```

The fields available on the participants are documented in the
[participant state documentation](https://github.com/GetStream/stream-video-android/blob/main/docusaurus/docs/Android/02-guides/03-call-and-participant-state.mdx#participant-state).

### Camera & Audio

Most video apps will show buttons to mute/unmute the audio or video and flip the camera.
The example below shows how to use the camera:

```kotlin
val call = client.call("default", "123")
val camera = call.camera
camera.setEnabled(true)  // Enable camera
camera.setEnabled(false) // Disable camera
camera.flip()            // Switch front/back
```

Here's how to enable the microphone or control the speaker volume:

```kotlin
call.microphone.setEnabled(true)  // Enable microphone
call.microphone.setEnabled(false) // Disable microphone

call.speaker.setVolume(100)       // Set volume to max
call.speaker.setVolume(0)         // Mute speaker
call.speaker.setEnabled(true)     // Enable speakerphone
```

### Incoming/Outgoing Calls

If you intend to support incoming and outgoing calls, the SDK must know which activities to call in the notification `PendingIntent`.
To accept and send incoming calls via the default notification handler provided by the SDK, you need to handle the intent actions in your manifest.

The SDK defines the following actions:

```kotlin
ACTION_NOTIFICATION = "io.getstream.video.android.action.NOTIFICATION"
ACTION_LIVE_CALL = "io.getstream.video.android.action.LIVE_CALL"
ACTION_INCOMING_CALL = "io.getstream.video.android.action.INCOMING_CALL"
ACTION_OUTGOING_CALL = "io.getstream.video.android.action.OUTGOING_CALL"
ACTION_ACCEPT_CALL = "io.getstream.video.android.action.ACCEPT_CALL"
ACTION_REJECT_CALL = "io.getstream.video.android.action.REJECT_CALL"
ACTION_LEAVE_CALL = "io.getstream.video.android.action.LEAVE_CALL"
ACTION_ONGOING_CALL = "io.getstream.video.android.action.ONGOING_CALL"
```

If you do not support incoming and outgoing calls, you can skip the `<intent-filter>` declarations.

To fully utilize the incoming/outgoing feature, the SDK needs to know which activity these actions resolve to in order to construct the `PendingIntent`s.
You must provide this information in your manifest.

The `ACTION_REJECT_CALL` and `ACTION_LEAVE_CALL` are handled by default by the SDK and you do not need to do anything about them.
The `ACTION_ONGOING_CALL` does not mandate an `<intent-filter>`, but omitting this will result in reduced functionality where the user will not be returned to your app if the notification is clicked.

All other actions must be declared in your manifest, otherwise the internal `CallService` will fail to create the required notification for a foreground service and thus not start, resulting in an exception.

```xml
<manifest>
  <application>
    <activity
            android:name=".Activity"
            android:exported="false"
            android:showOnLockScreen="true"
            android:showWhenLocked="true"
    >
      <intent-filter android:priority="1">
        <action android:name="io.getstream.video.android.action.INCOMING_CALL" />
        <action android:name="io.getstream.video.android.action.ONGOING_CALL" />
        <action android:name="io.getstream.video.android.action.ACCEPT_CALL" />
        <action android:name="io.getstream.video.android.action.OUTGOING_CALL" />
        <action android:name="io.getstream.video.android.action.NOTIFICATION" />
      </intent-filter>
    </activity>
  </application>
</manifest>
```

> **Note**
>
> You can handle multiple `IntentFilter` within a single `activity` if you prefer, or have separate activities for each action.

For more details on notification customization, see our [Push Notification Guide](/video/docs/android/advanced/incoming-calls/push-notifications/).

## Additional Resources

- [Stream Video Android Documentation](/video/docs/android/)
- [Sample Apps](https://github.com/GetStream/stream-video-android)
- [Community Support](https://github.com/GetStream/stream-video-android/discussions)


---

This page was last updated at 2026-03-06T17:08:44.822Z.

For the most recent version of this documentation, visit [https://getstream.io/video/docs/android/basics/quickstart/](https://getstream.io/video/docs/android/basics/quickstart/).