Skip to main content

Telnyx Android WebRTC SDK

JitPack Unit Tests Enable Telnyx real-time communication services on Android

Table of Contents

Project structure:

  • SDK project: sdk module, containing all Telnyx SDK components as well as tests.
  • Demo application: app module, containing a sample demo application utilizing the sdk module.

Project Setup:

  1. Clone the repository
  2. Open the cloned repository in Android Studio and hit the build button to build both the sdk and sample app:

  3. Connect a device or start an emulated device and hit the run button

  4. Enjoy 😎

SIP Credentials

In order to start making and receiving calls using the TelnyxRTC SDK you will need to get SIP Credentials:
  1. Access to https://portal.telnyx.com/
  2. Sign up for a Telnyx Account.
  3. Create a Credential Connection to configure how you connect your calls.
  4. Create an Outbound Voice Profile to configure your outbound call settings and assign it to your Credential Connection.
For more information on how to generate SIP credentials check the Telnyx WebRTC quickstart guide.

Usage

Telnyx Client

NOTE: Remember to add and handle INTERNET, RECORD_AUDIO and ACCESS_NETWORK_STATE permissions

To initialize the TelnyxClient you will have to provide the application context. Once an instance is created, you can call the .connect() method to connect to the socket. An error will appear as a socket response if there is no network available:

Logging into Telnyx Client

To log into the Telnyx WebRTC client, you’ll need to authenticate using a Telnyx SIP Connection. Follow our quickstart guide to create JWTs (JSON Web Tokens) to authenticate. To log in with a token we use the tokinLogin() method. You can also authenticate directly with the SIP Connection username and password with the credentialLogin() method:
Note: tokenConfig and credentialConfig are data classes that represent login settings for the client to use. They look like this:

Creating a call invitation

In order to make a call invitation, you need to provide your callerName, callerNumber, the destinationNumber (or SIP credential), and your clientState (any String value).

Accepting a call

In order to be able to accept a call, we first need to listen for invitations. We do this by getting the Telnyx Socket Response. Recommended approach using SharedFlow (Kotlin Flows):
Deprecated approach using LiveData:
We can then use this method to create a listener that listens for an invitation - in this example we assume getSocketResponse is a method within a ViewModel. Using SharedFlow (Recommended):
Using LiveData (Deprecated):
When we receive a call we will receive an InviteResponse data class that contains the details we need to accept the call. We can then call the acceptCall method in TelnyxClient from our ViewModel:

Handling Multiple Calls

The Telnyx WebRTC SDK allows for multiple calls to be handled at once. You can use the callId to differentiate the calls..
With the current call object, you can perform actions such as:
  1. Hold/UnHold currentCall.onHoldUnholdPressed(callId: UUID)
  2. Mute/UnMute currentCall.onMuteUnmutePressed()
  3. AcceptCall currentCall.acceptCall(...)
  4. EndCall currentCall.endCall(callId: UUID)

Adding push notifications

The Telnyx Android Client WebRTC SDK makes use of Firebase Cloud Messaging in order to deliver push notifications. If you want to receive notifications for incoming calls on your Android mobile device you have to enable Firebase Cloud Messaging within your application. In order to do this you need to:
  1. Set up a Firebase console account
  2. Create a Firebase project
  3. Add Firebase to your Android Application
  4. Setup a Push Credential within the Telnyx Portal
  5. Generate a Firebase Cloud Messaging instance token
  6. Send the token with your login message

Providing our SDK with the FCM Token to receive Push Notifications

You will need to provide the connect(..) method with a CredentialConfig or TokenConfig that contains an fcmToken value (received from FirebaseMessaging like in the above code snippet). Once the fcmToken has been provided, we can provide push notifications to the application when a call is received but the device is not actively connected to the socket. (eg. Killed or Backgrounded states)
For a detailed tutorial, please visit our official Push Notification Docs

Custom Logging

The Telnyx WebRTC SDK allows you to implement your own custom logging solution by providing a TxLogger implementation. This gives you full control over how logs are handled, allowing you to route them to your own logging frameworks or analytics services.

Using Custom Logger

  1. Create a class that implements the TxLogger interface:
  1. Pass your custom logger when creating the configuration:

Default Behavior

If no custom logger is provided, the SDK will use its default logging implementation based on Android’s Log class. The logLevel parameter still controls which logs are generated, regardless of whether you’re using a custom logger or the default one.

Trickle ICE

The SDK supports Trickle ICE, which enables faster call setup by sending ICE candidates incrementally as they are discovered, rather than waiting for all candidates before establishing the connection.

Key Features

  • Faster Call Establishment: Candidates are sent immediately as discovered, reducing connection time
  • Automatic Management: No configuration required - the SDK handles Trickle ICE automatically
  • Smart Queuing: Answering side queues candidates until ANSWER is sent to prevent race conditions
  • Candidate Cleaning: WebRTC extensions are removed for maximum server compatibility

How It Works

Outbound Calls: Candidates are sent immediately as they are generated Inbound Calls: Candidates are queued until the call is answered, then flushed all at once followed by real-time sending of new candidates This approach prevents race conditions where candidates might arrive before the answer, ensuring reliable call setup.

