Skip to navigation

Kotlin SDK

ElevenAgents SDK: implementeer binnen enkele minuten aangepaste, interactieve spraakagents in Android-apps.

Raadpleeg het ElevenAgents-overzicht voor een uitleg over hoe ElevenAgents werkt.

Installatie

Voeg de ElevenLabs SDK toe aan je Android-project door de volgende dependency op te nemen in het build.gradle-bestand op appniveau:

build.gradle.kts
dependencies {
// ElevenLabs Agents SDK (Android)
implementation("io.elevenlabs:elevenlabs-android:<latest>")
// Kotlin coroutines, AndroidX, etc., as needed by your app
}

Een voorbeeld-Android-app die deze SDK gebruikt, vind je hier

Vereisten

  • Android API-niveau 21 (Android 5.0) of hoger
  • Internettoestemming voor API-calls
  • Microfoontoestemming voor spraakinvoer
  • Netwerkbeveiligingsconfiguratie voor HTTPS-calls

Configuratie

Manifestconfiguratie

Voeg de benodigde toestemmingen toe aan je AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

Runtime-toestemmingen

Voor Android 6.0 (API-niveau 23) en hoger moet je microfoontoestemming tijdens runtime aanvragen:

import android.Manifest
import android.content.pm.PackageManager
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
private fun requestMicrophonePermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) {
// Show explanation to the user
showPermissionExplanationDialog()
} else {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.RECORD_AUDIO),
MICROPHONE_PERMISSION_REQUEST_CODE
)
}
}
}

Gebruik

Initialiseer de ElevenLabs SDK in je Application-klasse of hoofdactiviteit:

Start een conversatiesessie met een van de volgende opties:

  • Openbare agent: geef agentId door
  • Private agent: geef conversationToken door dat door je backend is verstrekt (stel je API-sleutel nooit bloot aan de client).
import io.elevenlabs.ConversationClient
import io.elevenlabs.ConversationConfig
import io.elevenlabs.ConversationSession
import io.elevenlabs.ClientTool
import io.elevenlabs.ClientToolResult
// Start a public agent session (token generated for you)
val config = ConversationConfig(
agentId = "<your_public_agent_id>", // OR conversationToken = "<token>"
userId = "your-user-id",
// Optional callbacks
onConnect = { conversationId ->
// Called when the conversation is connected and returns the conversation ID. You can access conversationId via session.getId() too
},
onMessage = { source, messageJson ->
// Raw JSON messages from data channel; useful for logging/telemetry
},
onModeChange = { mode ->
// "speaking" | "listening" — drive UI indicators
},
onStatusChange = { status ->
// "connected" | "connecting" | "disconnected"
},
onCanSendFeedbackChange = { canSend ->
// Enable/disable thumbs up/down buttons for feedback reporting
},
onUnhandledClientToolCall = { call ->
// Agent requested a client tool not registered on the device
},
onVadScore = { score ->
// Voice Activity Detection score, range from 0 to 1 where higher values indicate higher confidence of speech
},
onAudioAlignment = { alignment ->
// Character-level timing data for synchronized text display
val chars = alignment["chars"] as? List<*>
val startTimes = alignment["char_start_times_ms"] as? List<*>
val durations = alignment["char_durations_ms"] as? List<*>
Log.d("ExampleApp", "Audio alignment: $chars")
},
// List of client tools the agent can invoke
clientTools = mapOf(
"logMessage" to object : ClientTool {
override suspend fun execute(parameters: Map<String, Any>): ClientToolResult {
val message = parameters["message"] as? String
Log.d("ExampleApp", "[INFO] Client Tool Log: $message")
return ClientToolResult.success("Message logged successfully")
}
}
),
)
// In an Activity context
val session: ConversationSession = ConversationClient.startSession(config, this)

Houd er rekening mee dat ElevenAgents microfoontoegang vereist. Overweeg om in de UI van je app uit te leggen waarom toestemming nodig is en deze aan te vragen voordat de conversatie begint, vooral op Android 6.0+ waar runtime-toestemmingen vereist zijn.

Als een tool op de server is geconfigureerd met expects_response=false, retourneer dan null vanuit execute om het terugsturen van een toolresultaat naar de agent over te slaan.

