Android
Calls Key Functions

Key Functions

This page explains key functions of Sendbird Calls consisting of how to make, receive, handle, and end a call from your client app.


Make a call

Initiate a call by providing the callee’s user id into the SendBirdCall.dial() method. Use the CallOptions object to choose initial call configuration, such as audio or video capabilities, video settings, and mute settings.

Light Color Skin
Copy
DialParams params = new DialParams(CALLEE_ID);
params.setVideoCall(true);
params.setCallOptions(new CallOptions());

DirectCall call = SendBirdCall.dial(params, new DialHandler() {
    @Override
    public void onResult(DirectCall call, SendBirdException e) {
        if (e == null) {
            // The call has been created successfully.
        }
    }
});

Receive a call

To receive an incoming call, a SendBirdCallListener event handler should already be registered in the callee’s client app. Accept or decline the call using the directCall.accept() or the directCall.end() method. If the call is accepted, a media session will automatically be established by the Calls SDK.

Before accepting the call, the call-specific DirectCallListener event handler must be added to the call object. It enables the callee’s app to react to events during the call through its callback methods.

Light Color Skin
Copy
SendBirdCall.addListener(UNIQUE_HANDLER_ID, new SendBirdCallListener() {
    @Override
    public void onRinging(DirectCall call) {
        call.setListener(new DirectCallListener() {
            @Override
            public void onEstablished(DirectCall call) {
            }

            @Override
            public void onConnected(DirectCall call) {
            }

            @Override
            public void onEnded(DirectCall call) {
            }

            @Override
            public void onRemoteAudioSettingsChanged(DirectCall call) {
            }

        });

        call.accept(new AcceptParams());
    }
});

The callee’s client app receives an incoming call through either the established connection with Sendbird server or a Firebase Cloud Messaging (FCM) push notification when the app is in the background. To use the Calls SDK in the callee’s client app, the SendBirdCall instance must deliver received FCM push notifications to the Calls SDK.

Light Color Skin
Copy
public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(@NonNull RemoteMessage remoteMessage) {
        if (SendBirdCall.handleFirebaseMessageData(remoteMessage.getData())) {
        
        } else {
            // Handle non-SendBirdCall Firebase messages.
        }
    }
}

Handle a current call

During a current call, both the caller and callee’s audio can be muted or unmuted by the directCall.muteMicrophone() or directCall.unmuteMicrophone() method. If one party changes audio settings, the other party receives an event callback through the DirectCallListener.onRemoteAudioSettingsChanged() method.

Light Color Skin
Copy
// Mute my microphone
call.muteMicrophone();
// Unmute my microphone
call.unmuteMicrophone();
// start to show video
call.startVideo();
// stop showing video
call.stopVideo();

// Receiving the event
call.setListener(new DirectCallListener() {
    ...

    @Override
    public void onRemoteAudioSettingsChanged(DirectCall call) {
        if (call.isRemoteAudioEnabled()) {
            // The remote user has been unmuted.
            // TODO: Display an unmuted icon.
        } else {
            // The remote user has been muted.
            // TODO: Display and toggles a muted icon.
        }
    }

    @Override
    public void onRemoteVideoSettingsChanged(DirectCall call) {
        if (call.isRemoteVideoEnabled()) {
            // The remote user has started video.
        } else {
            // The remote user has stopped video.
        }
    }
    ...

});

End a call

The directCall.end() method ends a current call of either the caller or callee’s side. If one party ends a current call, the other party receives an event callback through the DirectCallListener.onEnded() method.

Light Color Skin
Copy
// End a call
call.end();


// Receiving the event
call.setListener(new DirectCallListener() {
    ...

    @Override
    public void onEnded(DirectCall call) {
        // TODO: Release or destroy call-related views from here.
    }
    ...

});

Manage custom items

