Direct Call Android SDK

Learn how to integrate Direct Call Android SDK in your app to avail the Direct Call feature.

Overview

CleverTap provides in-app calls via its Direct Call Android SDK, which means you can make and receive calls in any Android app if the device has an internet connection and Direct Call Android SDK. This section shows you how to integrate the Direct Call Android SDK and manage calls. To know more about the Direct Call feature, refer to Direct Call.

Requirements

The basic requirements for the Direct Call Android SDK are:

  • Minimum SDK Level - 21
  • Java 8 and above
  • Application permissions for the following:
    • Microphone (Required)
    • Read Phone State (Optional)

πŸ“˜

Emulator Support

Emulator support is available for voice calls, but voice transmission will not work.

Install Direct Call Android SDK

You can pull the latest version of the Direct Call Android SDK from mavenCentral as follows:

  1. Include mavenCentral in your project level build.gradle file as follows:
allprojects {
    repositories {
        mavenCentral()
    }
}
  1. Add the following line to the dependencies element in your application module's build.gradle file:
implementation "com.clevertap.android:clevertap-directcall-sdk:0.0.1"

Add Other Dependencies

To enable voice calling with the Direct Call Android SDK, you must add the following dependencies to your application module build.gradle file:

CleverTap Android SDK

The Direct Call Android SDK uses CleverTap Android SDK for analytics. The Direct Call Android SDK requires an active CleverTap instance as a parameter during the SDK initialization.

To integrate the CleverTap Android SDK, refer to the CleverTap Android SDK Integration.

πŸ“˜

Minimum Supported Version

The Direct Call Android SDK requires a CleverTap SDK version of v4.5.0 or higher.

Socket-IO Client

The Direct Call Android SDK uses a Socket-IO client library to enable the socket-based signaling channel for voice calls.

To add the Socket-IO client dependency to your application, add the following line to the application module's dependency element:

implementation('io.socket:socket.io-client:2.0.1') {
        exclude group: 'org.json', module: 'json'
}

Glide

The Direct Call Android SDK uses a Glide library for loading the image assets on the call screen.

To add the Glide dependency to your application, add the following line to the application module's dependency element:

implementation 'com.github.bumptech.glide:glide:4.12.0'

Work Manager

The Direct Call Android SDK uses a Work Manager dependency to process the incoming call push for the receiver.

To add the Work Manager dependency to your application, add the following line to the application module's dependency element:

implementation 'androidx.work:work-runtime:2.7.1'

ConstraintLayout

The Direct Call Android SDK uses a ConstraintLayout dependency to build a responsive UI for the call screens.

To add the ConstraintLayout dependency to your application, add the following line to the application module's dependency element:

implementation 'androidx.constraintlayout:constraintlayout:2.1.3'

Upgrade Java Compatibility

The Direct Call Android SDK's source and target compatibility are set to Java 8.

To upgrade your application to target Java 8, use the following snippet:

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

After updating your build.gradle file, sync your project by clicking the Sync Project button.

Initialize and Authenticate the Direct Call Android SDK

Initialize the Direct Call Android SDK using the instance of the DirectCallAPI class:

DirectCallInitResponse directCallInitListener = new DirectCallInitResponse() {
      @Override
      public void onSuccess() {
          //App is notified on the main thread when the Direct Call SDK is initialized
      }

      @Override
      public void onFailure(@NonNull InitException initException) {
          //App is notified on the main thread when the initialization is failed
          Log.d("DirectCall: ", "error code: " + initException.getErrorCode()
                 + "\n error message: " + initException.getMessage()
                 + "\n error explanation: " + initException.getExplanation());

          if (initException.getErrorCode() == InitException.DirectCallSdkNotInitializedException.getErrorCode()) {
             //Handle this error here
          }
      }
};

//Create a Builder instance of DirectCallInitOptions and pass it inside the init() method
DirectCallInitOptions directCallInitBuilder = new DirectCallInitOptions.Builder(initOptions, allowPersistSocketConnection)
         .build();