Openbare versus private agents

  • Openbare agents (geen authenticatie): Initialiseer met agentId in ConversationConfig. De SDK vraagt een conversatietoken aan bij ElevenLabs zonder dat een API-sleutel op het apparaat nodig is.
  • Private agents (authenticatie): Initialiseer met conversationToken in ConversationConfig. Je server vraagt een conversatietoken aan bij ElevenLabs met je ElevenLabs API-sleutel.
Sluit API-sleutels nooit in clients in. Ze kunnen eenvoudig worden geëxtraheerd en kwaadwillig worden gebruikt.

Clienttools

Registreer clienttools zodat de agent lokale mogelijkheden op het apparaat kan aanroepen.

val config = ConversationConfig(
agentId = "<public_agent>",
clientTools = mapOf(
"logMessage" to object : io.elevenlabs.ClientTool {
override suspend fun execute(parameters: Map<String, Any>): io.elevenlabs.ClientToolResult? {
val message = parameters["message"] as? String ?: return io.elevenlabs.ClientToolResult.failure("Missing 'message'")
android.util.Log.d("ClientTool", "Log: $message")
return null // No response needed for fire-and-forget tools
}
}
)
)

Wanneer de agent een client_tool_call uitvoert, voert de SDK de overeenkomende tool uit en antwoordt deze met een client_tool_result. Als de tool niet is geregistreerd, wordt onUnhandledClientToolCall aangeroepen en wordt een foutresultaat naar de agent teruggestuurd (als een antwoord wordt verwacht).

Overzicht van callbacks

  • onConnect - Wordt aangeroepen wanneer de WebRTC-verbinding tot stand is gebracht. Retourneert de conversatie-ID.
  • onMessage - Wordt aangeroepen wanneer een nieuw bericht wordt ontvangen. Dit kunnen voorlopige of definitieve transcripties van de stem van de gebruiker zijn, antwoorden die door een LLM zijn geproduceerd, of debugberichten. Geeft de bron ("ai" of "user") en het onbewerkte JSON-bericht.
  • onModeChange - Wordt aangeroepen wanneer de conversatiemodus verandert. Dit is nuttig om aan te geven of de agent spreekt ("speaking") of luistert ("listening").
  • onStatusChange - Wordt aangeroepen wanneer de conversatiestatus verandert ("connected", "connecting" of "disconnected").
  • onCanSendFeedbackChange - Wordt aangeroepen wanneer de mogelijkheid om feedback te versturen verandert. Schakelt feedbackknoppen in of uit.
  • onUnhandledClientToolCall - Wordt aangeroepen wanneer de agent een clienttool aanvraagt die niet op het apparaat is geregistreerd.
  • onVadScore - Wordt aangeroepen wanneer de score voor spraakactiviteitsdetectie verandert. Bereik van 0 tot 1, waarbij hogere waarden een grotere zekerheid van spraak aangeven.
  • onAudioAlignment - Wordt aangeroepen wanneer audio-uitlijningsgegevens worden ontvangen en timinginformatie op tekenniveau voor spraak van de agent biedt.

Niet alle clientevents zijn standaard ingeschakeld voor een agent. Als je een callback hebt ingeschakeld maar geen events ontvangt, controleer dan of voor je ElevenLabs-agent het bijbehorende event is ingeschakeld. Dit kun je doen op het tabblad “Advanced” in de agentinstellingen in het ElevenLabs-dashboard.

Methoden

startSession

De methode startSession start de WebRTC-verbinding en gebruikt de microfoon om met de ElevenLabs Agents-agent te communiceren.

Openbare agents

Voor openbare agents (dat wil zeggen: agents waarvoor authenticatie niet is ingeschakeld) is alleen de agentId vereist. Je kunt de agent-ID ophalen via de ElevenLabs-UI.

val session = ConversationClient.startSession(
config = ConversationConfig(
agentId = "your-agent-id"
),
context = this
)
Private agents

Voor private agents moet je een conversationToken doorgeven dat je via de ElevenLabs API hebt verkregen. Voor het genereren van dit token is een ElevenLabs API-sleutel vereist.

