Kotlin

Receive call

Before making a call lets add the ability to receive a call to the application. Add onGoingCallID and callInviteID properties at the top of the MainActivity class:

private var onGoingCallID: CallId? = null
private var callInviteID: CallId? = null

To listen for incoming calls add incoming call listener at the end of onCreate method inside MainActivity class:

client.setCallInviteListener { callId, from, channelType ->
    callInviteID = callId
    runOnUiThread {
        hideUI()
        answerCallButton.visibility = View.VISIBLE
        rejectCallButton.visibility = View.VISIBLE
    }
}

The app will now listen for the incoming call event. The above code shows the answer and the reject call buttons when the incoming call event is received. Notice that you are storing callInviteID reference to interact later with the call.

Before you will be able to perform actions using UI you also need to add listeners to the buttons. Add this code at of the onCreate inside MainActivity class:

answerCallButton.setOnClickListener { answerCall() }
rejectCallButton.setOnClickListener { rejectCall() }
endCallButton.setOnClickListener { endCall() }

To answer the call add answerCall method inside MainActivity class:

@SuppressLint("MissingPermission")
private fun answerCall() {
    callInviteID?.let {
        client.answer(it) {
            err ->
            when {
                err != null -> {
                    connectionStatusTextView.text = err.localizedMessage
                }
                else -> {
                    onGoingCallID = it
                    hideUI()
                    endCallButton.visibility = View.VISIBLE
                }
            }
        }
    }
}

After answering the call the end call button will be shown.

NOTE: The SuppressLint annotation is used for simplicity. In the production app you should make sure permissions are granted before answering the call.

To reject the call add rejectCall method inside MainActivity class:

private fun rejectCall() {
    callInviteID?.let {
        client.reject(it) { err ->
            when {
                err != null -> {
                    connectionStatusTextView.text = err.localizedMessage
                }
                else -> {
                    hideUI()
                    startCallButton.visibility = View.VISIBLE
                    waitingForIncomingCallTextView.visibility = View.VISIBLE
                }
            }
        }
        onGoingCallID = null
    }
}

To end the call add endCall method inside MainActivity class:

private fun endCall() {
    onGoingCallID?.let {
        client.hangup(it) {
            err ->
            when {
                err != null -> {
                    connectionStatusTextView.text = err.localizedMessage
                }
                else -> {
                    hideUI()
                    startCallButton.visibility = View.VISIBLE
                    waitingForIncomingCallTextView.visibility = View.VISIBLE
                }
            }
        }
    }
    onGoingCallID = null
}

Notice that after a successful rejecting or ending the call you set onGoingCall property value back to null.