SDK setup

The following sections describe integration of the Voice SDK on the Android platform:


To use the Voice SDK you need:

Setup the development environment

Complete the following steps to setup your Android studio development environment:

  1. Open Android Studio and click Start a new Android Studio project.


  1. In the Select a Project Template window, select a template of your choice and click Next.


  1. In the Configure Your Project window:
    • Enter the name of your app, your Package name.
    • Enter the location your project will be saved
    • Select either Java or Kotlin as the language
    • Select API 23: Android 6.0 (Marshmellow) as the Minimum SDK and click Finish.


Add the Voice SDK as a dependency

Confirm you have the latest dependency version:

  1. Add the following to your top-level build.gradle file:
allprojects {
   repositories {


  1. Add the Wavecell dependency as well as sourceCompatibility in your app-level build.gradle file:
android {
   compileOptions {
      sourceCompatibility JavaVersion.VERSION_1_8
      targetCompatibility JavaVersion.VERSION_1_8

dependencies {
   implementation "com.eght:wavecell-voice-sdk:[LATEST_VERSION]"


  1. Click on File > Sync Project with Gradle Files.

You can now use the Voice SDK in your application.


Add the following uses-permission elements to your AndroidManifest

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

Initialize the SDK

To initialize the Voice SDK add the following in the onCreate function of your Application class.

To listen to Voice SDK logs, pass the class that implements the WavecellLogListener:

class MyApplication: Application(), WavecellLogListener {

   val wavecell = Wavecell.getInstance()

   override fun onCreate() {
      wavecell.init(this, this)

   override fun onLog(wavecellLog: WavecellLog) {
      //get SDK logs

The Voice SDK sends log information to the application.

Note: References to Wavecell in this document pertain to the wavecell object.

Register Wavecell user

In order for the Voice SDK to function correctly, you need to add Wavecell user information to make and receive calls. Use the following for user data:

val userConfiguration = WavecellUserConfiguration.Builder()


  • Msisdn is optional
  • The DeviceId is the device unique identifier, preferably FirebaseInstanceId. Refer to Work with instance IDs and GUIDs for more information.

Application information

The Voice SDK also requires application information in the setup. Use the following for application data:

val sessionConfiguration = WavecellSessionConfiguration.Builder()

Note: The Wavecell URL is provided by the console when you request access to the Voice SDK.

Activate the SDK

Once you have the configurations ready, use them to activate the Voice SDK. For example:

val configuration = WavecellConfiguration.Builder()
                .setOnFailureListener { exception ->
                    // Handle failure
                }.setOnSuccessListener {
                    // Handle success

Upon activation, the application is ready to make and receive calls. To check if the user is registered and activated, use


SDK state

The Voice SDK allows you to listen to the state it currently is in. To receive state updates, use the following listener:

wavecell.setOnStateChangedListener { state ->
   // Handle the state

Note: The state provided is type Wavecell.State which consists of values INACTIVE, ACTIVATING, ACTIVE, DEACTIVATING, and the initial value UNKNOWN.

Request runtime permissions

The Voice SDK requires access to READ_PHONE_STATE and RECORD_AUDIO permissions in order to successfully place and receive calls. To find out which permissions are not granted, call:

wavecell.setOnPermissionsListener { permissions ->
   ActivityCompat.requestPermissions (this, permissions, REQUEST_CODE)

Note: The Voice SDK needs phone and mic permission in order to make and receive calls. If you have not enabled access to these required permissions, you will receive them once per application lifecycle. An application lifecycle is defined as the time that an application has started until it is removed/killed.

Call features

Place a call

In order to place a call, the Voice SDK requires the callee contact information. Use the VoiceContact object from the Voice SDK to create the callee information.

Once the contact object is ready you can place a call using the following:

wavecell.makeCall(activity, contact) { result ->
   when (result) {
      is WavecellCallResult.Success -> {
         val voiceCall =
         // Handle success
      is WavecellCallResult.Failure -> {
         val exception = result.exception
         // Handle failure

Note: Passing activity is optional. This is required for the Voice SDK to prompt the user for permissions that are not granted while placing the call. When not provided, placing a call will fail with a PermissionNotGranted exception.

Mid-call features

The Voice SDK provides APIs to interact with an active VoiceCall object. These actions are:

  • accept()
  • reject()
  • endAndAccept()
  • hangup()
  • mute()
  • unmute()
  • hold()
  • resume()

You can also query the state of incoming calls such as isIncoming, isPeerOnHold, isMuted, and callStartTime.

The Voice SDK allows a user to have a second incoming call while a call is in progress. Notifications happens via the VoiceCallUpdateListener. The Voice SDK provides functionality to end the ongoing call and accept an incoming call using the endAndAccept action. The default accept behavior is to put the ongoing call on hold and accept the incoming call.

Call updates

In order to receive call updates use the setOnVoiceCallUpdateListener object. This object takes the class where you want to receive call updates:

wavecell.setOnVoiceCallUpdateListener (this.javaClass.simpleName, this) { disposable ->
   // Handle disposable

Once the listener is set up, call updates are received by the following callbacks:

override fun onCallAdded(call: VoiceCall) {
   // call recently added

override fun onCallRemoved(call: VoiceCall) {
   // call failed or finished.

override fun onCallUpdated(call: VoiceCall?) {
   // call that's recently updated.

override fun onCallFailed(call: VoiceCall?, exception: Exception) {
   // call that failed with an exception.

override fun onCallHoldUpdated(call: VoiceCall?) {
   // call that has been moved on hold because of accepting another incoming call.

Receive a call

The application needs to receive push notifications via FCM. If you are not using FCM on your project refer to this Firebase topic.

The application receives a push notification via the FirebaseMessagingService object as an indication of an incoming call. Once the application receives the push notification, it needs to check if the notification is for an incoming call. Use:


If the notification is for an incoming call, it is passed along with it’s context to the Voice SDK. To process an incoming call the Voice SDK starts a Foreground Service which requires a notification to be displayed by the application. The notification is displayed for a very short time and may display text such as Incoming call. This notification can be replaced by another notification with Accept and Reject actions as soon as updates are received.

Once the notification is ready, use the following:

wavecell.handleIncomingCall(context, data, notification, {
   when (it) {
      WavecellCallAction.PRESENT_INCOMING_CALL -> {
         // Show your incoming call notification
      WavecellCallAction.MUTE_INCOMING_CALL -> {
         // Show your mute incoming call notification
}) { result ->
   when (result) {
      is WavecellCallResult.Success -> {
         val call =
         // Handle incoming call success
      is WavecellCallResult.Failure -> {
         val call =
         // Handle incoming call failure

Update contact information

For any active call, you can update the contact information by using the following:

wavecell.updateContact(call.uuid, contact)

Note: You would need the VoiceCall uuid in order for the SDK to know which call contact information is being updated. This update will notify onCallUpdated from your VoiceCallUpdateListener implementation.

Audio control

The Voice SDK allows you to switch your audio output during a call by using the following:


To listen to audio output changes set up the following:

wavecell.setOnVoiceCallAudioOptionListener { audioOption ->
   // Handle audio option

Implementation of the Voice SDK also provides confirmation when your phone is connected to a bluetooth headset. The listener is invoked if the phone is connected to a bluetooth headset; otherwise the Voice SDK switches between SPEAKER and EARPIECE values.

To show a third option (bluetooth) use the following:

wavecell.switchAudioOption  {
   // Handle a third option (bluetooth)

Note: audioOption is of the type VoiceCallAudioOption which consists of the values of BLUETOOTH, SPEAKER, and EARPIECE.

Update the push token and phone number

After registration the push token and phone number that are provided during activation can be reconfigured.

For updating the push token add the following to the class which extends FirebaseMessagingService:

override fun onNewToken(token: String) {
   wavecell.updatePushToken(PushNotificationChannel(token), object: CompletionHandler {
      override fun onSuccess() {
         // Handle Success

      override fun onFailure(e: WavecellException) {
         // Handle failure

For updating the phone number, use the following:

wavecell.updatePhoneNumber("UPDATED_PHONE_NUMBER", object: CompletionHandler {
   override fun onSuccess() {
      // Handle Success

   override fun onFailure(e: WavecellException) {
      // Handle failure


To deactivate or unregister a user, use the following method:

wavecell.deactivate(object : CompletionHandler {
   override fun onSuccess() {
      // Handle success

   override fun onFailure(e: WavecellException){
      // Handle failure