Gestion de la mise en attente des appels

Le Vonage Client SDK ne dispose pas d'une API dédiée à la « mise en attente ». À la place, La fonction « hold » est mise en œuvre en combinant les fonctions « mute » et « earmuff »:

  • mute(callId) — cesse d'envoyer votre son à votre interlocuteur
  • enableEarmuff(callId) — ne reçoit plus le son provenant de l'interlocuteur

Vers débloquer, inverser les deux : appel unmute(callId) et disableEarmuff(callId).

Sur iOS et Android, l'interface utilisateur des appels système (CallKit / framework Telecom) propose un bouton de mise en attente natif. Les guides de la plateforme ci-dessous expliquent comment associer ce bouton aux fonctions « Muet » et « Casque » du SDK.

Ce guide vous expliquera étape par étape comment mettre en place la fonctionnalité de mise en attente des appels dans vos applications iOS et Android à l'aide de notre SDK VoIP.

La mise en attente des appels n'est actuellement pas prise en charge par le SDK Web.

Intégration des télécommunications

Avant de vous lancer dans ce tutoriel, assurez-vous d'avoir intégré le framework Android Telecom à votre application.

Vous pouvez suivre le guide officiel ici ou découvrez notre application Android « Voice Sample » disponible ici.

Prise en charge de la conservation via la mise en œuvre de la connexion

Une fois que vous aurez développé votre implémentation de la Connexion classe, vous devrez ajouter le CAPABILITY_SUPPORT_HOLD aux capacités de connexion et remplacer le onHold() et onUnhold() des méthodes.

Voici un exemple en Kotlin :

class CallConnection(val callId: CallId) : Connection() {
    private lateinit var clientManager: VoiceClientManager
    var isOnHold = false
        private set

    init {
        connectionProperties = connectionProperties or PROPERTY_SELF_MANAGED
        connectionCapabilities = connectionCapabilities or CAPABILITY_SUPPORT_HOLD /** add other capabilities */
        audioModeIsVoip = true
    }

    // ... Other methods ...

    override fun onHold() {
        if (!isOnHold) {
            clientManager.holdCall(this)
        }
    }

    override fun onUnhold() {
        if (isOnHold) {
            clientManager.unholdCall(this)
        }
    }

    fun toggleHoldState() {
        isOnHold = !isOnHold
        if (isOnHold) setOnHold() else setActive()
    }
}

Interaction avec le SDK vocal

Pour activer le mode d'attente d'un appel, activez désactiver le son et cagoule simultanément.

Le code suivant, situé à l'intérieur de la balise VoiceClientManager La classe suivante en est une illustration :

class VoiceClientManager(private val context: Context) {
    private lateinit var client : VoiceClient

    fun holdCall(call: CallConnection){
        call.apply{
            client.mute(callId){ error ->
                error?.let {
                    println("Error muting when holding call with id: $callId")
                } ?: run {
                    client.enableEarmuff(callId){ error ->
                        error?.let {
                            println("Error enabling earmuff when holding with id: $callId")
                        } ?: run {
                            println("Call $callId successfully put on hold")
                            toggleHoldState()
                        }
                    }
                }
            }
        }
    }

    fun unholdCall(call: CallConnection){
        call.apply{
            client.unmute(callId){ error ->
                error?.let {
                    println("Error unmuting when unholding call with id: $callId")
                } ?: run {
                    client.disableEarmuff(callId){ error ->
                        error?.let {
                            println("Error disabling earmuff unholding call with id: $callId")
                        } ?: run {
                            println("Call $callId successfully removed from hold")
                            toggleHoldState()
                        }
                    }
                }
            }
        }
    }
}

N'hésitez pas à adapter ces extraits de code en fonction de votre implémentation et de vos besoins spécifiques.

Intégration de Callkit

Avant de vous lancer dans ce tutoriel, assurez-vous d'avoir intégré le framework Callkit à votre application.

Vous pouvez suivre le guide officiel, ou découvrez notre application iOS « Voice Sample » disponible ici.

Prise en charge via CXUpdate

Une fois que vous avez créé votre CallController classe, contenant une référence à un CXProvider et un CXCallController vous devrez activer la supportsHolding drapeau sur le CXCallUpdate tant pour les appels sortants que pour les appels entrants.

Voici un exemple en Swift :

import CallKit

class CallController {
    let callProvider: CXProvider
    let cxController = CXCallController()

    // ... Other methods ...

    func reportOutgoingCall(callId: String){
        self.callProvider.reportOutgoingCall(with: callId, connectedAt: Date.now)
        let update = CXCallUpdate()
        /** add other capabilities */
        update.supportsHolding = true
        self.callProvider.reportCall(with: callId, updated: update)
    }

    func reportIncomingCall(callId: String){
        let update = CXCallUpdate()
        /** add other capabilities */
        update.supportsHolding = true
        self.callProvider.reportNewIncomingCall(with: callId, update: update)
    }
}

Interaction avec le SDK vocal

Une fois que vous avez créé votre CXProviderDelegate mise en œuvre, écouter le CXSetHeldCallAction pour mettre des appels en attente à l'aide du SDK Voice.

Pour activer le mode d'attente d'un appel, activez désactiver le son et cagoule simultanément.

Le code suivant, situé à l'intérieur de la balise CallController La classe suivante en est une illustration :

import VonageClientSDKVoice

class CallController: NSObject {
    let callProvider: CXProvider
    let cxController = CXCallController()
    let client: VGVoiceClient
    var activeCalls: [UUID: String] = [:] // Maps CallKit UUID to Vonage callId

    // ... initialization and other methods ...
}

extension CallController: CXProviderDelegate {

    func provider(_ provider: CXProvider, perform action: CXSetHeldCallAction) {
        guard let callId = self.activeCalls[action.callUUID] else {
            action.fail()
            return
        }
        if action.isOnHold {
            self.client.mute(callId) { error in
                if let error = error {
                    print("Error muting when holding call: \(error)")
                    return
                }
                self.client.enableEarmuff(callId) { error in
                    if let error = error {
                        print("Error enabling earmuff when holding call: \(error)")
                        return
                    }
                    print("Call \(callId) successfully put on hold")
                }
            }
        } else {
            self.client.unmute(callId) { error in
                if let error = error {
                    print("Error unmuting when unholding call: \(error)")
                    return
                }
                self.client.disableEarmuff(callId) { error in
                    if let error = error {
                        print("Error disabling earmuff when unholding call: \(error)")
                        return
                    }
                    print("Call \(callId) successfully removed from hold")
                }
            }
        }
        // CallKit requires fulfilling the action synchronously
        action.fulfill()
    }
}

N'hésitez pas à adapter ces extraits de code en fonction de votre implémentation et de vos besoins spécifiques.