Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
title: 'Accept a call'
description: 'Accept a call invitation with the Android SDK and retrieve room credentials.'
product: 'sdk'
context: 'chat/sdk/android'
template: 'guide'
status: 'published'
lastUpdated: '2026-08-10'
version: 'v4'
platform: 'android'
sourcePath: '/sdk/android/calling/managing-calls/accept-call'
---

After receiving the original `SignalingInfo` from `onReceiveNewInvitation`, pass it to `signalingAccept()`:

```java
OpenIMClient.getInstance().signalingManager.signalingAccept(
new OnBase<SignalingCertificate>() {
@Override
public void onSuccess(SignalingCertificate credentials) {
// credentials provides the roomID, token, and liveURL for joining a media room.
}

@Override
public void onError(int code, String error) {
// code and error describe the failure.
}
},
receivedInfo
);
```

Preserve the original `roomID`, inviter, invitees, and session type in `receivedInfo`. Do not rebuild it as an object that contains only `roomID`.

The success callback returns `SignalingCertificate`. Connect to the media room only after obtaining a valid `token` and `roomID`. A successful API call only confirms that the accept request was submitted to the server; it does not mean the call is established. Continue listening for [call events](/sdk/android/calling/managing-calls/handle-call-events) and update the call UI and state based on events from the inviter, other devices, or room participants.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: 'Cancel a call invitation'
description: 'Cancel a call invitation before it is accepted with the Android SDK.'
product: 'sdk'
context: 'chat/sdk/android'
template: 'guide'
status: 'published'
lastUpdated: '2026-08-10'
version: 'v4'
platform: 'android'
sourcePath: '/sdk/android/calling/managing-calls/cancel-call'
---

Before an invitation is accepted, the inviter can call `signalingCancel()`:

```java
OpenIMClient.getInstance().signalingManager.signalingCancel(
new OnBase<String>() {
@Override
public void onSuccess(String result) {
// The signaling request completed.
}

@Override
public void onError(int code, String error) {
// code and error describe the failure.
}
},
activeInfo
);
```

Pass the complete `SignalingInfo` saved when the call was started, not a new object containing only `roomID`. A successful callback means that the cancel signaling request completed; the application should also end the local pending-answer state and release unused media resources. Remote clients update through `onInvitationCancelled`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: 'Handle call events'
description: 'Register Android SDK invitation, participant, and media-stream callbacks in one call listener.'
product: 'sdk'
context: 'chat/sdk/android'
template: 'guide'
status: 'published'
lastUpdated: '2026-08-10'
version: 'v4'
platform: 'android'
sourcePath: '/sdk/android/calling/managing-calls/handle-call-events'
---

Register `OnSignalingListener` once in your application's call state manager. The SDK uses these callbacks to notify your app about incoming invitations, acceptances, rejections, cancellations, timeouts, hang-ups, and participants joining or leaving a room. Use them to update the call UI and local call state.

`SignalingManager` retains only one listener: calling `setSignalingListener()` again replaces the previous listener. When signing out or switching accounts, first stop updating the old account's call state, then set the listener for the new account.

```java
OpenIMClient.getInstance().signalingManager.setSignalingListener(
new OnSignalingListener() {
@Override
public void onReceiveNewInvitation(SignalingInfo info) {
// info contains the incoming call invitation.
}

@Override
public void onInviteeAccepted(SignalingInfo info) {
// info indicates that the call was accepted.
}

@Override
public void onInviteeRejected(SignalingInfo info) {
// info indicates that the call was rejected.
}

@Override
public void onInvitationCancelled(SignalingInfo info) {
// info indicates that the invitation was cancelled.
}

@Override
public void onInvitationTimeout(SignalingInfo info) {
// info indicates that the invitation timed out.
}

@Override
public void onInviteeAcceptedByOtherDevice(SignalingInfo info) {
// info indicates that another device accepted the call.
}

@Override
public void onInviteeRejectedByOtherDevice(SignalingInfo info) {
// info indicates that another device rejected the call.
}

@Override
public void onHangup(SignalingInfo info) {
// info indicates that the call ended.
}

@Override
public void onRoomParticipantConnected(RoomCallingInfo room) {
// room contains the participant that joined.
}

@Override
public void onRoomParticipantDisconnected(RoomCallingInfo room) {
// room contains the participant that left.
}

@Override
public void onStreamChange(String streamInfo) {
// streamInfo describes the media stream change.
}
}
);
```