With custom items, you can store additional information to a call in addition to default values in the DirectCall object. These key-value custom items are delivered as a Map<String, String> and can be updated during the call. Examples of items that could be included in the call are customer service, refund, or inquiry for better user experience.

Add

Custom items can be added to a call either by a caller or a callee. When dialing, the caller can add a Map<String, String> to a DialParams object by using the setCustomItems() method. The default value of a call's custom items is an empty Map object.

Light Color Skin
Copy
Map<String, String> customItemsToAdd = new HashMap<>();
customItemsToAdd.put("key1", "value1");
customItemsToAdd.put("key2", "value2");
directCall.updateCustomItems(customItemsToAdd, (addedCustomItems, affectedKeys, e) -> {
    // Handle added custom items.
});

Update and delete

During a call, custom items can be modified by directly updating or deleting custom items of a given call. You can use directCall.updateCustomItems() to update current custom items with new custom items. If keys for the new custom items don't exist, new custom items will be added to the existing list of items. Otherwise, existing items will be replaced with new custom items.

You can modify custom items without directly referring to the DirectCall object. The custom items of the call from the SendBirdCall can also be modified by calling the same set of methods with an additional callId parameter. If a call with the corresponding callId exists, the SendBirdCall will update the custom items of that call.

You can delete a specific custom item with its given key by using directCall.deleteCustomItems() or delete all custom items associated with the call by using directCall.deleteAllCustomItems(). Through a completion handler, you will receive the updated custom items, a list of keys of the modified custom items, and an error from Sendbird server.

Light Color Skin
Copy
Map<String, String> customItemsToModify = new HashMap<>();
customItemsToModify.put("key1", "value3");
customItemsToModify.put("key2", "value4");
directCall.updateCustomItems(customItemsToModify, (modifiedCustomItems, affectedKeys, e) -> {
    // Handle updated custom items.
});

Set<String> customItemKeysToDelete = new HashSet<>();
customItemsKeysToDelete.add("key1");
customItemsKeysToDelete.add("key2");
directCall.deleteCustomItems(customItemKeysToDelete, (deletedCustomItems, affectedKeys, e) -> {
    // Handle deleted custom items.
});

directCall.deleteAllCustomItems((deletedCustomItems, affectedKeys, e) -> {
    // Handle deleted custom items.
});

Receive events

To receive events from Sendbird server when custom items are modified, you can implement onCustomItemsUpdated() and onCustomItemsDeleted() from the DirectCallListener. Events contain the DirectCall object of changed custom items and updatedKeys or deletedKeys. Custom items can always be modified, custom items are always modifiable, Custom items can always be modified, however these events will only be delivered if the call is ongoing. If the call ends, events are not delivered to the DirectCallListener. You can always access modified custom items with the Calls API or by using the directCall.getCustomItems().

Light Color Skin
Copy
directCall.setListener(new DirectCallListener() {
    ...

    @Override
    public void onCustomItemsUpdated(DirectCall call, List<String> updatedKeys) {
    }

    @Override
    public void onCustomItemsDeleted(DirectCall call, List<String> deletedKeys) {
    }

    ...
});

// You can get the call's custom items by calling the `getCustomItems()` method.
directCall.getCustomItems();

Add event handlers

There are two types of event handlers that the Calls SDK provides: SendBirdCallListener and DirectCallListener.

SendBirdCallListener

Add a device-specific SendBirdCallListener event handler using the SendBirdCall.addSendBirdCallListener() method. Once the event handler is added, responding to device events such as incoming calls can be managed as shown below.

Note: If a SendBirdCallListener event handler isn’t registered, a user can't receive an onRinging callback event, thus recommended to add this handler at the initialization of the app. Also, the SendBirdCallListener event handler is automatically removed when the app closes by default.

Light Color Skin
Copy
//The UNIQUE_HANDLER_ID below is a unique user-defined ID for a specific event handler.
SendBirdCall.addListener(UNIQUE_HANDLER_ID, new SendBirdCallListener() {
    @Override
    public void onRinging(DirectCall call) {
    }
});
MethodInvoked when