DirectCallAPI.getInstance().init(getApplicationContext(), directCallInitBuilder, cleverTapAPI, directCallInitListener);
val directCallInitListener: DirectCallInitResponse = object : DirectCallInitResponse {
    override fun onSuccess() {
        //App is notified on the main thread when the Direct Call SDK is initialized
    }

    override fun onFailure(initException: InitException) {
        //App is notified on the main thread when the initialization is failed
        Log.d("DirectCall: ", "error code: " + initException.errorCode
                 + "\n error message: " + initException.message
                 + "\n error explanation: " + initException.explanation)

        if (initException.errorCode == InitException.DirectCallSdkNotInitializedException.errorCode) 
        {
           //Handle this error here
        }
    }
}

//Create a Builder instance of DirectCallInitOptions and pass it inside the init() method
val directCallInitBuilder = DirectCallInitOptions.Builder(initOptions, allowPersistSocketConnection)
    .enableReadPhoneState(<pass boolean here>)
    .build()

DirectCallAPI.getInstance().init(applicationContext, directCallInitBuilder, cleverTapAPI, directCallInitListener)

Following are the parameters passed inside the constructor of DirectCallInitOptions.Builder:

initOptions

The initOptions is a JSON object that is passed inside the constructor of DirectCallInitOptions.Builder with the following properties:

Properties

Description

Type

Notes

accountId

Unique identity of the client's account.

String

  • Required
  • Available from the CleverTap dashboard.

apikey

Unique identity of the client's account.

String

  • Required
  • Available from the CleverTap dashboard.

cuid

Unique identity of the user.

String

  • Required

Validation rules:

  • The cuid must range between 5 and 50 characters.
  • The cuid is case sensitive and only '_' is allowed as a special character.
  • The cuid parameter cannot be of the number-number type, that is, a number followed by another number separated with a special character. For example, org_25 is allowed, but 91_8899555 is not allowed.
  • You must use a unique cuid for every device.

appId

Application ID of the app.

String

  • Optional
  • Use the BuildConfig.APPLICATION_ID to get your application ID.

name

The name of the user.

String

  • Optional
  • The name must range between 3 and 25 characters.

ringtone

The URL of the ringtone that is played on the caller's end during the outgoing call.

String

  • Optional
  • The default ringtone plays without this parameter.

The syntax for the properties of initOptions is as follows:

JSONObject initOptions = new JSONObject();
try {
    initOptions.put("accountId", <string>);
    initOptions.put("apikey", <string>);
    initOptions.put("cuid", <string>);
    initOptions.put("appId", <string / optional>);
    initOptions.put("name", <string / optional>);
    initOptions.put("ringtone", <string / optional>);
} catch (JSONException e) {
    e.printStackTrace();
}
val initOptions = JSONObject();
try {
    initOptions.put("accountId", <string>);
    initOptions.put("apikey", <string>);
    initOptions.put("cuid", <string>);
    initOptions.put("appId", <string / optional>);
    initOptions.put("name", <string / optional>);
    initOptions.put("ringtone", <string / optional>);
} catch (e: JSONException) {
    e.printStackTrace();
}

allowPersistSocketConnection

The allowPersistSocketConnection is a boolean parameter passed inside the constructor of DirectCallInitOptions.Builder.

The Direct Call Android SDK uses a socket connection to initiate or receive a call. Use the allowPersistSocketConnection to allow the Direct Call Android SDK to use a background service. This service keeps the socket connection persistent in the foreground and background states of the application.

Following is the Direct Call Android SDK behavior per the passed value:

Value

Direct Call Android SDK Behavior

true

The Direct Call Android SDK uses a background service to keep the socket connection persistent in the foreground and background states of the application.

false

The Direct Call Android SDK does not use the background service for the socket connection, meaning that the socket connection would be intermittent.

Permission Management

Following are the permissions that the Direct Call Android SDK uses and their management:

Microphone