| Callback | When it is called | What your app should do |
| --- | --- | --- |
| `onReceiveNewInvitation` | A new call invitation arrives. | Save the `SignalingInfo`, show the incoming-call UI, and let the user accept or reject it. |
| `onInviteeAccepted`, `onInviteeRejected` | An invitee accepts or rejects. | Update that member's call status. In a group call, do not affect the other members. |
| `onInvitationCancelled`, `onInvitationTimeout`, `onHangup` | An invitation is cancelled or times out, or either party hangs up. | Close the matching call UI, disconnect from the media room, and release local resources. |
| `onInviteeAcceptedByOtherDevice`, `onInviteeRejectedByOtherDevice` | Another device signed in to the same account accepts or rejects. | End the incoming-call UI on this device so that two devices do not handle the same invitation. |
| `onRoomParticipantConnected`, `onRoomParticipantDisconnected` | A member joins or leaves the media room. | Update the member's status in a group call. |
| `onStreamChange` | The server sends media-stream change information. | Parse the string according to your server integration, then update the media stream. |
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: 'Hang up a call'
description: 'Hang up an established call with the Android SDK.'
product: 'sdk'
context: 'chat/sdk/android'
template: 'guide'
status: 'published'
lastUpdated: '2026-08-10'
version: 'v4'
platform: 'android'
sourcePath: '/sdk/android/calling/managing-calls/hang-up-call'
---

After a call is established, any participant can call `signalingHungUp()` to hang up. Pass the complete `SignalingInfo` saved for the active call; its `roomID` must match the active media room.

```java
OpenIMClient.getInstance().signalingManager.signalingHungUp(
new OnBase<String>() {
@Override
public void onSuccess(String result) {
// The signaling request completed.
}

@Override
public void onError(int code, String error) {
// code and error describe the failure.
}
},
signalingInfo
);
```

The success callback only confirms that the hang-up signaling request completed; it does not release local resources automatically. Close the call UI, stop local capture, disconnect from the media room, and release the camera and microphone.
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: 'Reject a call'
description: 'Reject a call invitation with the Android SDK.'
product: 'sdk'
context: 'chat/sdk/android'
template: 'guide'
status: 'published'
lastUpdated: '2026-08-10'
version: 'v4'
platform: 'android'
sourcePath: '/sdk/android/calling/managing-calls/reject-call'
---

When the user declines an incoming call, pass the original `SignalingInfo` to `signalingReject()`:

```java
OpenIMClient.getInstance().signalingManager.signalingReject(
new OnBase<String>() {
@Override
public void onSuccess(String result) {
// The reject signaling request completed.
}

@Override
public void onError(int code, String error) {
// code and error describe the failure.
}
},
signalingInfo
);
```

The success callback only means that the reject signaling request completed. The inviter later updates its interface through `onInviteeRejected`; see [Handle call events](/sdk/android/calling/managing-calls/handle-call-events).
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: 'Start a group call'
description: 'Start a group audio or video call with the Android SDK.'
product: 'sdk'
context: 'chat/sdk/android'
template: 'guide'
status: 'published'
lastUpdated: '2026-08-10'
version: 'v4'
platform: 'android'
sourcePath: '/sdk/android/calling/managing-calls/start-group-call'
---

`signalingInviteInGroup()` starts a group call and uses the same parameter types as [Start a one-to-one call](/sdk/android/calling/managing-calls/start-single-call). For group calls, `invitation.groupID` must contain the group ID and `invitation.sessionType` is always `ConversationType.GROUP_CHAT`.

Only members in `inviteeUserIDList` are invited; setting `groupID` does not invite every group member automatically. Exclude the current user, empty IDs, and duplicates from the list. This example uses the group ID as the room ID; if you generate a separate `roomID`, every participant must use the same value.

```java
SignalingInvitationInfo invitation = new SignalingInvitationInfo();
invitation.setInviterUserID(currentUserID);
invitation.setInviteeUserIDList(selectedGroupMemberIDs);
invitation.setGroupID(groupID);
invitation.setRoomID(groupID);
invitation.setTimeout(30);
invitation.setMediaType("video");
invitation.setSessionType(ConversationType.GROUP_CHAT);
invitation.setPlatformID(Platform.ANDROID);
invitation.setCustomData("{\"source\":\"group-call\"}");

SignalingInfo info = new SignalingInfo();
info.setInvitation(invitation);
info.setOfflinePushInfo(offlinePushInfo);

OpenIMClient.getInstance().signalingManager.signalingInviteInGroup(
new OnBase<SignalingCertificate>() {
@Override
public void onSuccess(SignalingCertificate credentials) {
// credentials contains the media room credentials.
}

@Override
public void onError(int code, String error) {
// code and error describe the failure.
}
},
info
);
```

