Skip to content

Commit 600d6bd

Browse files
Merge branch 'feat/android'
2 parents b8b50ed + d0ab815 commit 600d6bd

321 files changed

Lines changed: 26833 additions & 7404 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
title: 'Accept a call'
3+
description: 'Accept a call invitation with the Android SDK and retrieve room credentials.'
4+
product: 'sdk'
5+
context: 'chat/sdk/android'
6+
template: 'guide'
7+
status: 'published'
8+
lastUpdated: '2026-08-10'
9+
version: 'v4'
10+
platform: 'android'
11+
sourcePath: '/sdk/android/calling/managing-calls/accept-call'
12+
---
13+
14+
After receiving the original `SignalingInfo` from `onReceiveNewInvitation`, pass it to `signalingAccept()`:
15+
16+
```java
17+
OpenIMClient.getInstance().signalingManager.signalingAccept(
18+
new OnBase<SignalingCertificate>() {
19+
@Override
20+
public void onSuccess(SignalingCertificate credentials) {
21+
joinMediaRoom(
22+
credentials.getRoomID(),
23+
credentials.getToken(),
24+
credentials.getLiveURL()
25+
);
26+
}
27+
28+
@Override
29+
public void onError(int code, String error) {
30+
showAcceptError(code, error);
31+
}
32+
},
33+
receivedInfo
34+
);
35+
```
36+
37+
Preserve the original `roomID`, inviter, invitees, and session type in `receivedInfo`. Do not rebuild it as an object that contains only `roomID`.
38+
39+
The success callback returns `SignalingCertificate`. Connect the media room only after receiving a valid `token` and `roomID`, then keep merging remote state through [Handle call events](/sdk/android/calling/managing-calls/handle-call-events).
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: 'Cancel a call invitation'
3+
description: 'Cancel a call invitation before it is accepted with the Android SDK.'
4+
product: 'sdk'
5+
context: 'chat/sdk/android'
6+
template: 'guide'
7+
status: 'published'
8+
lastUpdated: '2026-08-10'
9+
version: 'v4'
10+
platform: 'android'
11+
sourcePath: '/sdk/android/calling/managing-calls/cancel-call'
12+
---
13+
14+
Before an invitation is accepted, the inviter can call `signalingCancel()`:
15+
16+
```java
17+
OpenIMClient.getInstance().signalingManager.signalingCancel(
18+
new OnBase<String>() {
19+
@Override
20+
public void onSuccess(String result) {
21+
stopWaitingForAnswer(activeInfo.getInvitation().getRoomID());
22+
}
23+
24+
@Override
25+
public void onError(int code, String error) {
26+
showCancelError(code, error);
27+
}
28+
},
29+
activeInfo
30+
);
31+
```
32+
33+
Pass the complete `SignalingInfo` saved when the call was started, not a new object containing only `roomID`. A successful callback means that the cancel request completed. End the local waiting state and release unused media resources; remote clients update through `onInvitationCancelled`.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
title: 'Handle call events'
3+
description: 'Register Android SDK invitation, participant, and media-stream callbacks in one call listener.'
4+
product: 'sdk'
5+
context: 'chat/sdk/android'
6+
template: 'guide'
7+
status: 'published'
8+
lastUpdated: '2026-08-10'
9+
version: 'v4'
10+
platform: 'android'
11+
sourcePath: '/sdk/android/calling/managing-calls/handle-call-events'
12+
---
13+
14+
Register `OnSignalingListener` once in the call state layer. Merge invitation lifecycle, participant connection, and media stream changes by `roomID`.
15+
16+
```java
17+
OpenIMClient.getInstance().signalingManager.setSignalingListener(
18+
new OnSignalingListener() {
19+
@Override
20+
public void onReceiveNewInvitation(SignalingInfo info) {
21+
upsertCall(info, "ringing");
22+
}
23+
24+
@Override
25+
public void onInviteeAccepted(SignalingInfo info) {
26+
mergeCallEvent("accepted", info);
27+
}
28+
29+
@Override
30+
public void onInviteeRejected(SignalingInfo info) {
31+
mergeCallEvent("rejected", info);
32+
}
33+
34+
@Override
35+
public void onInvitationCancelled(SignalingInfo info) {
36+
mergeCallEvent("cancelled", info);
37+
}
38+
39+
@Override
40+
public void onInvitationTimeout(SignalingInfo info) {
41+
mergeCallEvent("timeout", info);
42+
}
43+
44+
@Override
45+
public void onInviteeAcceptedByOtherDevice(SignalingInfo info) {
46+
mergeCallEvent("accepted-by-other-device", info);
47+
}
48+
49+
@Override
50+
public void onInviteeRejectedByOtherDevice(SignalingInfo info) {
51+
mergeCallEvent("rejected-by-other-device", info);
52+
}
53+
54+
@Override
55+
public void onHangup(SignalingInfo info) {
56+
finishCall(info.getInvitation().getRoomID());
57+
}
58+
59+
@Override
60+
public void onRoomParticipantConnected(RoomCallingInfo room) {
61+
mergeConnectedParticipants(room.getRoomID(), room.getParticipant());
62+
}
63+
64+
@Override
65+
public void onRoomParticipantDisconnected(RoomCallingInfo room) {
66+
mergeDisconnectedParticipants(room.getRoomID(), room.getParticipant());
67+
}
68+
69+
@Override
70+
public void onStreamChange(String streamInfo) {
71+
mergeStreamChange(streamInfo);
72+
}
73+
}
74+
);
75+
```
76+
77+
This page owns the complete handling contract for the 11 call callbacks exposed by the Android adapter other than `onReceiveCustomSignal`. Custom signaling belongs to [Send a custom signal](/sdk/android/calling/sending-custom-signals/send-a-custom-signal).
78+
79+
Merge invitation events with `SignalingInfo.invitation.roomID`. Merge participant state with `RoomCallingInfo.roomID` plus the participant user ID. Do not merge by event order, display name, or array position. `onStreamChange` currently carries a string payload; parse and validate it according to the actual server protocol used by your deployment.
80+
81+
`SignalingManager` retains one listener. Setting another replaces the previous instance, and there is no public remove method. Combine custom signaling with these callbacks in the same application-level listener. When signing out or switching accounts, stop writing into old account state and replace the listener with the complete listener for the new account.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: 'Hang up a call'
3+
description: 'Hang up an established call with the Android SDK.'
4+
product: 'sdk'
5+
context: 'chat/sdk/android'
6+
template: 'guide'
7+
status: 'published'
8+
lastUpdated: '2026-08-10'
9+
version: 'v4'
10+
platform: 'android'
11+
sourcePath: '/sdk/android/calling/managing-calls/hang-up-call'
12+
---
13+
14+
After a call is established, a participant can call `signalingHungUp()`. The supplied `SignalingInfo` should preserve the complete invitation, and its `roomID` must match the active media room.
15+
16+
```java
17+
OpenIMClient.getInstance().signalingManager.signalingHungUp(
18+
new OnBase<String>() {
19+
@Override
20+
public void onSuccess(String result) {
21+
releaseCallResources(activeInfo.getInvitation().getRoomID());
22+
}
23+
24+
@Override
25+
public void onError(int code, String error) {
26+
showHangUpError(code, error);
27+
}
28+
},
29+
activeInfo
30+
);
31+
```
32+
33+
The success callback only means that the hang-up request completed. Stop local capture, disconnect the media room, and release the camera and microphone. Cancellation, rejection, timeout, and hang-up should all enter one idempotent cleanup flow keyed by `roomID`.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
title: 'Reject a call'
3+
description: 'Reject a call invitation with the Android SDK.'
4+
product: 'sdk'
5+
context: 'chat/sdk/android'
6+
template: 'guide'
7+
status: 'published'
8+
lastUpdated: '2026-08-10'
9+
version: 'v4'
10+
platform: 'android'
11+
sourcePath: '/sdk/android/calling/managing-calls/reject-call'
12+
---
13+
14+
When the user declines an incoming call, pass the original `SignalingInfo` to `signalingReject()`:
15+
16+
```java
17+
OpenIMClient.getInstance().signalingManager.signalingReject(
18+
new OnBase<String>() {
19+
@Override
20+
public void onSuccess(String result) {
21+
closeIncomingCallUI();
22+
}
23+
24+
@Override
25+
public void onError(int code, String error) {
26+
showRejectError(code, error);
27+
}
28+
},
29+
receivedInfo
30+
);
31+
```
32+
33+
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).
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
title: 'Start a group call'
3+
description: 'Start a group audio or video call with the Android SDK.'
4+
product: 'sdk'
5+
context: 'chat/sdk/android'
6+
template: 'guide'
7+
status: 'published'
8+
lastUpdated: '2026-08-10'
9+
version: 'v4'
10+
platform: 'android'
11+
sourcePath: '/sdk/android/calling/managing-calls/start-group-call'
12+
---
13+
14+
`signalingInviteInGroup()` starts a group call. It invites only the members explicitly listed in `inviteeUserIDList`; setting `groupID` does not automatically invite every group member.
15+
16+
```java
17+
SignalingInvitationInfo invitation = new SignalingInvitationInfo();
18+
invitation.setInviterUserID(currentUserID);
19+
invitation.setInviteeUserIDList(selectedGroupMemberIDs);
20+
invitation.setGroupID(groupID);
21+
invitation.setRoomID(groupID);
22+
invitation.setTimeout(30);
23+
invitation.setMediaType("video");
24+
invitation.setSessionType(ConversationType.GROUP_CHAT);
25+
invitation.setPlatformID(Platform.ANDROID);
26+
invitation.setCustomData("{\"source\":\"group-call\"}");
27+
28+
SignalingInfo info = new SignalingInfo();
29+
info.setUserID(currentUserID);
30+
info.setInvitation(invitation);
31+
info.setOfflinePushInfo(offlinePushInfo);
32+
33+
OpenIMClient.getInstance().signalingManager.signalingInviteInGroup(
34+
new OnBase<SignalingCertificate>() {
35+
@Override
36+
public void onSuccess(SignalingCertificate credentials) {
37+
startGroupCall(credentials);
38+
}
39+
40+
@Override
41+
public void onError(int code, String error) {
42+
showCallError(code, error);
43+
}
44+
},
45+
info
46+
);
47+
```
48+
49+
`groupID` must not be empty. Remove the current user, empty IDs, and duplicates from `inviteeUserIDList`. The example reuses the group ID as the room ID. If your application generates another `roomID`, every participant must use the same value.
50+
51+
The success callback returns `SignalingCertificate`; see [Start a one-to-one call](/sdk/android/calling/managing-calls/start-single-call) for its fields. `busyLineUserIDList` only identifies some unavailable members and should not stop invitations to the others. Success does not mean that any member has accepted.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
title: 'Start a one-to-one call'
3+
description: 'Start a one-to-one audio or video call with the Android SDK.'
4+
product: 'sdk'
5+
context: 'chat/sdk/android'
6+
template: 'guide'
7+
status: 'published'
8+
lastUpdated: '2026-08-10'
9+
version: 'v4'
10+
platform: 'android'
11+
sourcePath: '/sdk/android/calling/managing-calls/start-single-call'
12+
---
13+
14+
`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.
15+
16+
## Parameters
17+
18+
| Field | Type | Required | Description |
19+
| ------------------- | ----------------- | -------- | --------------------------------------------------------------------------- |
20+
| `userID` | `String` | Yes | The current signed-in user performing the invite operation. |
21+
| `inviterUserID` | `String` | Yes | The inviter, normally the current signed-in user. |
22+
| `inviteeUserIDList` | `List<String>` | Yes | The invitees; for a one-to-one call, include only the other user. |
23+
| `groupID` | `String` | Yes | Use an empty string for a one-to-one call. |
24+
| `roomID` | `String` | Yes | The call's unique room identifier and the primary key for subsequent state. |
25+
| `timeout` | `long` | Yes | Invitation timeout in seconds. |
26+
| `mediaType` | `String` | Yes | The application-defined media type, typically `audio` or `video`. |
27+
| `sessionType` | `int` | Yes | Use `ConversationType.SINGLE_CHAT`. |
28+
| `platformID` | `int` | Yes | Use `Platform.ANDROID` for an Android phone client. |
29+
| `customData` | `String` | No | Application extra data carried with the invitation. |
30+
| `offlinePushInfo` | `OfflinePushInfo` | No | Push content used when the invitee is offline. |
31+
32+
```java
33+
SignalingInvitationInfo invitation = new SignalingInvitationInfo();
34+
invitation.setInviterUserID(currentUserID);
35+
invitation.setInviteeUserIDList(Collections.singletonList(peerUserID));
36+
invitation.setGroupID("");
37+
invitation.setRoomID(roomID);
38+
invitation.setTimeout(30);
39+
invitation.setMediaType("video");
40+
invitation.setSessionType(ConversationType.SINGLE_CHAT);
41+
invitation.setPlatformID(Platform.ANDROID);
42+
invitation.setCustomData("{\"source\":\"contact-card\"}");
43+
44+
SignalingInfo info = new SignalingInfo();
45+
info.setUserID(currentUserID);
46+
info.setInvitation(invitation);
47+
info.setOfflinePushInfo(offlinePushInfo);
48+
49+
OpenIMClient.getInstance().signalingManager.signalingInvite(
50+
new OnBase<SignalingCertificate>() {
51+
@Override
52+
public void onSuccess(SignalingCertificate credentials) {
53+
joinMediaRoom(
54+
credentials.getRoomID(),
55+
credentials.getToken(),
56+
credentials.getLiveURL()
57+
);
58+
}
59+
60+
@Override
61+
public void onError(int code, String error) {
62+
showCallError(code, error);
63+
}
64+
},
65+
info
66+
);
67+
```
68+
69+
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.
70+
71+
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).

0 commit comments

Comments
 (0)