The Direct Call Android SDK requires Microphone permission to exchange voices during the call. At the receiver's end, the Direct Call Android SDK asks for the Microphone permission and handles it accordingly when the user answers the call. If a user denies the Microphone permission, the Direct Call Android SDK declines the call. The microphone is required permission. We recommend you add the required handling to request the Microphone permission before initiating a call.

Read Phone State

The Direct Call Android SDK uses Read Phone State permission to enable busy handling for Public Switched Telephone Network (PSTN) calls and determines if the receiver is available or busy on another call. The Read Phone State is optional permission. We recommend you add the required handling to request the Read Phone State permission before initiating a call.

The Direct Call Android SDK exposes a enableReadPhoneState(boolean) method via the DirectCallInitOptions.Builder class. Pass the boolean flag as true to allow the Direct Call Android SDK to ask the Read Phone State permission at the receiver's end when the receiver answers the call.

DirectCallInitOptions directCallInitBuilder = new DirectCallInitOptions.Builder(initOptions, allowPersistSocketConnection)
         .enableReadPhoneState(<pass boolean here>)
         .build();

DirectCallAPI.getInstance().init(getApplicationContext(), directCallInitBuilder, cleverTapAPI, directCallInitListener);
val directCallInitBuilder = DirectCallInitOptions.Builder(initOptions, allowPersistSocketConnection)
        .enableReadPhoneState(< pass boolean here >)
        .build()

DirectCallAPI.getInstance().init(applicationContext, directCallInitBuilder, cleverTapAPI, directCallInitListener)

Logout the Direct Call Android SDK

When the Direct Call Android SDK initializes, it saves the initOptions details in a local session and maintains the local session until the logout(context) method is called.

DirectCallAPI.getInstance().logout(getApplicationContext());
DirectCallAPI.getInstance().logout(applicationContext)

πŸ“˜

Logout Usage

Use the logout(context) method:

  • To clear the active session and update the initOptions details.
  • To disable the Direct Call functionality (initiation or reception of the calls).

Make a Direct Call

Use the following code to make a Direct Call:

OutgoingCallResponse outgoingCallResponseListener = new OutgoingCallResponse() {
    @Override
    public void callStatus(VoIPCallStatus callStatus) {
        //App is notified on the main thread to notify the changes in the call-state
        if (callStatus == VoIPCallStatus.CALL_DECLINED) {
            //when the call is declined from the receiver's end
        } else if (callStatus == VoIPCallStatus.CALL_MISSED) {
            //when the call is missed at the receiver's end
        } else if (callStatus == VoIPCallStatus.CALL_ANSWERED) {
            //When the call is picked up by the receiver
        } else if (callStatus == VoIPCallStatus.CALL_IN_PROGRESS) {
            //when the connection to the receiver is established
        } else if (callStatus == VoIPCallStatus.CALL_OVER) {
            //when the call has been disconnected
        } else if (callStatus == VoIPCallStatus.CALLEE_BUSY_ON_ANOTHER_CALL) {
            //when the receiver is busy on another call
        }
    }

    @Override
    public void onSuccess() {
        //App is notified on the main thread when the call-request is accepted and being processed by the signalling channel
    }

    @Override
    public void onFailure(CallException callException) {
        //App is notified on the main thread when the call is failed
        Log.d("DirectCall: ", "error code: " + callException.getErrorCode()
               + "\n error message: " + callException.getMessage()
               + "\n error explanation: " + callException.getExplanation());

        if (callException.getErrorCode() == CallException.BadNetworkException.getErrorCode()) {
            //Handle this error here
        }
    }
};

