Skip to main content

Start an audio and video call

AgoraChatCallKit is an open-source audio and video UI library developed based on Agora's real-time communications and signaling services. With this library, you can implement audio and video calling functionalities with enhanced synchronization between multiple devices. In scenarios where a user ID is logged in to multiple devices, once the user deals with an incoming call that is ringing on one device, all the other devices stop ringing simultaneously.

This page describes how to implement real-time audio and video communications using the AgoraChatCallKit.

Understand the tech

The basic process for implementing real-time audio and video communications with AgoraChatCallKit is as follows:

  1. Initialize AgoraChatCallKit by calling init and add the AgoraChatCallKit event listener by calling setCallKitListener.
  2. Call startSingleCall or startInviteMultipleCall on the caller's client to send a call invitation for one-to-one or group calls.
  3. On the callee's client, accept or decline the call invitation after receiving onReceivedCall. Once a user accepts the invitation, they enter the call.
  4. When the call ends, the SDK triggers the onEndCallWithReason callback.

Prerequisites

Before proceeding, ensure that your development environment meets the following requirements:

  • Java Development Kit 1.8 or later.
  • Android Studio 3.5 or later.
  • targetSdkVersion 30.
  • minSdkVersion 21.
  • Gradle 4.6 or later.
  • a Chat project that has integrated the Chat SDK and implemented the basic real-time chat functionalities, including users logging in and out and sending and receiving messages.

Project setup

Take the following steps to integrate the AgoraChatCallKit into your project and set up the development environment.

  1. Add the dependency

    AgoraChatCallKit is developed upon io.agora.rtc:chat-sdk:x.x.x (1.0.5 and later) and io.agora.rtc:full-rtc-basic:x.x.x (3.6.2 and later). Follow the steps to add AgoraChatCallKit using Gradle.

    In /Gradle Scripts/build.gradle(Module: <projectname>.app), add the following lines to integrate the AgoraChatCallKit into your Android project:


    _1
    implementation 'io.agora.rtc:chat-callkit:1.0.1'

  2. Add project permissions

    In /app/Manifests/AndroidManifest.xml, add the following permissions after </application>:


    _10
    <!-- Add alert window -->
    _10
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    _10
    <!-- Access to the internet -->
    _10
    <uses-permission android:name="android.permission.INTERNET" />
    _10
    <!-- Access to the microphone -->
    _10
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    _10
    <!-- Access to the camera -->
    _10
    <uses-permission android:name="android.permission.CAMERA" />
    _10
    <!-- Access to the tasks -->
    _10
    <uses-permission android:name="android.permission.REORDER_TASKS" />

  3. Add the AgoraChatCallKit Activity

    In /app/Manifests/AndroidManifest.xml, add activities for the one-to-one audio and video call, and the group video call, for example, CallSingleBaseActivity (inherited from EaseCallSingleBaseActivity) and CallMultipleBaseActivity (inherited from EaseCallMultipleBaseActivity).


    _14
    <activity
    _14
    android:name=".av.CallSingleBaseActivity"
    _14
    android:configChanges="orientation|keyboardHidden|screenSize"
    _14
    android:excludeFromRecents="true"
    _14
    android:label="@string/demo_activity_label_video_call"
    _14
    android:launchMode="singleInstance"
    _14
    android:screenOrientation="portrait" />
    _14
    <activity
    _14
    android:name=".av.CallMultipleBaseActivity"
    _14
    android:configChanges="orientation|keyboardHidden|screenSize"
    _14
    android:excludeFromRecents="true"
    _14
    android:label="@string/demo_activity_label_multi_call"
    _14
    android:launchMode="singleInstance"
    _14
    android:screenOrientation="portrait" />

Implement audio and video calling

This section introduces the core steps for implementing audio and video calls in your project.

Initialize AgoraChatCallKit

Call init to initialize the AgoraChatCallKit after the Chat SDK is initialized. You can also add callback events to listen for and set the configurations. Refer to the following sample code:


_25
// Construct the CallKitConfig class.
_25
EaseCallKitConfig callKitConfig = new EaseCallKitConfig();
_25
// Set the call out time (ms).
_25
callKitConfig.setCallTimeOut(30 * 1000);
_25
// Set the Agora App ID.
_25
callKitConfig.setAgoraAppId("******");
_25
// Set whether to enable token authentication.
_25
callKitConfig.setEnableRTCToken(true);
_25
// Set the default avatar.
_25
callKitConfig.setDefaultHeadImage(getUsersManager().getCurrentUserInfo().getAvatar());
_25
// Set the ringtone file.
_25
String ringFile = EaseFileUtils.getModelFilePath(context,"huahai.mp3");
_25
callKitConfig.setRingFile(ringFile);
_25
// Set the user information.
_25
Map<String, EaseCallUserInfo> userInfoMap = new HashMap<>();
_25
userInfoMap.put("***",new EaseCallUserInfo("****",null));
_25
userInfoMap.put("***",new EaseCallUserInfo("****",null));
_25
callKitConfig.setUserInfoMap(userInfoMap);
_25
// Call init to initialie EaseCallKit.
_25
EaseCallKit.getInstance().init(context, callKitConfig);
_25
// Register the activity added in the Manifest file.
_25
EaseCallKit.getInstance().registerVideoCallClass(CallSingleBaseActivity.class);
_25
EaseCallKit.getInstance().registerMultipleVideoClass(CallMultipleBaseActivity.class);
_25
// Add event listeners to the AgoraChatCallKit.
_25
addCallkitListener();

In this method, you need to set the EaseCallKitConfig class. Some of the configurations include the following:


_19
/**
_19
* The EaseCallKitConfig class.
_19
* @param defaultHeadImage The default avatar. Set it as the absolute path of a local file or a URL.
_19
* @param userInfoMap The dictionary of the user information. The data format is key-value pairs, where key represents the user ID and value is EaseCallUser.
_19
* @param callTimeOut The timeout duration for the call invitation, in miliseconds. The default value is 30 seconds.
_19
* @param agoraAppId The Agora App ID.
_19
* @param ringFile The ringtone file, represented by the absolute path of a local file.
_19
* @param enableRTCToken Whether to enable token authentication for using the RTC service. If you enabled token authentication in Agora Console, set this parameter as true. The default value is false.
_19
*/
_19
public class EaseCallKitConfig {
_19
private String defaultHeadImage;
_19
private Map<String, EaseCallUserInfo> userInfoMap = new HashMap<>();
_19
private String ringFile;
_19
private String agoraAppId;
_19
private long callTimeOut = 30 * 1000;
_19
private boolean enableRTCToken = false;
_19
public EaseCallKitConfig(){
_19
...
_19
}

Send a call invitation

From the caller's client, call startSingleCall or startInviteMultipleCall to send a call invitation for a one-to-one call or group call. You need to specify the call type when calling the method.

  • One-to-one audio and video call

    Call startSingleCall to start a one-to-one call. You need to specify the call type as an audio call or video call in this method.


    _10
    /**
    _10
    * Starts a one-to-one call.
    _10
    *
    _10
    * @param type The call type:
    _10
    * - SINGLE_VOICE_CALL: A one-to-one voice call.
    _10
    * - SINGLE_VIDEO_CALL: A one-to-one video call.
    _10
    * @param user The user ID of the callee. Ensure that you set this parameter.
    _10
    * @param ext The extension information in the call invitation. Set it as null if you do not need this information.
    _10
    */
    _10
    public void startSingleCall(final EaseCallType type, final String user, final Map<String, Object> ext){}

The following screenshot gives an example of the user interface after sending a call invitation for one-to-one audio call:

  • Group audio and video call

    Call startInviteMultipleCall to start a group call. Set the call type as audio call or video call. You can set the users you want to invite from a chat group or the contact list. Refer to ConferenceInviteActivity in the sample project for implementation.


    _10
    /**
    _10
    * Starts a group call.
    _10
    *
    _10
    * @param type The call type:
    _10
    * - SINGLE_VOICE_CALL: A one-to-one voice call.
    _10
    * - SINGLE_VIDEO_CALL: A one-to-one video call.
    _10
    * @param user The user ID of the callee. Ensure that you set this parameter.
    _10
    * @param ext The extension information in the call invitation. Set it as null if you do not need this information.
    _10
    */
    _10
    public void startInviteMultipleCall(final EaseCallType type, final String[] users, final Map<String, Object> ext) {}

Receive the invitation

Once a call invitaion is sent, the callee receives the invitation in the onReceivedCall callback.


_7
/**
_7
* Occurs when a call invitation is received.
_7
* @param callType The call type.
_7
* @param fromUserId The user ID of the caller.
_7
* @param ext The extension information in the call invitation. Set it as null if you do not need this information.
_7
*/
_7
void onReceivedCall(EaseCallType callType, String fromUserId, JSONObject ext);

If the callee is online and available for a call, you can pop out a user interface that allows the callee to accept or decline the invitation. Refer to the following screenshot to implement the interface:

Send a call invitation during a group call

In call sessions with multiple users, these users can also send call invitations to other users. After sending the invitation, the SDK triggers the onInviteUsers callback in EaseCallKitListener on the sender's client.


_7
/**
_7
* Occurs when the local user sends a call invitation during a group call.
_7
* @param callType The call type.
_7
* @param existMembers The current members of the group call, excluding the local user.
_7
* @param ext The extension information in the call invitation. Set it as null if you do not need this information.
_7
*/
_7
void onInviteUsers(EaseCallType callType, String[] existMembers, JSONObject ext);

Refer to io.agora.chatdemo.group.fragments.MultiplyVideoSelectMemberChildFragment in the sample project for the user interface of the call invitation.

Listen for callback events

When a remote user joins the call, all the other users in the call receive the onRemoteUserJoinChannel callback. You need to look up the Chat user ID corresponding to the Agora UID in you app server.