De conversationToken is 10 minuten geldig.
// Server-side token generation (Node.js example)
app.get("/conversation-token", yourAuthMiddleware, async (req, res) => {
const response = await fetch(
`https://api.elevenlabs.io/v1/convai/conversation/token?agent_id=${process.env.AGENT_ID}`,
{
headers: {
// Requesting a conversation token requires your ElevenLabs API key
// Do NOT expose your API key to the client!
"xi-api-key": process.env.ELEVENLABS_API_KEY,
},
}
);
if (!response.ok) {
return res.status(500).send("Failed to get conversation token");
}
const body = await response.json();
res.send(body.token);
});

Geef het token vervolgens door aan de methode startSession. Houd er rekening mee dat voor private agents alleen de conversationToken vereist is.

// Get conversation token from your server
val conversationToken = fetchConversationTokenFromServer()
// For private agents, pass in the conversation token
val session = ConversationClient.startSession(
config = ConversationConfig(
conversationToken = conversationToken
),
context = this
)

Je kunt optioneel een gebruikers-ID doorgeven om de gebruiker in de conversatie te identificeren. Dit kan je eigen klant-ID zijn. Deze wordt opgenomen in de gegevens voor het starten van de conversatie die naar de server worden gestuurd.

val session = ConversationClient.startSession(
config = ConversationConfig(
agentId = "your-agent-id",
userId = "your-user-id"
),
context = this
)

endSession

Een methode om de conversatie handmatig te beëindigen. De methode verbreekt de verbinding en beëindigt de conversatie.

session.endSession()

sendUserMessage

Stuur een tekstbericht naar de agent tijdens een actieve conversatie. Hiermee wordt een antwoord van de agent geactiveerd.

session.sendUserMessage("Hello, how can you help me?")

sendContextualUpdate

Stuurt contextuele informatie naar de agent die geen antwoord activeert.

session.sendContextualUpdate(
"User navigated to the profile page. Consider this for next response."
)

sendFeedback

Geef feedback over de kwaliteit van de conversatie. Dit helpt de prestaties van de agent te verbeteren. Gebruik onCanSendFeedbackChange om je UI voor duim omhoog/omlaag in te schakelen wanneer feedback is toegestaan.

// Positive feedback
session.sendFeedback(true)
// Negative feedback
session.sendFeedback(false)

sendUserActivity

Meldt gebruikersactiviteit aan de agent om onderbrekingen te voorkomen. Handig wanneer de gebruiker de app actief gebruikt en de agent moet pauzeren met spreken, bijvoorbeeld wanneer de gebruiker in een chat typt.

De agent pauzeert ongeveer 2 seconden met spreken nadat dit signaal is ontvangen.

session.sendUserActivity()

getId

Haal de conversatie-ID op.

val conversationId = session.getId()
Log.d("Conversation", "Conversation ID: $conversationId")
// e.g., "conv_123"

Dempen/dempen opheffen

session.toggleMute()
session.setMicMuted(true) // mute
session.setMicMuted(false) // unmute

Controleer session.isMuted om het UI-label bij te werken tussen “Dempen” en “Dempen opheffen”.

Eigenschappen

status

Haal de huidige status van de conversatie op.

val status = session.status
Log.d("Conversation", "Current status: $status")
// Values: DISCONNECTED, CONNECTING, CONNECTED

ProGuard / R8

Als je verkleint/obfusceert, zorg er dan voor dat Gson-modellen en LiveKit behouden blijven. Voorbeeldregels (pas ze waar nodig aan):

-keep class io.elevenlabs.** { *; }
-keep class io.livekit.** { *; }
-keepattributes *Annotation*

Problemen oplossen

  • Zorg dat tijdens runtime microfoontoestemming is verleend
  • Als opnieuw verbinden vastloopt, controleer dan of je app session.endSession() aanroept en of je een nieuwe sessie-instantie start voordat je opnieuw verbinding maakt
  • Controleer bij emulators of audio-invoer-/uitvoerroutes werken; fysieke apparaten werken doorgaans betrouwbaarder

Voorbeeldimplementatie

Bekijk voor een voorbeeldimplementatie de voorbeeldapp in de ElevenLabs Android SDK-repository. De app toont:

  • Verbinden/verbreken met één tik
  • Indicator voor spreken/luisteren
  • Feedbackknoppen met UI in-/uitschakelen
  • Typindicator via sendUserActivity()
  • Contextuele berichten en gebruikersberichten vanuit een invoerveld
  • Knop voor microfoon dempen/dempen opheffen