Important Notes

  • Codec Negotiation: The final codec used will be negotiated between your preferred codecs and what the remote party supports.
  • Fallback Behavior: If none of your preferred codecs are supported, the system will automatically fall back to a mutually supported codec.
  • Order Matters: Codecs are prioritized in the order you specify them in the list.
  • Platform Support: All codecs listed are supported by the Telnyx platform, but actual availability may depend on the remote party’s capabilities.

Best Practices

Handling Push Notifications

In order to properly handle push notifications, we recommend using a call type Foreground Service with a broadcast receiver to show push notifications. An answer or reject call intent with telnyxPushMetaData can then be passed to the MainActivity for processing. Declining Push Notifications The SDK now provides a simplified way to decline incoming calls from push notifications using the connectWithDeclinePush() method. This new approach automatically handles the decline process by:
  1. Connecting to the socket with a decline_push parameter
  2. Sending the appropriate decline message
  3. Disconnecting automatically
This eliminates the need for the complex flow of launching the app, waiting for invites, and manually sending bye messages. Use connectWithDeclinePush() instead of the standard connect() method when declining calls from push notifications. Best Practices for Push Notifications
  • Play a ringtone when a call is received from push notification using the RingtoneManager
  • Make Sure to set these flags for your pendingIntents, so the values get updated anytime when the notification is clicked

Android 14 Requirements

In order to receive push notifications on Android 14, you will need to add the following permissions to your AndroidManifest.xml file and request a few at runtime:

Handling Missed Call Notifications

The backend sends a missed call notification when a call is ended while the socket is not yet connected. It comes with the Missed call! message. In order to handle missed call notifications, you can use the following code snippet in the FirebaseMessagingService class:

Handling Multiple Calls

The Telnyx WebRTC SDK allows for multiple calls to be handled at once. You can use the callId to differentiate the calls.

AI Agent Usage

The Android WebRTC SDK supports Voice AI Agent implementations. To get started, follow the steps described here to build your first AI Assistant. Once your AI Agent is up and running, you can use the SDK to communicate with your AI Agent with the following steps:

1. Logging in to communicate with the AI Agent

To connect with an AI Assistant, you can use the connectAnonymously method. This allows you to establish a connection without traditional authentication credentials. This method takes a targetId which is the ID of your AI assistant, and an optional targetVersionId. If a targetVersionId is not provided, the SDK will use the latest version available. Note: After a successful anonymous connection, any subsequent call, regardless of the destination, will be directed to the specified AI Assistant. Here’s an example of how to use it:
Once connected, you can use the standard newInvite method to start a conversation with the AI Assistant.

2. Starting a Conversation with the AI Assistant

After a successful anonymousLogin, you can initiate a call to your AI Assistant using the newInvite method. Because the session is now locked to the AI Assistant, the destinationNumber parameter in the newInvite method will be ignored. Any values provided for callerName and callerNumber will be passed on, but the call will always be routed to the AI Assistant specified during the login. Here is an example of how to start the call:
Note that you can also provide customHeaders in the newInvite method. These headers need to start with the X- prefix and will be mapped to dynamic variables in the AI assistant (e.g., X-Account-Number becomes {{account_number}}). Hyphens in header names are converted to underscores in variable names. The call will be automatically answered by the AI Assistant. From this point on, the call flow is handled in the same way as any other answered call, allowing you to use standard call control methods like endCall, mute, etc.

3. Receiving Transcript Updates

During an AI Assistant conversation, the SDK provides real-time transcript updates that include both the caller’s speech and the AI Assistant’s responses. This allows you to display a live conversation transcript in your application. To receive transcript updates, use the transcriptUpdateFlow SharedFlow on your TelnyxClient instance:
The TranscriptItem contains the following properties:
  • id: Unique identifier for the transcript item
  • role: Either “user” (for the caller) or “assistant” (for the AI Agent)
  • content: The transcribed text content
  • timestamp: When the transcript item was created
  • isPartial: Whether this is a partial response (for streaming AI responses)
You can also manually retrieve the current transcript at any time:
Note: Transcript updates are only available during AI Assistant conversations initiated through anonymousLogin. Regular calls between users do not provide transcript functionality.

4. Sending a text message to the AI Agent

In addition to voice conversation, you can send text messages directly to the AI Agent during an active call. This allows for mixed-mode communication where users can both speak and type messages to the AI Assistant. To send a text message to the AI Agent, use the sendAIAssistantMessage method:
Important Notes:
  • The sendAIAssistantMessage method is only available during AI Assistant conversations
  • Text messages sent this way will appear in the transcript updates alongside spoken conversation
  • The AI Agent will process and respond to text messages just like spoken input
  • You must have an active call established before sending text messages
This feature enables rich conversational experiences where users can seamlessly switch between voice and text communication with the AI Assistant. For detailed documentation and advanced usage examples, see the AI Agent documentation.

ProGuard changes

NOTE: In the case that you need to modify your application’s proguard settings in order to obfuscate your code, such as we have done below: app/build.gradle
please keep in mind that you will need to add the following rules to the proguard-rules.pro file in your app in order for the SDK to continue functioning app/proguard-rules.pro

Additional Resources

Questions? Comments? Building something rad? Join our Slack channel and share.

License

MIT Licence © Telnyx