-
public class DaakiaCallKitEntry point of the Daakia CallKit SDK.
Initialize once from your
Application.onCreate, before using any other API:DaakiaCallKit.initialize( context = this, config = DaakiaCallKitConfig(baseUrl = "https://…", secret = "…"), )The API falls into five groups:
Receiving calls — handleRemoteMessage (or ai.daakia.callkit.push.DaakiaMessagingService) turns a Daakia push into a ringing incoming call.
Placing calls — registerDevice, getRegisteredDevice, startCallByUsername, startCallByToken. These are
suspend; call them from your own scope.Reporting call lifecycle — sendCallEvent while the app runs, plus configureCallEventFallback for the killed-state path.
Cancelling a ringing call — endCall, for when the caller hangs up first.
Observing — callEvents and consumeLaunchEvent.
Permissions — canUseFullScreenIntent and openFullScreenIntentSettings.
-
-
Field Summary
Fields Modifier and Type Field Description private final static SharedFlow<CallEvent>callEventspublic final static DaakiaCallKitINSTANCE
-
Method Summary
Modifier and Type Method Description final static Unitinitialize(Context context, DaakiaCallKitConfig config)Initializes the SDK. final static BooleancanUseFullScreenIntent()Whether the app may use full-screen intents, i.e. final static BooleanopenFullScreenIntentSettings()Opens the Android 14+ system screen where the user grants full-screen intent use. final static CallEventconsumeLaunchEvent(Intent intent)Recovers the call event carried by the intent that launched your activity — the accept-from-killed-state path, where the SDK starts your launcher activity because the user accepted a call while the app process was dead. final static DeviceTokenRecordregisterDevice(String username, String fcmToken)Registers this device's push token with the Daakia backend, so calls placed to username reach it. final static DeviceTokenRecordgetRegisteredDevice(String username, DaakiaPlatform platform)Looks up the push token the backend currently holds for username. final static DeviceTokenRecordgetRegisteredDevice(String username)Looks up the push token the backend currently holds for username. final static PushResultstartCallByUsername(String username, IncomingCallData call, String message)Places a call by username: the backend resolves username to its registered devices and pushes the incoming call to them. final static PushResultstartCallByUsername(String username, IncomingCallData call)Places a call by username: the backend resolves username to its registered devices and pushes the incoming call to them. final static PushResultstartCallByToken(String token, DaakiaPlatform platform, IncomingCallData call, String message)Places a call straight to a known device token, skipping the backend's username lookup — see getRegisteredDevice for obtaining one. final static PushResultstartCallByToken(String token, DaakiaPlatform platform, IncomingCallData call)Places a call straight to a known device token, skipping the backend's username lookup — see getRegisteredDevice for obtaining one. final static UnitendCall(String callId)Stops a ringing incoming call: silences the ringtone and vibration, removes the notification, closes the SDK's call screen if it is showing, and emits ai.daakia.callkit.model.CallEventType.ENDED. final static UnitendCall()Stops a ringing incoming call: silences the ringtone and vibration, removes the notification, closes the SDK's call screen if it is showing, and emits ai.daakia.callkit.model.CallEventType.ENDED. final static UnitsendCallEvent(String meetingUid, CallEventAction action, Map<String, String> metadata)Reports a call lifecycle action to the Daakia backend webhook. final static UnitsendCallEvent(String meetingUid, CallEventAction action)Reports a call lifecycle action to the Daakia backend webhook. final static UnitconfigureCallEventFallback(Set<CallEventAction> actions, Map<String, String> metadata)Enables the killed-state fallback webhook: when the user accepts, declines, or lets a call time out, the SDK reports the matching CallEventAction to the backend even if the app process is not running (via WorkManager), using the base URL and secret captured from initialize's config at call time. final static UnitconfigureCallEventFallback(Set<CallEventAction> actions)Enables the killed-state fallback webhook: when the user accepts, declines, or lets a call time out, the SDK reports the matching CallEventAction to the backend even if the app process is not running (via WorkManager), using the base URL and secret captured from initialize's config at call time. final static UnitclearCallEventFallback()Disables the killed-state fallback webhook configured by configureCallEventFallback. final static UnitclearSentCallEventCache()Clears the local dedupe cache of call events already reported to the backend, allowing the same meetingUid+ action pair to be reported again.final static BooleanhandleRemoteMessage(RemoteMessage message)Handles an FCM message if it is a Daakia incoming-call push. final static SharedFlow<CallEvent>getCallEvents()-
-
Method Detail
-
initialize
final static Unit initialize(Context context, DaakiaCallKitConfig config)
Initializes the SDK. Call once from your
Application.onCreatebefore anything else.After initialization, call pushes consumed by handleRemoteMessage ring: a foreground service posts the CallStyle notification, plays the ringtone, and times the call-out after DaakiaCallKitConfig.callTimeout.
-
canUseFullScreenIntent
final static Boolean canUseFullScreenIntent()
Whether the app may use full-screen intents, i.e. whether the incoming-call screen can appear over the lock screen. Always
truebelow Android 14; on Android 14+ the user can revoke it, in which case the call shows as a heads-up notification only — check this and offer openFullScreenIntentSettings from your app's settings.
-
openFullScreenIntentSettings
final static Boolean openFullScreenIntentSettings()
Opens the Android 14+ system screen where the user grants full-screen intent use.
-
consumeLaunchEvent
final static CallEvent consumeLaunchEvent(Intent intent)
Recovers the call event carried by the intent that launched your activity — the accept-from-killed-state path, where the SDK starts your launcher activity because the user accepted a call while the app process was dead.
Call it from your launcher activity's
onCreateandonNewIntent:DaakiaCallKit.consumeLaunchEvent(intent)?.let { event -> // event.type is ACCEPTED (or INCOMING); join event.call }One-shot: the first call strips the SDK extras from intent and returns the event; later calls with the same intent (e.g. after a configuration change) return
null.
-
registerDevice
final static DeviceTokenRecord registerDevice(String username, String fcmToken)
Registers this device's push token with the Daakia backend, so calls placed to username reach it.
Call it after obtaining the FCM token (
FirebaseMessaging.getInstance().token) and again from your messaging service whenever the token is refreshed.- Parameters:
username- Username the token is registered under; the same value callers pass to startCallByUsername.fcmToken- The device's current FCM registration token.
-
getRegisteredDevice
@JvmOverloads() final static DeviceTokenRecord getRegisteredDevice(String username, DaakiaPlatform platform)
Looks up the push token the backend currently holds for username.
Mostly useful before startCallByToken, when you want to push straight to a known device rather than let the backend resolve the target.
- Parameters:
platform- Platform to look the registration up for.
-
getRegisteredDevice
@JvmOverloads() final static DeviceTokenRecord getRegisteredDevice(String username)
Looks up the push token the backend currently holds for username.
Mostly useful before startCallByToken, when you want to push straight to a known device rather than let the backend resolve the target.
-
startCallByUsername
@JvmOverloads() final static PushResult startCallByUsername(String username, IncomingCallData call, String message)
Places a call by username: the backend resolves username to its registered devices and pushes the incoming call to them.
DaakiaCallKit.startCallByUsername( username = "bob", call = IncomingCallData(callId = meetingUid, title = "Alice"), )- Parameters:
call- The call description; itstitlebecomes the notification title and IncomingCallData.toDataJson the push'sdataobject.message- Notification body sent alongside the payload.
-
startCallByUsername
@JvmOverloads() final static PushResult startCallByUsername(String username, IncomingCallData call)
Places a call by username: the backend resolves username to its registered devices and pushes the incoming call to them.
DaakiaCallKit.startCallByUsername( username = "bob", call = IncomingCallData(callId = meetingUid, title = "Alice"), )- Parameters:
call- The call description; itstitlebecomes the notification title and IncomingCallData.toDataJson the push'sdataobject.
-
startCallByToken
@JvmOverloads() final static PushResult startCallByToken(String token, DaakiaPlatform platform, IncomingCallData call, String message)
Places a call straight to a known device token, skipping the backend's username lookup — see getRegisteredDevice for obtaining one.
- Parameters:
platform- Platform of the target device, so the backend picks FCM or APNs.call- The call description; itstitlebecomes the notification title and IncomingCallData.toDataJson the push'sdataobject.message- Notification body sent alongside the payload.
-
startCallByToken
@JvmOverloads() final static PushResult startCallByToken(String token, DaakiaPlatform platform, IncomingCallData call)
Places a call straight to a known device token, skipping the backend's username lookup — see getRegisteredDevice for obtaining one.
- Parameters:
platform- Platform of the target device, so the backend picks FCM or APNs.call- The call description; itstitlebecomes the notification title and IncomingCallData.toDataJson the push'sdataobject.
-
endCall
@JvmOverloads() final static Unit endCall(String callId)
Stops a ringing incoming call: silences the ringtone and vibration, removes the notification, closes the SDK's call screen if it is showing, and emits ai.daakia.callkit.model.CallEventType.ENDED.
The case this exists for is the caller hanging up before the callee answers. When your app learns the call was cancelled — a second push, a socket message — call this, or the device keeps ringing until the timeout and reports a
call-timeoutthat never happened:override fun onMessageReceived(message: RemoteMessage) { if (message.data["type"] == "call_cancelled") { DaakiaCallKit.endCall(message.data["callId"]) return } if (DaakiaCallKit.handleRemoteMessage(message)) return }Purely local: it reports nothing to the backend. Use sendCallEvent with CallEventAction.END for that.
- Parameters:
callId- Ends only the call with this id, so a stale cancellation cannot silence a newer call that started meanwhile.
-
endCall
@JvmOverloads() final static Unit endCall()
Stops a ringing incoming call: silences the ringtone and vibration, removes the notification, closes the SDK's call screen if it is showing, and emits ai.daakia.callkit.model.CallEventType.ENDED.
The case this exists for is the caller hanging up before the callee answers. When your app learns the call was cancelled — a second push, a socket message — call this, or the device keeps ringing until the timeout and reports a
call-timeoutthat never happened:override fun onMessageReceived(message: RemoteMessage) { if (message.data["type"] == "call_cancelled") { DaakiaCallKit.endCall(message.data["callId"]) return } if (DaakiaCallKit.handleRemoteMessage(message)) return }Purely local: it reports nothing to the backend. Use sendCallEvent with CallEventAction.END for that.
-
sendCallEvent
@JvmOverloads() final static Unit sendCallEvent(String meetingUid, CallEventAction action, Map<String, String> metadata)
Reports a call lifecycle action to the Daakia backend webhook.
Use it when your app drives the call itself — for example to report CallEventAction.JOIN once the user is in the meeting, or CallEventAction.END when they hang up. The accept/decline/timeout actions that happen on the SDK's own notification are covered by configureCallEventFallback; this is the in-app path.
Deduped against the same cache the fallback webhook uses: each
meetingUid+ action pair is delivered once, so a repeat call is a no-op rather than a second webhook. clearSentCallEventCache resets that.
-
sendCallEvent
@JvmOverloads() final static Unit sendCallEvent(String meetingUid, CallEventAction action)
Reports a call lifecycle action to the Daakia backend webhook.
Use it when your app drives the call itself — for example to report CallEventAction.JOIN once the user is in the meeting, or CallEventAction.END when they hang up. The accept/decline/timeout actions that happen on the SDK's own notification are covered by configureCallEventFallback; this is the in-app path.
Deduped against the same cache the fallback webhook uses: each
meetingUid+ action pair is delivered once, so a repeat call is a no-op rather than a second webhook. clearSentCallEventCache resets that.
-
configureCallEventFallback
@JvmOverloads() final static Unit configureCallEventFallback(Set<CallEventAction> actions, Map<String, String> metadata)
Enables the killed-state fallback webhook: when the user accepts, declines, or lets a call time out, the SDK reports the matching CallEventAction to the backend even if the app process is not running (via WorkManager), using the base URL and secret captured from initialize's config at call time.
The webhook body enriches metadata with
caller_id,receiver_id,call_timestamp,delivery_mode: "fallback"andplatform: "android".Passing an empty actions set clears the fallback, like clearCallEventFallback.
-
configureCallEventFallback
@JvmOverloads() final static Unit configureCallEventFallback(Set<CallEventAction> actions)
Enables the killed-state fallback webhook: when the user accepts, declines, or lets a call time out, the SDK reports the matching CallEventAction to the backend even if the app process is not running (via WorkManager), using the base URL and secret captured from initialize's config at call time.
The webhook body enriches metadata with
caller_id,receiver_id,call_timestamp,delivery_mode: "fallback"andplatform: "android".Passing an empty actions set clears the fallback, like clearCallEventFallback.
-
clearCallEventFallback
final static Unit clearCallEventFallback()
Disables the killed-state fallback webhook configured by configureCallEventFallback.
-
clearSentCallEventCache
final static Unit clearSentCallEventCache()
Clears the local dedupe cache of call events already reported to the backend, allowing the same
meetingUid+ action pair to be reported again.
-
handleRemoteMessage
final static Boolean handleRemoteMessage(RemoteMessage message)
Handles an FCM message if it is a Daakia incoming-call push.
Forward every message from your
FirebaseMessagingService:override fun onMessageReceived(message: RemoteMessage) { if (DaakiaCallKit.handleRemoteMessage(message)) return // consumed // your own handling }If your app has no messaging service of its own, register ai.daakia.callkit.push.DaakiaMessagingService instead.
A push older than DaakiaCallKitConfig.staleCallWindow — typically one FCM queued while the device was offline — does not ring; it is handled per DaakiaCallKitConfig.staleCallBehavior and reported as CallEventType.STALE. It still returns
true: the message was Daakia's and the SDK dealt with it.
-
getCallEvents
final static SharedFlow<CallEvent> getCallEvents()
-
-
-
-