The success callback returns `SignalingCertificate`. `roomID` is the media room ID, `token` is the short-lived credential for joining it, `liveURL` is the media service address, and `busyLineUserIDList` lists busy users. Busy users do not prevent invitations to the remaining members, and a successful callback does not mean that any member has accepted.

Connect to the media room only after obtaining a valid `token` and `roomID`. A successful API call does not mean the invitees have accepted; merge subsequent state through [Handle call events](/sdk/android/calling/managing-calls/handle-call-events).
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
title: 'Start a one-to-one call'
description: 'Start a one-to-one audio or video call with the Android SDK.'
product: 'sdk'
context: 'chat/sdk/android'
template: 'guide'
status: 'published'
lastUpdated: '2026-08-10'
version: 'v4'
platform: 'android'
sourcePath: '/sdk/android/calling/managing-calls/start-single-call'
---

`signalingInvite()` starts a one-to-one call. The Android SDK handles call signaling; your application must connect a real-time audio/video engine with the returned room credentials.

## Parameters

Call signature:

```java
signalingInvite(OnBase<SignalingCertificate> callback, SignalingInfo info)
```

All fields below belong to `info`; dot notation represents nested objects. Only parameters shared by the Android and WASM SDKs are listed.

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `invitation` | `SignalingInvitationInfo` | Yes | The call invitation. |
| `invitation.inviterUserID` | `String` | Yes | The inviter; pass the current signed-in user ID. |
| `invitation.inviteeUserIDList` | `List<String>` | Yes | The invitees; for a one-to-one call, include only the other user. |
| `invitation.groupID` | `String` | Yes | Group ID. Pass an empty string for a one-to-one call. |
| `invitation.roomID` | `String` | Yes | The call's unique room identifier and the primary key for subsequent state. |
| `invitation.timeout` | `long` | Yes | Invitation timeout in seconds. |
| `invitation.mediaType` | `String` | Yes | The application-defined media type, typically `audio` or `video`. |
| `invitation.sessionType` | `int` | Yes | Use `ConversationType.SINGLE_CHAT` for one-to-one calls and `ConversationType.SUPER_GROUP_CHAT` for group calls. |
| `invitation.platformID` | `int` | Yes | The current client platform; pass `Platform.ANDROID`. |
| `invitation.customData` | `String` | No | Application extra data carried with the invitation. |
| `invitation.initiateTime` | `long` | No | The invitation start time. It is normally maintained by the signaling flow and does not need to be set manually. |
| `offlinePushInfo` | `OfflinePushInfo` | No | Push content used when the invitee is offline. |
| `offlinePushInfo.title` | `String` | Conditionally required | Push title; required when `offlinePushInfo` is provided. |
| `offlinePushInfo.desc` | `String` | Conditionally required | Push body; required when `offlinePushInfo` is provided. |
| `offlinePushInfo.ex` | `String` | Conditionally required | Push extension string; pass an empty string when there is no content. |
| `offlinePushInfo.iOSPushSound` | `String` | Conditionally required | iOS push sound; required when `offlinePushInfo` is provided. |
| `offlinePushInfo.iOSBadgeCount` | `boolean` | Conditionally required | Whether to update the iOS badge; required when `offlinePushInfo` is provided. |

```java
SignalingInvitationInfo invitation = new SignalingInvitationInfo();
invitation.setInviterUserID(currentUserID);
invitation.setInviteeUserIDList(Collections.singletonList(peerUserID));
invitation.setGroupID("");
invitation.setRoomID(roomID);
invitation.setTimeout(30);
invitation.setMediaType("video");
invitation.setSessionType(ConversationType.SINGLE_CHAT);
invitation.setPlatformID(Platform.ANDROID);
invitation.setCustomData("{\"source\":\"contact-card\"}");

SignalingInfo info = new SignalingInfo();
info.setInvitation(invitation);
info.setOfflinePushInfo(offlinePushInfo);

OpenIMClient.getInstance().signalingManager.signalingInvite(
new OnBase<SignalingCertificate>() {
@Override
public void onSuccess(SignalingCertificate credentials) {
// credentials provides the roomID, token, and liveURL for joining a media room.
}

@Override
public void onError(int code, String error) {
// code and error describe the failure.
}
},
info
);
```

The success callback returns `SignalingCertificate`. `roomID` identifies the media room, `token` is a short-lived join credential, `liveURL` is the media service address, and `busyLineUserIDList` contains busy users.

Connect the media engine only after receiving a valid `token` and `roomID`. API success does not mean the invitee accepted; merge subsequent state through [Handle call events](/sdk/android/calling/managing-calls/handle-call-events).
Loading
Loading