Skip to main content
Implement native VoIP calling that works when your app is in the background or killed. This guide shows how to integrate Android’s Telecom framework with CometChat to display system call UI, handle calls from the lock screen, and provide a native calling experience.

Overview

VoIP calling differs from basic in-app ringing by leveraging Android’s ConnectionService to:
  • Show incoming calls on lock screen with system UI
  • Handle calls when app is in background or killed
  • Integrate with Bluetooth, car systems, and wearables
  • Provide consistent call experience across Android devices

Prerequisites

Before implementing VoIP calling, ensure you have:
This documentation builds on the Ringing functionality. Make sure you understand basic call signaling before implementing VoIP.

Architecture Overview

The VoIP implementation consists of several components working together:

Step 1: Configure Push Notifications

Push notifications are essential for receiving incoming calls when your app is not in the foreground. When a call is initiated, CometChat sends a push notification to the receiver’s device.
For detailed FCM setup instructions, see the Android Push Notifications documentation.

1.1 Add FCM Dependencies

Add Firebase Messaging to your build.gradle:

1.2 Create FirebaseMessagingService

This service receives push notifications from FCM. When a call notification arrives, it extracts the call data and decides how to display the incoming call based on the app’s state.

1.3 Create CallData Model

The CallData class is a simple data container that holds all information about an incoming or outgoing call. It implements Parcelable so it can be passed between Android components (Activities, Services, BroadcastReceivers).

Step 2: Register PhoneAccount

A PhoneAccount tells Android that your app can handle phone calls. This registration is required for the system to route incoming calls to your app and display the native call UI.

2.1 Create PhoneAccountManager

This singleton class handles registering your app with Android’s Telecom system. The PhoneAccount must be registered before you can receive or make VoIP calls.

2.2 Register on App Start

Register the PhoneAccount when your app starts. This should be done in your Application class to ensure it’s registered before any calls can be received.

Step 3: Implement ConnectionService

The ConnectionService is the core component that bridges your app with Android’s Telecom framework. It creates Connection objects that represent individual calls and handle user interactions.

3.1 Create CallConnectionService

This service is called by Android when a new incoming or outgoing call needs to be created. It’s responsible for creating Connection objects that manage the call state.

3.2 Create CallConnection

The Connection class represents an individual call. It receives callbacks from Android when the user interacts with the call (answer, reject, hold, etc.) and is responsible for updating the call state and communicating with CometChat.

3.3 Create CallConnectionHolder

This singleton holds a reference to the active Connection so it can be accessed from other components (like the CallActivity or BroadcastReceiver).

Step 4: Create CallNotificationManager

This class is responsible for showing incoming calls to the user. It first tries to use the system call UI via TelecomManager, and falls back to a high-priority notification if that fails.

Step 5: Create CallActionReceiver

This BroadcastReceiver handles the Accept and Decline button taps from the fallback notification.

Step 6: Create CallActivity

The CallActivity hosts the actual call UI using CometChat’s Calls SDK. It joins the call session and handles the call lifecycle.

Step 7: Configure AndroidManifest

Add all required permissions and component declarations to your AndroidManifest.xml:

Step 8: Initiate Outgoing Calls

To make an outgoing VoIP call, use the CometChat Chat SDK to initiate the call, then join the session:

Complete Flow Diagram

This diagram shows the complete flow for both incoming and outgoing VoIP calls:

Troubleshooting