DirectCallAPI.getInstance().call(getApplicationContext(), receiverCuid, contextOfCall, callOptions, outgoingCallResponseListener);
val outgoingCallResponseListener: OutgoingCallResponse = object : OutgoingCallResponse {
    override fun callStatus(callStatus: VoIPCallStatus) {
        //App is notified on the main thread to notify the changes in the call-state
        if (callStatus == VoIPCallStatus.CALL_DECLINED) {
            //when the call is declined from the receiver's end
        } else if (callStatus == VoIPCallStatus.CALL_MISSED) {
            //when the call is missed at the receiver's end
        } else if (callStatus == VoIPCallStatus.CALL_ANSWERED) {
            //When the call is picked up by the receiver
        } else if (callStatus == VoIPCallStatus.CALL_IN_PROGRESS) {
            //when the connection to the receiver is established
        } else if (callStatus == VoIPCallStatus.CALL_OVER) {
            //when the call has been disconnected
        } else if (callStatus == VoIPCallStatus.CALLEE_BUSY_ON_ANOTHER_CALL) {
            //when the receiver is busy on another call
        }
    }

    override fun onSuccess() {
        //App is notified on the main thread when the call-request is accepted and being processed by the signalling channel
    }

    override fun onFailure(callException: CallException) {
        //App is notified on the main thread when the call is failed
        Log.d("DirectCall: ", "error code: ${callException.errorCode}" 
               + "\n error message: ${callException.message}" 
               + "\n error explanation: ${callException.explanation}")
    }
}


DirectCallAPI.getInstance().call(applicationContext, receiverCuid, contextOfCall, callOptions, outgoingCallResponseListener)

The parameters to make a Direct Call are as follows:

Parameter

Description

Type

Notes

receiverCuid

It is the receiver's cuid.

String

  • Required
  • The Direct Call Android SDK returns CallException.CalleeInfoRequiredException error if this parameter is not passed.

contextOfCall

It specifies the context of the call. For example, Delivery Partner is calling, Driver is calling, Agent is calling, and so on.

String

  • Required
  • It must include alphanumeric characters, and its length must not exceed 64 characters.

callOptions

It is a JSON object with the following properties:

  • receiver_image (string)
  • initiator_image (string)

JSON Object

  • Optional
  • receiver_imageΒ is a URL that displays the receiver's image to the initiator of the call. (optional)
  • initiator_imageΒ is a URL that displays the initiator's image to the receiver of the call. (optional)

Call Button Handling

Before initiating a call, always check whether the Direct Call services are enabled or not using the isEnabled() method.

Add the following code inside the onClick handler of your call button:

if (DirectCallAPI.getInstance().isEnabled()) {
    DirectCallAPI.getInstance().call(getApplicationContext(), receiverCuid, contextOfCall, callOptions, outgoingCallResponseListener);
}
if(DirectCallAPI.getInstance().isEnabled) {
   DirectCallAPI.getInstance().call(applicationContext, receiverCuid, contextOfCall, callOptions, outgoingCallResponseListener)
}

Call Quality Control

The Direct Call Android SDK always checks the ping latency before processing the call initiation request. If the latency is more than 3 seconds, the Direct Call Android SDK does not process the call request and returns a CallException.BadNetworkException exception.

Receive a Direct Call

Direct Call uses the following routing channels to receive Direct Calls at the receiver's end:

Socket Channel

It is a primary routing channel. Direct Call Android SDK requires a successful initialization to receive a call on the socket channel.

FCM Channel

It is a secondary or fallback routing channel that is used when the receiver is not connected to the primary routing channel (Socket).

πŸ“˜

FCM Version

The minimum supported version of FCM is v21.0.0 for Direct Call Android SDK.

To enable the FCM channel, follow the steps below:

  1. Add your FCM Server Key to the Direct Call section of the CleverTap dashboard. Ignore it if you have already added it.

  2. Add the following code to your Application class:

CleverTapAPI.setDirectCallNotificationHandler(new DirectCallNotificationHandler());
CleverTapAPI.setDirectCallNotificationHandler(DirectCallNotificationHandler())
  1. Add the following code inside your FirebaseMessagingService:
public class MyFcmMessageListenerService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage message){
        new CTFcmMessageHandler().createNotification(getApplicationContext(), message);
    }
}
class MyFcmMessageListenerService : FirebaseMessagingService() {

