How to programmatically merge calls in Android?

1.2k Views Asked by At

In Call Service

Am using InCallService to listen for incoming call and in onCallStateChanged callback am updating call state, I have successfully achieved till holding 'call 1' and connecting 'call 2', so 'call 1' is on HOLD and 'call 2' is on ACTIVE state respectively, now when I tap on merge, it throws an error as

"Unable to merge calls"

Am using Conference method to merge calls

For better understanding, am posting my code below

 class CallService : InCallService() {

    override fun onCallAdded(call: Call) {
        super.onCallAdded(call)
        CallManager.updateCall(call)

    }

    private val callCallback = object : Call.Callback() {
        override fun onStateChanged(call: Call, state: Int) {
            CallManager.updateCall(call)
        }
    }

    override fun onCallRemoved(call: Call) {
        super.onCallRemoved(call)
        call.unregisterCallback(callCallback)
        CallManager.updateCall(null)
    }
}


@TargetApi(Build.VERSION_CODES.M)
object CallManager {
    private const val LOG_TAG = "CallManager"
    private val subject = BehaviorSubject.create<GsmCall>()
    private var currentCall: Call? = null
    private var anotherCall: Call? = null
    fun updates(): Observable<GsmCall> = subject


    fun updateCall(call: Call?) {
        if (currentCall != null) {
            call?.let {
                if (it.details.handle.schemeSpecificPart ==
                    currentCall!!.details.handle.schemeSpecificPart
                )
                    currentCall = call
                else anotherCall = call
            }
        } else currentCall = call
        call?.let {
            subject.onNext(it.toGsmCall())
        }
    }


    fun cancelCall() {
        currentCall?.let {
            when (it.state) {
                Call.STATE_RINGING -> rejectCall()
                else -> disconnectCall()
            }
        }
    }


    fun holdCall() {
        currentCall?.let {
            when (it.state) {
                Call.STATE_ACTIVE -> currentCall?.hold()
                else -> Log.i(LOG_TAG, "Call not in connected state")
            }
        }
    }

//Conference call method
    fun conferenceCall() {
        anotherCall?.conference(currentCall)
    }

    fun swapConferenceCall() {
        currentCall?.swapConference()
    }

    fun mergeConferenceCall() {
        currentCall?.mergeConference()
    }

    fun unHoldCall() {
        currentCall?.let {
            when (it.state) {
                Call.STATE_HOLDING -> currentCall?.unhold()
                else -> Log.i(LOG_TAG, "Call not in connected state")
            }
        }
    }

    fun isCallOnHold(): Boolean {
        currentCall?.let {

            return when (it.state) {
                Call.STATE_HOLDING -> true
                else -> false
            }
        }
        return false
    }

    fun acceptCall() {
        Log.i(LOG_TAG, "acceptCall")
        currentCall?.let {
            it.answer(it.details.videoState)
        }
    }

    private fun rejectCall() {
        Log.i(LOG_TAG, "rejectCall")
        currentCall?.reject(false, "")
    }

    private fun disconnectCall() {
        Log.i(LOG_TAG, "disconnectCall")
        currentCall?.disconnect()
    }

}
1

There are 1 best solutions below

0
On
 anotherCall?.conference(currentCall)
 currentCall?.mergeConference();//add this line