# Android Quickstart

> Build a native Android voice AI client with Jetpack Compose.

A Kotlin and Jetpack Compose voice-agent client for Agora Conversational AI. The app owns the RTC/RTM lifecycle and renders live transcript via Agora's official Android ConversationalAI toolkit, talking to a bundled keyless Python backend.

- Author: Agora
- Updated: 2026-06-14
- Difficulty: Intermediate
- Categories: voice-ai
- Platforms: Android
- Use cases: Quickstart, Voice AI
- Capabilities: Conversational AI, Voice Agent, Android, Jetpack Compose
- [Recipe page](https://recipes.agora.io/recipes/android-quickstart)
- [Implementation repository](https://github.com/AgoraIO-Conversational-AI/recipe-client-android-quickstart)
- [Source recipe](https://github.com/AgoraIO-Conversational-AI/recipe-client-android-quickstart/blob/main/README.md)
- [Raw source Markdown](https://raw.githubusercontent.com/AgoraIO-Conversational-AI/recipe-client-android-quickstart/main/README.md)
- [All recipes](https://recipes.agora.io/llms.txt)

## Use with Agora CLI

agora init my-android-quickstart --recipe android-quickstart

## Implementation guide

# recipe-client-android-quickstart

A native **Android (Kotlin + Jetpack Compose)** voice-agent quickstart. It talks to a bundled,
**key-less** Python backend and renders the live transcript using Agora's official
`ConversationalAIAPI` Kotlin toolkit. The agent greets you on join — no human speech is
required to see it working.

The app owns the Agora **RTC + RTM** lifecycle; the toolkit parses the agent's messages
into transcript and agent-state callbacks.

## Layout

- `server/` — the reused key-less Python/FastAPI backend (`GET /get_config`, `POST /startAgent`,
  `POST /stopAgent`). A managed cascade means you only need `AGORA_APP_ID` / `AGORA_APP_CERTIFICATE`.
- `android/` — the Gradle / Kotlin / Compose app, with Agora RTC, RTM, and Agent Client Toolkit
  dependencies from Maven Central.

## Zero-key

No Agora secret ships in the app. The backend mints the RTC/RTM token and starts the managed agent;
the only secrets it needs are `AGORA_APP_ID` and `AGORA_APP_CERTIFICATE` in `server/.env.local`.

## Run it

### 1. Backend

macOS/Linux:

```bash
cd server
uv venv venv && . venv/bin/activate
uv pip install -r requirements.txt -r requirements-dev.txt
python src/server.py        # serves on 0.0.0.0:8000
```

Windows PowerShell:

```powershell
cd server
py -3 -m venv venv
.\venv\Scripts\python.exe -m pip install -r requirements.txt -r requirements-dev.txt
.\venv\Scripts\python.exe src\server.py
```

(or `pytest -q` to run the server tests).

### 2. Android app

```bash
cd android
./gradlew installDebug      # to a running emulator or a connected device
```

…or open `android/` in Android Studio and Run.

The app reads the backend URL from the `AGENT_BACKEND_URL` build-config field, default
`http://10.0.2.2:8000` — **`10.0.2.2` is the Android emulator's alias for the host machine**, so the
emulator reaches the server running on your laptop. A **physical device** must instead point at the
host's LAN IP (edit `AGENT_BACKEND_URL` in `android/app/build.gradle.kts`).

`RECORD_AUDIO` + `INTERNET` permissions are requested; cleartext traffic is allowed for the dev
localhost.

## How it works (lifecycle)

1. `GET /get_config` → `{app_id, token, uid, channel_name, agent_uid}`.
2. Create the RTC engine; `loadAudioSettings()`; **join with `ChannelMediaOptions`** —
   `publishMicrophoneTrack = true`, `autoSubscribeAudio = true`, `clientRoleType = BROADCASTER`.
3. Create + **log in** the RTM client.
4. `ConversationalAIAPIConfig(rtcEngine, rtmClient, renderMode = Text)` → `ConversationalAIAPIImpl`;
   `addHandler(...)`; **`subscribeMessage(channelName)` BEFORE `POST /startAgent`**.
5. `POST /startAgent` with `rtcUid = agent_uid`, `userUid = uid`.
6. `onTranscriptUpdated` rows are **upserted by `(turnId, type)`** (a turn has separate user + agent
   rows); the Compose `LazyColumn` is keyed by the composite `"$turnId-$type"`.
7. End: `unsubscribeMessage` → `POST /stopAgent` → `leaveChannel` → RTM `logout` → `destroy`.

The toolkit is configured with **`TranscriptRenderMode.Text`** (full-text rendering) for this pilot.

## SDKs

Resolved from Maven Central (+ jitpack):

- `io.agora.rtc:full-sdk:4.5.1`
- `io.agora:agora-rtm:2.2.3`
- `io.agora.agents:agora-agent-client-toolkit:2.9.0`

The Android app requires API 26 or newer, matching the Agent Client Toolkit 2.9.0 AAR metadata.

## Agent Client Toolkit

The transcript and agent-event implementation comes from the published
`io.agora.agents:agora-agent-client-toolkit:2.9.0` Maven artifact. Application code imports its
public API from `io.agora.conversational.api`.

## License

MIT — see [`LICENSE`](https://github.com/AgoraIO-Conversational-AI/recipe-client-android-quickstart/blob/main/LICENSE).


## Recipe prompt

You are implementing the "Android Quickstart" recipe in this project.

Read the recipe markdown first:
https://raw.githubusercontent.com/AgoraIO-Conversational-AI/recipe-client-android-quickstart/main/README.md

Use the source repository for cross-reference:
https://github.com/AgoraIO-Conversational-AI/recipe-client-android-quickstart

Build this recipe into the user's app using the markdown as the implementation guide. Inspect related source files through the repository links when the recipe points to them. Ask before installing new dependencies.