    override fun onMessageReceived(message: RemoteMessage) {
        super.onMessageReceived(message)
        CTFcmMessageHandler().createNotification(applicationContext, message)
    }
}

πŸ“˜

Note

If you use CleverTap’s default implementation to handle the push notifications, then step 3 is not required. For more information, refer to Adding CleverTap's Listener Service.

Busy Handling

Direct Call Android SDK smartly handles the scenarios when the user is busy on a call.

The following scenarios describe the Direct Call Android SDK behavior:

Scenario 1: The user is busy on a call (VoIP or PSTN), and another user initiates a VoIP call to the busy user. In this case, the Direct Call Android SDK displays User is busy on another call on the outgoing call screen and declines the initiated call.

Scenario 2: The user is busy on a VoIP call, and meanwhile, the user answers a PSTN call meaning that two calls (VoIP and PSTN) are connected simultaneously. In this case, the Direct Call Android SDK prioritizes the PSTN call over the VoIP call by putting the VoIP call on hold for both the receiver and initiator of the VoIP call. After the PSTN call ends, the Direct Call Android SDK resumes the VoIP call.

πŸ“˜

Read Phone State Permission

The Read Phone State permission is a prerequisite for the busy handling of PSTN calls. The Direct Call Android SDK supports the underlying implementation only if the user has granted the Read Phone State permission.

Missed Call Solution

If the receiver misses a call, the Direct Call Android SDK shows a missed call notification to the receiver. The Direct Call Android SDK uses action buttons on the missed call notification to display a Call to Action (CTA).

To configure the CTA on the missed call notification, follow the steps during the initialization of the Direct Call Android SDK:

  1. Create a list of CTAs using the MissedCallActions class.
List<MissedCallActions> missedCallActionsList = new ArrayList<>();
missedCallActionsList.add(new MissedCallActions("<Unique Identifier>", "<label on action-button>"));
val missedCallActionsList: MutableList<MissedCallActions> = ArrayList()
missedCallActionsList.add(MissedCallActions("<Unique Identifier>", "<label on action-button>"))

πŸ“˜

Action Buttons

You can configure a maximum of three action buttons on a missed call notification.

  1. Handle the click events of the missed call CTAs. To do so, create a custom MissedCallActionsHandler class by implementing the MissedCallNotificationOpenedHandler.
public class MissedCallActionsHandler implements MissedCallNotificationOpenedHandler {

    @Override
    public void onMissedCallNotificationOpened(Context context, MissedCallNotificationOpenResult result) {
        //get the the action-details from result object and handle accordingly
        Log.d(TAG, "actionID: " + result.action.actionID
                + " actionLabel: " + result.action.actionLabel
                + " context of call: " + result.callDetails.callContext
                + " cuid of caller: " + result.callDetails.callerCuid
                + " cuid of callee: " + result.callDetails.calleeCuid);
    }
}
class MissedCallActionsHandler : MissedCallNotificationOpenedHandler {

    override fun onMissedCallNotificationOpened(context: Context, result: MissedCallNotificationOpenResult) {
        //get the the action-details from result object and handle accordingly
        Log.d(TAG, "actionID: " + result.action.actionID
                    + " actionLabel: " + result.action.actionLabel
                    + " context of call: " + result.callDetails.callContext
                    + " cuid of caller: " + result.callDetails.callerCuid
                    + " cuid of callee: " + result.callDetails.calleeCuid);
    }
}

πŸ“˜

Note

The MissedCallActionsHandler must not be a singleton class.

  1. Pass the list of MissedCallActions and the canonical path of the MissedCallActionsHandler in the
    setMissedCallReceiverActions(List<MissedCallActions> list, String path) method of the DirectCallInitOptions.Builder class.
List<MissedCallActions> missedCallActionsList = new ArrayList<>();
missedCallActionsList.add(new MissedCallActions("<Unique Identifier>", "<label on action-button>"));

//gets the name of the class including its package
String missedCallHandlerPath = MissedCallActionsHandler.class.getCanonicalName();

