Home
/
Calls
/
Android

Calls integration to Chat

You can integrate Sendbird Calls to Sendbird Chat to provide users with a seamless experience in using Calls and Chat services by allowing them to make a call within a chat channel. With the implementation of Calls integration to Chat, the call screen will appear when the call starts and when the call ends users will return to the chat view.

Showing Calls integration to Chat view

Note: To turn on Calls integration to Chat on the Sendbird Dashboard, go to Settings > Chat > Messages.


Benefits

Calls integration to Chat provides the following benefits:

Natively integrated service

Sendbird Calls and Sendbird Chat are provided from the same app to offer an advanced in-app chat experience for users.

Call within channel

Users can directly make a call to anyone in a channel without leaving the app.

Immersive user experience

Smooth transition between Calls and Chat within a chat channel will make the user experience more engaging.


How it works

Since Calls integration to Chat is a way to add call capabilities to Sendbird Chat, it requires an app that uses Chat. If you already have one, you are ready to move to the next step. If you don’t have an app, learn how to set up Sendbird Chat from our About Chat SDK page.


Prerequisites

To use Calls integration to Chat, an environment setup is first needed for both Sendbird Calls and Sendbird Chat using the SDKs. To learn more about each, refer to Sendbird Calls for Android Quickstart and Sendbird Chat samples.


Requirements

The minimum requirements for Calls integration to Chat are:

  • Android 4.1 (API level 16) or higher
  • Java 8 or higher
  • Gradle 3.4.0 or higher
  • Sendbird Chat sample
  • Sendbird Chat SDK
  • Sendbird Calls SDK

Install the SDKs

To install the Calls SDK and the Chat SDK, do the following steps:

Step 1: Configuration

Sendbird Chat SDK and Sendbird Calls SDK both use singleton interfaces. Since these two SDKs work independently, create appropriate functions that can handle them together.

Step 2: Initialize the Calls SDK and the Chat SDK

Find your application ID from the Sendbird Dashboard to use in the Calls SDK and the Chat SDK.

Light Color Skin
Copy
// BaseApplication.java
@Override
public void onCreate() {
    ...
    SendBird.init(APP_ID, getApplicationContext());
    SendBirdCall.init(getApplicationContext(), APP_ID);
    ...
}

Step 3: Log in to the Calls SDK and the Chat SDK

To log in to the Calls and Chat SDKs, create a function that allows you to authenticate the Calls SDK and the Chat SDK together.

Light Color Skin
Copy
// SendBirdUser.java
class SendBirdUser {
    private User chatUser;
    private com.sendbird.calls.User callUser;

    public SendBirdUser(User chatUser, com.sendbird.calls.User callUser) {
        this.chatUser = chatUser;
        this.callUser = callUser;
    }

    public User getChatUser() {
        return chatUser;
    }

    public com.sendbird.calls.User getCallUser() {
        return callUser;
    }
}

// LoginHandler.java
interface LoginHandler {
    void onResult(SendBirdUser user, Exception e);
}

// LoginActivity.java
private void login(String userId, AuthenticateHandler handler) {
    SendBird.connect(userId, (chatUser, e) -> {
        if (e != null) {
            handler.onResult(null, e);
            return;
        }

        SendBirdCall.authenticate(new AuthenticateParams(userId), (callUser, e1) -> {
            if (e1 != null) {
                handler.onResult(null, e1);
                return;
            }

            handler.onResult(new SendBirdUser(chatUser, callUser), null);
        });
    });
}

As written above, the Chat SDK is authenticated by using the SendBird.connect() method and the Calls SDK is authenticated by using the SendBirdCall.authenticate() method.

Step 4: Log out from the Calls SDK and the Chat SDK

To log out from the Calls SDK and the Chat SDK, create a function that handles the two SDKs together like it was to log in.

Light Color Skin
Copy
private void logout(CompletionHandler handler) {
    SendBird.disconnect(() -> SendBirdCall.deauthenticate(handler::onCompleted));
}

Register push tokens

Push notifications services allow users to receive notifications when the app is in the background. Before utilizing this feature, you need to register appropriate push tokens to Sendbird server. To turn on this feature, go to Settings > Notifications in your dashboard.

