Reconnect a Call or Conversation's Media

Overview

This guide covers how to reconnect to a call or a conversation's media in your Android and iOS Vonage Client application.

Automatically Reconnect

The Client SDK can attempt to automatically reconnect to a call or a conversation's media if you set the client's autoReoffer configuration property. This is useful for when there is a short drop in internet connectivity or the user switches between cellular and WiFi.

val client = NexmoClient.Builder().autoMediaReoffer(true).build(this)
NexmoClient client = new NexmoClient.Builder()
    .autoMediaReoffer(true)
    .build(context);
let config = NXMClientConfig()
config.autoMediaReoffer = true
NXMClient.setConfiguration(config)
NXMClientConfig *configuration = [[NXMClientConfig alloc] init];
configuration.autoMediaReoffer = YES;
[NXMClient setConfiguration:configuration];

Listening for Call Status Changes

To know when the status of a call or conversation's media has changed, you can listen for media status events with the Android and iOS SDK. Note the disconnected state. A disconnected state means that there has been a temporary network issue and the client will attempt a reconnection providing the autoReoffer configuration property was set. If you did not set autoReoffer to true then you can manually reconnect here.

To get MediaConnectionState updates you need to add a NexmoMediaStatusListener. You can do this by setting it on a call's conversation object.

call?.conversation?.addMediaStatusListener(object: NexmoMediaStatusListener {
    override fun onMediaConnectionStateChange(legId: String, status: EMediaConnectionState) {
        // Update UI and/or reconnect
    }
})

To get MediaConnectionState updates, you need to add a NexmoMediaStatusListener. You can do this by setting it on a call's conversation object.

NexmoMediaStatusListener listener = new NexmoMediaStatusListener() {
    @Override
    public void onMediaConnectionStateChange(@NonNull String legId, @NonNull EMediaConnectionState status) {
        // Update UI and/or reconnect
    }
};

call.getConversation().addMediaStatusListener(listener);

To get NXMMediaConnectionStatus updates you need to conform to the NXMConversationDelegate. You can do this by setting it on a call's conversation object.

call.conversation.delegate = self

Then you can implement the onMediaConnectionStateChange delegate function

extension ViewController: NXMConversationDelegate {
    func conversation(_ conversation: NXMConversation, didReceive error: Error) {}

    func conversation(_ conversation: NXMConversation, onMediaConnectionStateChange state: NXMMediaConnectionStatus, legId: String) {
        // Update UI and/or reconnect
    }
}

To get NXMMediaConnectionStatus updates you need to conform to the NXMConversationDelegate. You can do this by setting it on a call's conversation object.

call.conversation.delegate = self

Then you can implement the onMediaConnectionStateChange delegate function

- (void)conversation:(NXMConversation *)conversation didReceive:(NSError *)error {}

- (void)conversation:(NXMConversation *)conversation onMediaConnectionStateChange:(NXMMediaConnectionStatus)state legId:(NSString *)legId {
    // Update UI and/or reconnect
}

Manually Reconnect

The Client SDK has functions for explicitly reconnecting a call or conversation's media. This is useful, for example, when you want to switch which device a user is speaking on without hanging up and starting a new call if the application dies.

Call:

client.reconnectCall("conversationId", "legId", object : NexmoRequestListener<NexmoCall> {
    override fun onSuccess(result: NexmoCall?) {
        // handle call
    }

    override fun onError(error: NexmoApiError) {
        // handle error
    }
})

Conversation media:

conversation.reconnectMedia()

Call:

NexmoRequestListener<NexmoCall> listener = new NexmoRequestListener<NexmoCall>() {
    @Override
    public void onSuccess(@Nullable NexmoCall result) {
        // handle call
    }

    @Override
    public void onError(@NonNull NexmoApiError error) {
        // handle error
    }
};

client.reconnectCall("conversationId", "legId", listener);

Conversation media:

conversation.reconnectMedia();

Call:

NXMClient.shared.reconnectCall(withConversationId: "", andLegId: "") { error, call in
    if error != nil {
        // handle error
        return
    }
    // handle call
}

Conversation media:

conversation.reconnectMedia()

Call:

[NXMClient.shared reconnectCallWithConversationId:@"" andLegId:@"" completionHandler:^(NSError * _Nullable error, NXMCall * _Nullable call) {
    if (error) {
        // handle error
        return;
    }
    // handle call
}];

Conversation media:

[conversation reconnectMedia];