  • If you find the Chat user ID, construct the user ID to an EaseUserAccount object and return it to the app using the callback parameter in onRemoteUserJoinChannel. For the callback parameter, implement onUserAccount in EaseCallGetUserAccountCallback.
  • If you fail to find the Chat user ID, report the error code and descriptions using the onSetUserAccountError callback in the EaseCallGetYserAccountCallback class.

_9
/**
_9
* Occurs when the remote user joins the channel.
_9
*
_9
* @param channelName The channel name.
_9
* @param userName The Chat user ID.
_9
* @param uid The Agora UID.
_9
* @param callback The callback object.
_9
*/
_9
void onRemoteUserJoinChannel(String channelName, String userName, int uid, EaseCallGetUserAccountCallback callback);

End the call

A one-to-one call ends as soon as one of the two users hangs up, while a group call ends only after the local user hangs up. When the call ends, the SDK triggers the onEndCallWithReason callback.


_22
/**
_22
* Occurs when a call ends.
_22
* @param callType The call type.
_22
* @param channelName The channel name.
_22
* @param reason The reason why the call ends.
_22
* @param callTime The call duration.
_22
*/
_22
void onEndCallWithReason(EaseCallType callType, String channelName, EaseCallEndReason reason, long callTime);
_22
_22
// The reasons for a call ending.
_22
public enum EaseCallEndReason {
_22
EaseCallEndReasonHangup(0), // One of the call members hangs up.
_22
EaseCallEndReasonCancel(1), // The local user cancels the call.
_22
EaseCallEndReasonRemoteCancel(2), // The remote user cancels the call.
_22
EaseCallEndReasonRefuse(3),// The remote user rejects the call.
_22
EaseCallEndReasonBusy(4), // The remote user is busy.
_22
EaseCallEndReasonNoResponse(5), // The local user did not answer the phone.
_22
EaseCallEndReasonRemoteNoResponse(6), // The remote user did not answer the phone.
_22
EaseCallEndReasonHandleOnOtherDeviceRefused(7),// The call is rejected on another device.
_22
EaseCallEndReasonHandleOnOtherDeviceAgreed; // The call is answered on another device.
_22
....
_22
}

Next steps

This section contains extra steps you can take for the audio and video call functionalities in your project.

Call exceptions

If exceptions or errors occur during a call, the SDK triggers the onCallError callback in the EaseCallKitListener class, which reports the detailed information of the exception in AggoraChatCallError.


_7
/**
_7
* Reports call exceptions.
_7
* @param type The error type.
_7
* @param errorCode The error code.
_7
* @param description The error description.
_7
*/
_7
void onCallError(EaseCallError type, int errorCode, String description);

Types of call errors are as follows:


_8
public enum EaseCallError {
_8
// The process error.
_8
PROCESS_ERROR,
_8
// The RTC service error.
_8
RTC_ERROR,
_8
// The IM service error.
_8
IM_ERROR
_8
}

Update the call kit configuration

After initializing the AgoraChatCallKit, you can refer to the following sample code to update the configuration of the call kit:


_12
/**
_12
* Gets the current call kit configuration.
_12
*
_12
* @return The current call kit configuration.
_12
*/
_12
public EaseCallKitConfig getCallKitConfig();
_12
// Sets the default avatar.
_12
EaseCallKitConfig config = EaseCallKit.getInstance().getCallKitConfig();
_12
if(config != null){
_12
String Image = EaseFileUtils.getModelFilePath(context,"bryant.png"……);
_12
callKitConfig.setDefaultHeadImage(Image);
_12
}

Update the user avatar or nickname

When changes to the UI or the channel state occur, for example, when a new user joins the channel, onUserInfoUpdated is triggered to notify the app to update the UI.

After a user updates the user information, call io.agora.chat.callkit.general.EaseCallKitConfig#setUserInfo to set the modified user information. Ensure that this method is implemented in a synchronous function so that the UI is updated timely.


_17
/**
_17
* \~chinese
_17
* Occurs when the user information is updated.
_17
* @param userName The Chat user ID.
_17
*/
_17
void onUserInfoUpdate(String userName){
_17
// For example,
_17
/**
_17
EaseUser user = mUsersManager.getUserInfo(userName);
_17
EaseCallUserInfo userInfo = new EaseCallUserInfo();
_17
if (user != null) {
_17
userInfo.setNickName(user.getNickname());
_17
userInfo.setHeadImage(user.getAvatar());
_17
}
_17
EaseCallKit.getInstance().getCallKitConfig().setUserInfo(userName, userInfo);
_17
*/
_17
}

Authenticate users with the RTC token

To enhance communication security, Agora recommends that you authenticate app users with the RTC token before they join a call. To do this, you need to make sure that the Primary Certificate of your project is enabled, and setEnableRTCToken in the AgoraChatCallKit is set to true.


_5
EaseCallKitConfig callKitConfig = new EaseCallKitConfig();
_5
……
_5
callKitConfig.setEnableRTCToken(true);
_5
……
_5
EaseCallKit.getInstance().init(context, callKitConfig);

Once you enable token authentication, the SDK triggers the onGenerateRTCToken callback. You need to retrieve an RTC token in this callback following the steps:

  1. Retrieve the RTC token and Agora UID from your app server.
  2. Trigger onSetToken to pass the token and UID to the callback object.
  3. AgoraChatCallKit uses the token and UID to join the channel.

Tokens are generated on your app server using the token generator provided by Agora. For how to generate a token on the server and retrieve and renew the token on the client, see Authenticate Your Users with Tokens.


_11
/**
_11
* Occurs when RTC token authentication is enabled.
_11
*
_11
* @param userId The Chat user ID of the current user.
_11
* @param channelName The channel name.
_11
* @param callback The callback object.
_11
*/
_11
default void onGenerateRTCToken(String userId, String channelName, EaseCallKitTokenCallback callback) {
_11
// Pass the token and UID to the callback object.
_11
// callback.onSetToken(token, uid);
_11
}

Push notifications

In scenarios where the app runs on the background or goes offline, use push notifications to ensure that the callee receives the call invitation. To enable push notifications, see Set up push notifications.

Once push notifications are enabled, when a call invitation arrives, a notification message pops out on the notification panel. Users can click the message to see the call invitation.

Reference

This section provides other reference information that you can refer to when implementing real-time audio and video communications functionalities.

API list

The AgoraChatCallKit provides the following APIs:

MethodDescription
initInitializes AgoraChatCallKit.
setCallKitListenerSets the event listener of the call kit.
startSingleCallStarts a one-to-one call.
startInviteMultipleCallStarts a group call.
getCallKitConfigRetrieves the configurations of AgoraChatCallKit.
registerVideoCallClassRegisters a one-to-one video call class.
registerMultipleVideoClassRegisters a group video call class.

EaseCallKitListener provides the following callback events:

EventDescription
onEndCallWithReasonOccurs when the call ends.
onInviteUsersOccurs when a member of the group call invites other users to the call.
onReceivedCallOccurs when the call invitation is received and the device rings.
onGenerateTokenRequests the RTC token. You need to pass the token to AgoraChatCallKit with callbacks.
onCallErrorReports exceptions and errors during the call.
onInviteCallMessageSentOccurs when the call invitation is sent.
onRemoteUserJoinChannelOccurs when a remote user joins the call.
onUserInfoUpdatedOccurs when the user information is updated. This callback is triggered when changes occur to the UI or the channel state in the AgoraChatCallKit.

EaseCallGetUserAccountCallback contains the following APIs:

EventDescription
onUserAccountOccurs when the Chat user ID correspondting to the Agora UID is retrieved.
onSetUserAccountErrorOccurs when the app fails to retrieve the user account.

EaseCallKitTokenCallback contains the following APIs:

EventDescription
onSetTokenOccurs when the app passes the retrieved RTC token to the AgoraChatCallKit.
onGetTokenErrorOccurs when the app fails to get the RTC token.

Sample project

Agora provides an open-source AgoraChat-android sample project on GitHub. You can download the sample to try it out or view the source code.

The sample project uses the Chat user ID to join a channel, which enables displaying the user ID in the view of the call. If you use the methods of the Agora RTC SDK to start a call, you can also use the Integer UID to join a channel.

Page Content