In your FirebaseMessagingService.java instance, save the push token from onNewToken() method.

Light Color Skin
Copy
// FirebaseMessagingService.java
@Override
public void onNewToken(String token) {
    if (SendBird.getCurrentUser() == null) {    // not authenticated yet
        return;
    }

    registerPushToken(token, e -> {
        if (e == null) {
            // save token here
        }
    });
}

private void registerPushToken(String pushToken, CompletionHandler handler) {
    SendBird.registerPushTokenForCurrentUser(pushToken, (pushTokenRegistrationStatus, e) -> {
        if (e != null) {
            handler.onCompleted(e);
            return;
        }

        SendBirdCall.registerPushToken(pushToken, false, handler::onCompleted);
    });
}

Unregister push tokens

Before logging out, unregister the push tokens as shown below:

Light Color Skin
Copy
private void unregisterPushToken(String pushToken, CompletionHandler handler) {
    SendBird.unregisterPushTokenForCurrentUser(pushToken, e -> {
        if (e != null) {
            handler.onCompleted(e);
            return;
        }

        SendBirdCall.unregisterPushToken(pushToken, handler::onCompleted);
    });
}

Make a call

For integration between the Calls and Chat services, the Calls SDK provides a specific option when dialing. You can provide the group channel URL to a DialParams object of Sendbird Calls as shown below:

Light Color Skin
Copy
DialParams dialParams = new DialParams(CALLEE_ID).setSendBirdChatOptions(
    new SendBirdChatOptions().setChannelUrl(CHANNEL_URL)
);

DirectCall call = SendBirdCall.dial(dialParams, (directCall, e) -> {
    if (e == null) {    // dial success
        ...
    }
});

When a group channel URL is provided to the DialParams object, messages containing call information such as calling status and duration will be automatically sent to the channel when the call starts and ends.

The messages will contain call information in the plugins field of the BaseMessage instance which can be used to properly show information about the calls.


Create custom UI components

The sample app for Calls integration to Chat is built based on Sendbird Chat. In the Chat sample app, every chat message is associated with a specific type of instance from the RecyclerView.ViewHolder class. With different types of messages such as user message, file message, and admin message, different view types of ViewHolder class are shown to the user, offering a more intuitive user experience.

For UI components for Calls integration to Chat, use the list_item_group_chat_call_me.xml layout resource file which will show the UI component like the following when users make or receive a call:

Showing an UI component of an outgoing voice call.

An example of a call message you can create is demonstrated in the following adapter class file in the sample app: GroupChatAdapter.java.

To create similar UI components for Calls integration to Chat, follow the steps below:

  1. In Android Studio, go to res > layout and open the context menu.
  2. Select New > Layout Resource File.
  3. In the new resource file for custom layout, add image view and text view within linear layout to display icon and message. In the sample app, card view is used to display a call message.

Bind UI components

You can integrate the custom layouts to integrate Sendbird Calls to the group channel fragment of Chat. Customize your ViewHolder class to initialize and bind UI components by extending the RecyclerView.ViewHolder class.

Light Color Skin
Copy
public MyCallHolder(View itemView) {
    super(itemView);
    callText = (TextView) itemView.findViewById(R.id.text_group_chat_call);
    callImage = (ImageView) itemView.findViewById(R.id.image_call);
    dateText = (TextView) itemView.findViewById(R.id.text_group_chat_date);
    timeText = (TextView) itemView.findViewById(R.id.text_group_chat_time);
    messageStatusView = itemView.findViewById(R.id.message_status_group_chat);

    // Dynamic padding that can be hidden or shown based on whether the message is continuous.
    padding = itemView.findViewById(R.id.view_group_chat_padding);
}

void bind(Context context, final UserMessage message, GroupChannel channel, boolean isContinuous, boolean isNewDay, final OnItemClickListener clickListener, final OnItemLongClickListener longClickListener, final int position){
    ...
}

Show UI components

To show the registered UI components, you have to identify which messages are associated with the Calls SDK.

  1. The BaseMessage class from Sendbird Chat SDK has a field called plugins where you can store additional information to default values. The key-value plugins are delivered as [String: String] map.
  2. When a call is made from the Calls SDK, the plugin field of a message associated with the call will contain the following information: vendor: sendbird, type : call.
  3. Then, for the messages that have these fields, show the UI component created.
  4. The following can be used to identify a call message and specify the type of UI by adding it in the RecyclerView.getItemViewType() of the GroupChatAdapter.java file from the Chat sample:
Light Color Skin
Copy
public boolean isCallMessage(BaseMessage message) {
    if (!(message instanceof UserMessage)) {
        return false;
    }

    UserMessage userMessage = (UserMessage) message;
    List<Plugin> plugins = userMessage.getPlugins();
    if (plugins == null || plugins.isEmpty()) {
        return false;
    }

    for (Plugin plugin : plugins) {
        if (plugin.getVendor().equals("sendbird") && plugin.getType().equals("call")) {
            return true;
        }
    }

    return false;
}

Extract call data from plugins

A bind method of the customizable ViewHolder class shown below demonstrates a way to extract specific information from the plugin about Sendbird Calls.

The detail of a call plugin could be parsed into the CallInfo class as below.

Light Color Skin
Copy
class CallInfo {
    String callId;
    String callType;
    boolean isVideoCall;
    Long duration;
    DirectCallEndResult endResult;

    CallInfo(Plugin plugin) {
        callId = plugin.getDetail().get("call_id");
        callType = plugin.getDetail().get("call_type");
        isVideoCall = Boolean.parseBoolean(plugin.getDetail().get("is_video_call"));
        String durationAsString = plugin.getDetail().get("duration");
        duration = durationAsString != null ? Long.valueOf(durationAsString) : null;
        String endResultAsString = plugin.getDetail().get("end_result");

        switch (endResultAsString) {
            case "canceled":
                endResult = DirectCallEndResult.CANCELED;
                break;
            case "completed":
                endResult = DirectCallEndResult.COMPLETED;
                break;
            case "declined":
                endResult = DirectCallEndResult.DECLINED;
                break;
            case "timed_out":
                endResult = DirectCallEndResult.TIMED_OUT;
                break;
            case "connection_lost":
                endResult = DirectCallEndResult.CONNECTION_LOST;
                break;
            case "no_answer":
                endResult = DirectCallEndResult.NO_ANSWER;
                break;
            default:
                endResult = null;
                break;
        }
    }
}

Call holder.bind() method in onBindViewHolder() method of GroupChatAdapter.java and the details of calls will be displayed in the RecyclerView.


Create call activity

The call activity provides events for users such as ending a call, muting or unmuting the microphone, or offers local and remote video views on a user’s screen.

To create call activity, refer to VoiceCallActivity.java, VideoCallActivity.java, and CallActivity.java on our Sendbird Calls for Android Quickstart.


Use message bubble to call

Calls integration to Chat can provide a seamless user experience by allowing users to initiate a new call directly from a channel by tapping the messages that contain call information.

First, declare the OnItemClickListener interface in the GroupChatAdapter.java file.

Light Color Skin
Copy
interface OnCallMessageClickListener {
    void onCallMessageClick(UserMessage message);
}

In the bind method of the ViewHolder class, register a click listener for the group chat view fragment and implement the onClick() method like the following:

Light Color Skin
Copy
itemView.setOnClickListener(v -> {
    if (callMessageClickListener != null) {
        callMessageClickListener.onCallMessageClick(message);
    }
});

Implement below in the group chat view fragment to make a call with a tap.

Light Color Skin
Copy
// GroupChatFragment.java
mChatAdapter.setItemClickListener(new GroupChatAdapter.OnItemClickListener() {
    @Override
    public void onUserMessageItemClick(UserMessage message) {
        ...

        CallInfo callInfo = CallInfo(plugin);
        DirectCall call = SendBirdCall.getCall(callInfo.callId);
        if (call == null || call.isOngoing()) {
            return;
        }

        String calleeId = call.getCallee().getUserId();
        if (call.isVideoCall()) {
            CallService.dial(getActivity(), calleeId,true, mChannelUrl);
        } else {
            CallService.dial(getActivity(), calleeId,false, mChannelUrl);
        }
    }
});

Other requirements

To enhance the user experience for Calls integration to Chat, you should add features such as receiving calls using SendBirdPushHandler and push notifications. Refer to Calls integration to Chat for Quickstart and learn more about these essential features.