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. CometChat sends a push to the callee,cometchat_voip rings the callee’s phone, and when the callee answers, both sides join the call session.
Prerequisites
- The Calls SDK set up and the user logged in on both devices.
cometchat_voipset up on both the caller’s and the callee’s app. The whole push side of ringing is on the Push Ringing page; this page assumes it is done. The caller needs it too: a decline reaches the caller as a push.- The caller’s microphone and camera permissions, requested by your app before
initiateCall.cometchat_voipasks only on the phone that answers.
Start a call
CometChatCalls.initiateCall creates the call, which rings the callee, and prepares the caller’s call session. The caller does not join yet.
InitiatedCall gives you sessionId, messageId (the id of the call message in the conversation), sender, receiver, receiverType, type, status, initiatedAt (in milliseconds), conversationId, isVideo, isPeerCall and session, the CallSession being prepared. onSuccess fires as soon as the call exists, while the session is still preparing.
initiateCall fails if a session is already being joined or is live on this device; leave it first.
Show “Ringing…” and detect the answer
The caller stays on the session thatinitiateCall prepared and listens to it. Don’t call joinSession yet: the caller joins only once the callee has joined.
Remove the listeners when the outgoing call screen closes (
removeParticipantEventListener, removeSessionStatusListener, CometChatCalls.removeIncomingCallListener).
Listen for calls ending
The caller learns how a call ended from the Calls SDK’s incoming call listener; the callee learns it fromcometchat_voip.
On the callee, a caller’s cancel reaches
onCallEnded as cancelled when the push gets there first. When the prepared session closes first, the Calls SDK reports ended, which cometchat_voip maps to declined, so don’t show “Declined” in your UI from that value alone. ended.reason.isMissed is true only for cancelled and timedOut.Answer a call
cometchat_voip rings and, on Answer, hands you the call. Listen for the answer and join. There is no separate “accept” call to make.
CometChatVoip.init, in main rather than in a screen. A call answered from the push that started the app is held until something listens.
On the lock screen, join without waiting for your UI. On iOS, onCallAnswered can fire while the phone is still locked and before your first screen exists. Call joinSession straight away: the Calls SDK joins into a view of its own and hands you the widget when the join completes, so it doesn’t need a window, a BuildContext or a navigator, and the audio connects before the user unlocks. An answered call that hasn’t joined within 20 seconds is ended as failed. Show the widget when your UI comes up.
Permissions. With requestCallPermissions on (the default), cometchat_voip asks for the microphone, and the camera for a video call, when the user answers. It never holds up the call: the user who refuses joins without that device.
Join the session
Both sides join the same way: the callee fromonCallAnswered, the caller from onParticipantJoined. joinSession takes over the session that was prepared earlier, so it connects almost at once. It keeps the settings the session was prepared with; the ones you pass here apply only if the session wasn’t prepared, so pass the same values.
Decline a call
Declining is handled bycometchat_voip: the Decline action on the notification, the ring screen and CallKit sends rejected, or busy when the user is already in another call, from a queue that survives the app being killed. A group call’s decline is local: nothing is sent. The caller receives onIncomingCallEnded — see Listen for calls ending.
You only write decline code when you draw your own ring screen:
Cancel a call
The caller ends a call that is still ringing withendCall and the cancelled status. endCall leaves the prepared session first. The callee’s ring stops and a missed call is shown there.
onParticipantJoined that arrives after you cancelled: the cancel wins.
Ring timeout
The callee’scometchat_voip ends an unanswered 1:1 call as unanswered when its ring time is up (45 seconds by default, defaultRingTimeout, unless the push carries its own). If the callee’s phone is never reached, nothing ends the caller’s ringing until its prepared session expires after 5 minutes, so run your own timer from initiateCall and end the call with the same status. Cancel the timer when the call is answered or ends:
End a call
Hang up by leaving the session. For a peer call, whichsetPeerCall(true) must have set before the session was prepared, the other side’s session ends too, and it receives onSessionLeft or onConnectionClosed. No status needs to be sent.
leaveSession() is deprecated; 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 bycometchat_voip, the 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” (CallKit’s End & Accept on iOS). Answer ends the live call and onCallAnswered fires for the new one once the live session has gone: close the old call screen and join the new call. Decline sends busy and keeps the live call. On Android, a call that arrives while another is already ringing, or while the user’s own outgoing call is ringing, is declined as busy without ringing. See A call while in a call.
Group calls
initiateCall also rings a group: pass the group’s GUID as receiver, set options.receiverType to ReceiverType.group, and build the session settings with isPeerCall: false. Every member of the group whose app is set up for ringing is rung; each one who answers joins the session, and the others keep ringing until they answer, decline or the ring time runs out. call.receiver is then the GUID, so on the caller treat any participant other than yourself joining as the answer.
A group ring ends on each member’s phone on its own, and nothing is sent back to the caller: a member who declines or lets the call ring out sends no rejected and no unanswered, so the caller learns only that somebody joined, through onParticipantJoined. Decide yourself when to give up on a group call: run a timer on the caller and call endCall with EndCallStatus.cancelled.
A session every member joins without ringing is still an option: share a session id with them (for example in a custom message) and have each one call joinSession.
Logout
Before logging the user out, unregister the push token withCometChatVoip.unregisterPushToken(), then log out of the Calls SDK with CometChatCalls.logout. Logging out stops a call still ringing for that user. End or cancel any call of your own first; the Calls SDK can’t send after the session is gone.
Call status values
Related
- Push Ringing: packages and platform setup, initializing
cometchat_voip, handing over pushes, the push token, ring readiness, the call modes and what happens when the app is killed. - Migrating from Legacy Ringing.
- Events, Actions, Call Logs.