DirectCallInitOptions directCallInitBuilder = new DirectCallInitOptions.Builder(initOptions, allowPersistSocketConnection)
       .setMissedCallReceiverActions(missedCallActionsList, missedCallHandlerPath)
       .build();

DirectCallAPI.getInstance().init(getApplicationContext(), directCallInitBuilder, cleverTapAPI, directCallInitListener);
val missedCallActionsList: MutableList<MissedCallActions> = ArrayList()
missedCallActionsList.add(MissedCallActions("<Unique Identifier>", "<label on action-button>"))

//gets the name of the class including its package
val missedCallHandlerPath = MissedCallActionsHandler::class.java.canonicalName

val directCallInitBuilder = DirectCallInitOptions.Builder(options, allowPersistSocketConnection)
    .setMissedCallReceiverActions(missedCallActionsList, missedCallHandlerPath)
    .build()

DirectCallAPI.getInstance().init(applicationContext, directCallInitBuilder, cleverTapAPI, directCallInitListener)

Call Hangup Functionality

The call hangup functionality is user-driven, and ending the call depends on the user. For example, if one of the users in a call clicks the call hangup button from the ongoing call screen, the Direct Call Android SDK internally manages the call hangup functionality to end the call.

In the case of a metered call, when a business wants to end the call after a specific duration, you must maintain a timer in the app and use the following method to terminate the call when the timer ends:

DirectCallAPI.getInstance().getCallController().endCall();
DirectCallAPI.getInstance().callController?.endCall()

Override the Dashboard's Call Screen Branding

CleverTap dashboard provides a branding tool to alter the look and feel of the call screens. If you have multiple apps to integrate with the Direct Call Android SDK, all those apps will share the same branding that you have set from the CleverTap dashboard. By overriding the dashboard's call screen branding, you can have different branding for each of your apps.

To override the dashboard branding, use the overrideDefaultBranding(DCCallScreenBranding branding) method exposed via DirectCallInitOptions.Builder class:

DCCallScreenBranding callScreenBranding = new DCCallScreenBranding(bgColor, fontColor, logoUrl, buttonTheme);

DirectCallInitOptions directCallInitBuilder = new DirectCallInitOptions.Builder(initOptions, allowPersistSocketConnection)  
      .overrideDefaultBranding(callScreenBranding)
      .build();

DirectCallAPI.getInstance().init(getApplicationContext(), directCallInitBuilder, cleverTapAPI, directCallInitListener);
val callScreenBranding = DCCallScreenBranding(bgColor, fontColor, logoUrl, buttonTheme)

val directCallInitBuilder = DirectCallInitOptions.Builder(initOptions, allowPersistSocketConnection)
    .overrideDefaultBranding(callScreenBranding)
    .build()

DirectCallAPI.getInstance().init(applicationContext, directCallInitBuilder, cleverTapAPI, directCallInitListener)

The parameters to override the dashboard's call screen branding are as follows:

Parameter

Description

Type

Notes

bgColor

The background color of the call screens.

String

  • Required
  • Use any Hex color code. For example, #000000

fontColor

The color of the text displayed on the call screens.

String

  • Required
  • Use any Hex color code. For example, #ffffff

logoUrl

The image URL that renders on the call screens.

String

  • Required
  • Use an HTTPS URL only.

buttonTheme

The theme of the control buttons shown on the ongoing call screen (Mute, Speaker, and Bluetooth).

DCCallScreenBranding.ButtonTheme.LIGHT
OR DCCallScreenBranding.ButtonTheme.DARK

  • Required
  • The Light theme represents the white color of the buttons whereas Dark is for the black color.

Debugging

Direct Call Android SDK logs are default set to DirectCallAPI.DCLogLevel.INFO level. We recommend that you set the Direct Call Android SDK to VERBOSE mode to log warnings or other important messages to the Android logging system during development. To do so, set the debug level to DirectCallAPI.DCLogLevel.VERBOSE. If you want to disable the Direct Call Android SDK logs for the production environment, you can set the debug level to DirectCallAPI.DCLogLevel.OFF.

