Coming from the earlier ringing flow? The Chat SDK’s calling methods (
CometChat.initiateCall, acceptCall, rejectCall, endCall, CallListener) are superseded by the Calls SDK and no longer used; a coming Chat SDK release marks them deprecated. This page describes the replacement. See Migrating from legacy ringing for a method-by-method mapping.How ringing works
The caller creates the call with the Calls SDK. The CometChat backend sends a push to the callee. The Push SDK rings the callee’s device, and when the callee answers, your call screen joins the session. The caller’s app learns that the callee is ringing and has answered from the Calls SDK, without joining the session first. What each side sees:Prerequisites
- Calls SDK set up and the user logged in.
- Push notifications configured with the Push Notifications SDK 2.0 calls module. The whole push side of ringing is on the Push ringing page; this page assumes it is done.
RECORD_AUDIOandCAMERAgranted at runtime. The Calls SDK’s manifest already declares them, so there is nothing to add to yours.minSdk 26,compileSdk 36and Android Gradle Plugin 8.9.1 or later: the Push Notifications SDK 2.0 depends onandroidx.core1.18, which requires them.
build.gradle.kts
Start a call
CometChatCalls.initiateCall creates the call on the backend, which rings the callee, and prepares the caller’s media session. The caller does not join yet.
- Kotlin
- Java
InitiatedCall gives you sessionId, messageId (the id of the call message in the conversation), sender, senderName, senderAvatar, receiver, receiverType, type, status, initiatedAt and conversationId.
There is no client-side ring timeout. The callee’s device stops at the ring window the backend sends in the push (45 seconds by default) and ends the call as
unanswered, which closes the caller’s call too. If the callee’s device is never reached, nothing ends the caller’s ringing until its prepared session expires after 5 minutes, so run your own timer on the caller and end the call as unanswered after the same window, as shown under Ring timeout.Show “Ringing…” and detect the answer
The caller stays on the session thatinitiateCall prepared and listens to it. Do not call joinSession yet: joining only when the callee has joined keeps the caller’s media off until there is someone to talk to, and it is what makes the two events below arrive.
- Kotlin
- Java
Both listeners are lifecycle-aware: pass your activity or fragment as the
LifecycleOwner and the SDK removes them when it is destroyed.
Listen for calls starting and ending
CometChatCalls.addIncomingCallListener is the one place a call announces itself and its end, on both sides. The Push SDK feeds it from the push, so it fires even when nothing of yours was running when the push arrived.
- Kotlin
- Java
Answer a call
The Push SDK rings and, on Answer, asks for the microphone (and the camera for a video call), then starts the activity you registered withPNConfiguration.Builder.setAnswerActivity. That activity reads the call from its intent and joins. There is no separate “accept” call to make.
- Kotlin
- Java
IncomingCall carries sessionId, callerUid, callerName, callerAvatarUrl, callType, receiverType, conversationId and isVideo.
Join the session
Both sides join the same way: the callee from the answer activity, the caller fromonParticipantJoined. joinSession takes over the session that was prepared earlier, so it connects almost at once. On a prepared session the settings passed to joinSession are ignored: the ones frozen when the session was prepared apply. That is the caller’s options.sessionSettings; the callee’s session is prepared by the Push SDK with its own settings (session type and peer call), so layout or hidden-button settings passed by the callee have no effect.
- Kotlin
- Java
Decline a call
Declining is handled by the Push SDK: the Decline button on the notification and on its incoming-call screen sendsendCall(sessionId, "rejected"), and sends "busy" instead when the user is already in another call. The caller receives onIncomingCallEnded with that reason.
You only write decline code when you draw your own incoming-call screen:
- Kotlin
- Java
CometChatCalls.endCall(sessionId, Constants.CALL_STATUS_REJECTED, listener).
Cancel a call
The caller ends a call that is still ringing withendCall and the cancelled status. The callee’s ring stops and a missed call is posted there.
- Kotlin
- Java
onParticipantJoined that arrives after you cancelled: the cancel wins.
Ring timeout
The callee’s Push SDK ends an unanswered 1:1 call asunanswered when its ring window closes (45 seconds unless the push carries a ringTimeout). To close the caller’s screen at the same moment even if that signal is late, run your own timer from initiateCall and end the call with the same status:
- Kotlin
- Java
End a call
Hang up by leaving the session. In a 1:1 call, setsetPeerCall(true) before the session is prepared, or a caller who cancels while the callee is joining leaves the callee alone in the room. The room tells the other side, which receives onParticipantLeft and then onSessionLeft or onConnectionClosed. No status needs to be sent and the call is logged by the backend.
- Kotlin
- Java
- Kotlin
- Java
CallSession.leaveSession() is deprecated in 5.1; use leave(). Leave only the session your screen owns: after answering a second call over a live one, the first screen’s clean-up must not leave the new session.Second call while in a call
Handled by the Push SDK, the same way a phone does it. A call that arrives while the user is in another call rings over it with “Answering ends your current call”. Answer leaves the live call, prepares the new one and opens your answer activity again (withFLAG_ACTIVITY_SINGLE_TOP, so it arrives in onNewIntent if the activity is still up: open a fresh screen for the new session). Decline sends busy and keeps the live call. A 1:1 call that arrives while another is already ringing, or while the user’s own outgoing call is ringing, is declined as busy without ringing; a group call in that situation is dropped on this device without a reply.
Group calls
To ring a group, callinitiateCall with the group’s GUID as receiverUid and Constants.RECEIVER_TYPE_GROUP; every member’s device rings through the push. You can also start a group call without ringing: share a session id (for example in a custom message) and have each member join it with joinSession. When a group call rings, declining it or letting it ring out sends nothing: the call carries on for the other members, and the decline is local to that device.
Logout
Log out of the Calls SDK when the user signs out (CometChatCalls.logout). On that logout the Push SDK stops a call still ringing for the old user and unregisters the push token. Logging out of the Chat SDK alone leaves the Calls SDK signed in, so a ring keeps playing for the old user and later declines go out with the old token.
End or cancel any call of your own before logging out; the Calls SDK cannot send after the session is gone.
Call status values
Related
- Push ringing: dependencies,
PNConfiguration, the FCM service, answer activity, your own incoming-call screen, readiness checks and what happens when the app is killed. - Migrating from legacy ringing.
- Events, Actions, Call Logs.