onRinging()

An incoming call is notified on the callee’s device.

onAudioInputDeviceChanged()

There are changes in the system’s audio input device or the available local audio input devices.

onAudioOutputDeviceChanged()

There are changes in the system’s audio output device or the available local audio output devices.

DirectCallListener

Before accepting the call, the call-specific DirectCallListener event handler must be added to the call object. It enables the callee’s app to react to events happening during the call through its callback methods.

Light Color Skin
Copy
call.setListener(new DirectCallListener() {
    @Override
    public void onEstablished(DirectCall call) {
    }

    @Override
    public void onConnected(DirectCall call) {
    }

    @Override
    public void onEnded(DirectCall call) {
    }

    @Override
    public void onRemoteAudioSettingsChanged(DirectCall call) {
    }

    @Override
    public void onCustomItemsUpdated(DirectCall call) {
    }

    @Override
    public void onCustomItemsDeleted(DirectCall call) {
    }
});
MethodInvoked when

onEstablished()

The callee has accepted the call by using the call.accept() method, but the media devices of caller and callee are not yet connected.

onConnected()

Media devices (for example, microphone and speakers) between the caller and callee are connected and can start the call.

onEnded()

One of the parties ends a call by using the call.end() method and a call is ended due to other reasons such as decline or connection lost.

onRemoteAudioSettingsChanged()

The other party changes their audio settings.

onRemoteVideoSettingsChanged()

The other party changes their video settings.

onCustomItemsUpdated()

The custom items of the call are updated.

onCustomItemsDeleted()

The custom items of the call are deleted.


Retrieve call information

One party’s information can be retrieved through the directCall.getLocalUser() method while the other party’s information through the directCall.getRemoteUser() method.


Retrieve call history

A user’s call history can be retrieved using the next() method of a DirectCallLogListQuery instance which returns a list of call objects.

Light Color Skin
Copy
DirectCallLogListQuery.Params params = new DirectCallLogListQuery.Params();
DirectCallLogListQuery query = SendBirdCall.createDirectCallLogListQuery(params);

query.next(new DirectCallLogListQueryResultHandler() {
    @Override
    public void onResult(List<DirectCallLog> callLogs, SendBirdException e) {
        if (e == null) {
            if (query.hasNext() && !query.isLoading()) {
                // The query.next() can be called once more to fetch more call logs.
            }
        }
    }
});

The call log can be immediately obtained after a call has ended. However, in the caller’s case, only the local log will be retrieved unless the sync has been made with the server. If you want to check whether a call log is synchronized with the server or not, use the callLog.isFromServer() method. To retrieve call history from the server instead of the local log, use the DirectCallLogListQuery.

Light Color Skin
Copy
call.setListener(new DirectCallListener() {
    ...

    @Override
    public void onEnded(DirectCall call) {
        ...
        
        DirectCallLog callLog = call.getCallLog();
        // Appropriately add this callLog object to the callLog list.
    }
    ...

});

Capture video views

During a video call, the caller and callee can capture the images of their streaming video by using either the captureLocalVideoVidew() or captureRemoteVideoView() methods when needed.

- Local video view

Light Color Skin
Copy
directCall.captureLocalVideoView(new CaptureVideoViewHandler() {
    @Override
    public void onCaptured(Bitmap capturedImage, SendBirdException e) {
        if (e != null) {    // Error handling 
            return;
        }
        // Implement code for handling a successfully-captured image.
    }
});

- Remote video view

Light Color Skin
Copy
directCall.captureRemoteVideoView(new CaptureVideoViewHandler() {
    @Override
    public void onCaptured(Bitmap capturedImage, SendBirdException e) {
        if (e != null) {    // Error handling 
            return;
        }
        // Implement code for handling a successfully-captured image.
    }
});

Note: For errors that may occur when capturing video views, see the Error Codes page.