To debug your app with the Direct Call Android SDK, follow the steps below:

  1. Set the debug level for the Direct Call Android SDK.
DirectCallAPI.setDebugLevel(DirectCallAPI.DCLogLevel.INFO);    //Default Log level

DirectCallAPI.setDebugLevel(DirectCallAPI.DCLogLevel.DEBUG);   //Set Log level to DEBUG log warnings or other important messages

DirectCallAPI.setDebugLevel(DirectCallAPI.DCLogLevel.VERBOSE); //Set Log level to VERBOSE

DirectCallAPI.setDebugLevel(DirectCallAPI.DCLogLevel.OFF);     //Switch off the logs for Production environment
DirectCallAPI.setDebugLevel(DirectCallAPI.DCLogLevel.INFO)    //Default Log level

DirectCallAPI.setDebugLevel(DirectCallAPI.DCLogLevel.DEBUG)   //Set Log level to DEBUG log warnings or other important messages

DirectCallAPI.setDebugLevel(DirectCallAPI.DCLogLevel.VERBOSE) //Set Log level to VERBOSE

DirectCallAPI.setDebugLevel(DirectCallAPI.DCLogLevel.OFF)     //Switch off the logs for Production environment
  1. After setting the debug level to DirectCallAPI.DCLogLevel.VERBOSE, search for CleverTap:DirectCall. The logcat window displays the handshakes between the Direct Call Android SDK and your app.

Error Handling

The Direct Call Android SDK provides error reporting and handling. The onFailure(InitException) of the DirectCallInitResponse reports all the initialization errors, where the onFailure(CallException) of the OutgoingCallResponse reports all the Call errors.

Initialization Errors

Below is the list of the errors that you may receive while initializing the Direct Call Android SDK:

Error

Description

NoInternetException

No internet connection.

InitConfigRequiredException

The initOptions is missing.

DirectCallSdkNotInitializedException

The Direct Call Android SDK is not initialized.

ContactNotRegisteredException

The server was not able to process the user registration.

MissingAccountIdOrApiKeyException

The accountId and apikey parameters are missing.

MissingCuIdException

The cuid is missing.

InvalidCuidLengthException

The cuid length is invalid.

InvalidCuidException

Invalid cuid due to violation of valid cuid rules.

InvalidNameLengthException

The name's length is invalid.

InvalidAppIdException

The appId is invalid.

InvalidBrandingConfigException

The branding configuration is invalid.

SdkNotInitializedAppRestartRequiredException

The Direct Call Android SDK failed to initialize and requires another initialization.

Call Errors

Below is the list of possible errors while making a call:

Status

Description

NoInternetException

No internet connection.

MicrophonePermissionNotGrantedException

Microphone permission is not available.

InternetLostAtReceiverEndException

The Internet is lost at the receiver's end before the call connects.

ContactNotReachableException

The receiver is unreachable.

BadNetworkException

The Direct Call Android SDK can not initiate the call because of poor network strength.

CanNotCallSelfException

The Receiver and Initiator's cuid is the same.

CallContextRequiredException

The call context is missing.

CallContextExceededBy64Exception

The context's length is invalid.

InvalidAppContextException

Invalid context of the application.

CalleeInfoRequiredException

The receiver's cuid is missing.

VoIPCallException

An unknown error occurred while making the call.

ClientDisconnectedDueToNetworkProblemException

The Direct Call Android SDK is disconnected from the signaling channel, due to poor network connectivity.

IncorrectParamsInCallOptionsException

The callOptions parameters are invalid.

CanNotProcessCallRequest

Can not process new call requests as the Direct Call Android SDK is already processing another call request.

FAQ

Q. Is Direct Call accountId and apikey the same as CleverTap's accountId and token?
A. No. Direct Call accountId and apikey are different from CleverTap's accountId and token. You can find these details under your dashboard's Direct Call Settings.