Skip to main content
Legacy ringing signalled calls through the Chat SDK: CometChat.initiateCall created the call, a CallListener on the WebSocket told the callee, acceptCall and rejectCall answered, and the app rang the device itself, often with a hand-built ConnectionService. Ringing now runs on the Calls SDK and the Push Notifications SDK calls module. The Chat SDK’s calling methods are superseded by the Calls SDK and no longer used; a coming Chat SDK release marks them deprecated. This page is the diff. For the full description of the current flow see Ringing; for the push side see Push ringing.

Before you start

Ringing with the Calls SDK is opt-in on the client: moving your app to the Calls SDK 5.1 and Push Notifications SDK 2.0 APIs below is the migration. While some of your users are still on legacy ringing, one dashboard setting lets the two flows call each other; see While some users are still on legacy ringing.

Why it changed

Before and after

Step 1: Update dependencies

build.gradle.kts
  • minSdk 26 or higher.
  • compileSdk 36 and Android Gradle Plugin 8.9.1 or later: the Push Notifications SDK 2.0 depends on androidx.core 1.18, which requires them.
  • Keep your Firebase Messaging dependency and google-services.json; the Push SDK never compiles against Firebase.
Adding the push-notifications-calls-android artifact turns ringing on. There is no second initialiser.

Step 2: Replace the push configuration

Step 3: Shrink the Firebase service

Never skip call pushes in the foreground any more. The WebSocket no longer delivers incoming call invitations to your app; the push is the only signal that a call is coming in, in every state.

Step 4: Delete the token code

The Push SDK registers the token on login and unregisters it on logout by itself. Remove:
  • FirebaseMessaging.getInstance().token + registerToken(...) / CometChatNotifications.registerPushToken(...) after login
  • unregisterToken(...) / unregisterPushToken(...) before logout

Step 5: Delete the app-side ringing

Everything in this list is now done by the Push SDK. Remove it, or it will fight the SDK’s ring (two ringtones, two screens, a busy reject sent on top of the SDK’s).
  • The Application-level CometChat.addCallListener(...) and its onIncomingCallReceived handler
  • The incoming-call overlay, snackbar, dialog or activity you launched from it
  • Your own ringtone / sound manager for incoming calls
  • The “already in a call → reject with busy” check
  • CometChatVoIP, PhoneAccount registration, CometChatVoIPConnectionService, CallConnection, and your own READ_PHONE_STATE and ANSWER_PHONE_CALLS requests. (MANAGE_OWN_CALLS still merges in from the Calls SDK’s manifest; leave it.)
  • Any isAppInForeground() gate around call pushes
RECORD_AUDIO, CAMERA and POST_NOTIFICATIONS merge into your manifest from the Calls SDK and the Push SDK’s calls module, so you can remove your own declarations; keep requesting them at runtime.

Step 6: Rewrite the call code

Caller screen, before and after

Callee screen, before and after

Step 7: Change the logout

If you drew your own incoming-call screen

Keep it, but drive it from the Push SDK instead of the CallListener:
  1. Register it with PNConfiguration.Builder.setIncomingCallActivity(YourRingActivity::class.java). The Push SDK still rings, times out and sends the decline; only the screen is yours.
  2. In onCreate, read CallBundles.getCall(intent) and call CometChatCallNotifications.onIncomingCallScreenOpened(sessionId) { reason -> finish() } so the SDK closes the screen when the call ends elsewhere.
  3. Answer with CometChatCallNotifications.answer(context, sessionId) after asking for the microphone (and camera) yourself; answer() skips the SDK’s own prompt.
  4. Decline with CometChatCallNotifications.decline(context, sessionId).
  5. In onDestroy, call CometChatCallNotifications.onIncomingCallScreenClosed(sessionId).
Details on the Push ringing page.

While some users are still on legacy ringing

Your users don’t all update at once, so during the rollout one CometChat app has devices on both flows. A device’s flow comes from its push registration: a device on the Calls SDK 5.1 and Push Notifications SDK 2.0 receives only the call-initiated push, and a device still on legacy ringing keeps receiving the legacy call events. To let users on the two flows call each other, turn on Connect legacy ringing in the CometChat dashboard under Voice & Video Calls → Settings. CometChat then also sends calls made on this flow as legacy call events, so devices on either flow ring for calls from the other.
  • Turn it on before the first users update, and leave it on while any version of your apps still in use rings the legacy way.
  • It can’t be turned off from the dashboard.
  • The six legacy call events (ongoing, cancelled, rejected, unanswered, busy and ended) are under Show legacy in Notifications → Settings → Call Preferences. They only reach devices on legacy ringing.

What users will notice

  • Calls ring with the app killed, from the lock screen, without a ConnectionService.
  • The caller sees “Ringing…” once the callee’s phone is reached, and the reason when a call is declined or missed.
  • The callee stops ringing after 45 seconds and the caller’s screen closes with it (and on its own timer, if the callee’s device was never reached).
  • Missed calls appear as notifications on the callee.
  • A call during a call is call waiting (answer ends the current call, decline sends busy), not an automatic reject.
  • The microphone and camera prompt appears on Answer the first time, on the device that answers.

Checklist

  • Dependencies bumped, push-notifications-calls-android added, minSdk 26
  • PNConfiguration has setProviderId and setAnswerActivity
  • Firebase service passes every push to handlePushNotification with message.sentTime
  • Manual token registration removed
  • CometChat.addCallListener, own incoming UI, ringtone, busy check and the ConnectionService stack removed
  • initiateCall sets the session type in sessionSettings
  • Caller listens on the prepared session and on IncomingCallListener; joins only on onParticipantJoined
  • Answer activity reads CallBundles.getCall(intent) and joins
  • Hang-up uses leave(); no CometChat.endCall
  • Logout also logs out of the Calls SDK
  • ensureRingReady runs after sign-in and anything other than READY is shown to the user
  • Call pushes are sent at high FCM priority
  • Connect legacy ringing is on in the dashboard if some users stay on legacy ringing during the rollout
  • Tested: ring with the app killed, decline, cancel, no answer, call during a call, logout while ringing