Android SDK tutorial

Follow this guide to quickly run an example project. There are two versions available: one in Java and another one in Kotlin.

Java version

SippoClient example

This section explains how to create and register a SippoClient instance.

First, you need to configure the client with the server URL. The static method “configure” in SippoClient creates and configures a new client instance. This instance is saved as a static property in the class so that it can be accessed from anywhere.

URL serverUrl;

SippoClient.configure(serverUrl);

Important: If other client instance already exists, it will continue alive (an explicit disconnect is required).

The WebRTC protocol must also be configured for conference related features to work properly. This should be done only once during the application’s lifecycle.

SippoClient.configureRTC(applicationContext);

In order to receive the session state changes, it is necessary to implement the SessionsListener interface and add it as a listener through the Sessions service.

public class SessionListenerExample implements SessionsListener {

    @Override
    public void onSessionStateReceived(@NotNull Sessions sessions, @NotNull State state) {
        // Do something
    }

}

SessionsListenerExample sessionsListenerExample;

SippoClient.getClient().getSessions().addListener(sessionsListenerExample);

The listener can also be removed through the Sessions service.

SessionsListenerExample sessionsListenerExample;

SippoClient.getClient().getSessions().removeListener(sessionsListenerExample);

At this point, if the user wants to establish a session, they need to authenticate. Basic, token or anonymous authentication can be used.

Authentication.Basic authenticationType = new Authentication.Basic("user", "password");

SippoClient.getClient().getSessions().connect(authenticationType, applicationContext);

If the request is processed correctly, the session state will be connected. If there is any problem, it will be error (we can have more information about the error by checking the field “reason” if needed).

In case the user has been previously authenticated, we can check if the session information is available and, if so, try to restore the former session.

if (SippoClient.getClient().getSessions().canRestoreSession(applicationContext)) {

    // We can try to restore the session

    SippoClient.getClient().getSessions().restore(applicationContext);

} else {

    // We need the user to authenticate as explained before

}

In this case, the session state will be connected if the session is successfully restored. Otherwise, it will be Error and the reason will be “RESTORE_NOT_POSSIBLE”.

When the application goes to background, if the session is already connected, it should be suspended. After this request, the session state will change to Disconnected with reason “CONNECTION_CLOSED”.

SippoClient.getClient().getSessions().suspend();

To permanently disconnect the session it is necessary to do it explicitly.

IMPORTANT: After invoke this method, it is necessary to configure a new client instance again in order to start a new session.

SippoClient.getClient().getSessions().disconnect(applicationContext);

After disconnecting the session, the state will also be disconnected but the reason will be different (it will be “LOGOUT” in this case).

In order to receive Firebase push notifications, a Firebase token must be configured. The SDK will automatically register this token in the server once the session is connected.

SippoClient.getClient().getSessions().setPushToken(context, "token");

Conferences example

This section explains how to receive or create a new conference and how to interact with it. In case we want to create a new conference:

Conference conference;

SippoClient.getClient().getConferences().createConference ( either -> {

    if (either.value() != null) {
        // Conference has been successfully created
        conference = either.value();
        ...

    } else {
        // An error has occurred
        ...
    }

    return Unit.INSTANCE;

});

Once the conference is created, we can join it directly and invite someone to the conference afterwards or the other way around.

Conference conference;
List<MediaType> requestedMedia = new ArrayList<>(Arrays.asList(MediaType.AUDIO, MediaType.VIDEO));

conference.inviteParticipant("participant", applicationContext, requestedMedia, true);

The “joinOnAnswer” parameter in the inviteParticipant method must be false if the user has already joined the conference explicitly before sending the invitation. Otherwise, we can set this parameter to true or invoke the method to join the conference after the invitation has been sent.

In order to cancel or left the conference:

Conference conference;

conference.hangup();

To receive a new conference, first of all it is necessary to implement and add the related listener through the Conferences service.

public class ConferencesListenerExample implements ConferencesListener {

    @Override
    public void onNewConference(@NotNull Conferences conferences, @NotNull Conference conference) {
         // We can join the conference or decline it
         // If the user decides to join it, be sure to set up the listener for this particular conference
         ...
    }

}

ConferencesListenerExample conferencesListenerExample;

SippoClient.getClient().getConferences().addListener(conferencesListenerExample);

The listener can also be removed through the same service.

ConferencesListenerExample conferencesListenerExample;

SippoClient.getClient().getConferences().removeListener(conferencesListenerExample);

When a conference is received, we can choose between joining it…

Conference conference;
List<MediaType> sharedMedia = new ArrayList<>(Arrays.asList(MediaType.AUDIO, MediaType.VIDEO));

conference.join(applicationContext, sharedMedia);

… or hanging up the conference as explained before.

Conference conference;

conference.hangup();

Once we have a conference instance (created or received) and before doing any action over it, we should set the ConferenceListener to receive the related events, such as when its state changes, when a new participant is added or when the media shared by a participant is modified.

public class ConferenceListenerExample implements ConferenceListener {

    @Override
    public void onConferenceStateReceived(@NotNull Conference conference, State state) {
        // Do something
    }

    @Override
    public void onInvitationUpdated(@NotNull Conference conference, Invitation invitation) {
        // Do something
    }

    @Override
    public void onParticipantAdded(@NotNull Conference conference, @NotNull Participant participant) {
        // Do something
    }

    @Override
    public void onParticipantRemoved(@NotNull Conference conference, @NotNull String participantName) {
        // Do something
    }

    @Override
    public void onLocalVideoAdded(@NotNull Conference conference) {
        // We can display de local video using the proper method
        conference.displayLocalVideo(localVideoRenderer, RenderCommon.ScalingType.SCALE_ASPECT_BALANCED, false);
    }

    @Override
    public void onRemoteVideoAdded(@NotNull Conference conference, @NotNull String participantName) {
        // We can display de remote video using the proper method
        conference.displayRemoteVideo(participantName, remoteVideoRenderer, RenderCommon.ScalingType.SCALE_ASPECT_BALANCED, false);
    }

    @Override
    public void onRemoteVideoRemoved(@NotNull String participant) {
        // Do something
    }

}

ConferenceListenerExample conferenceListenerExample;
Conference conference;

conference.addListener(conferenceListenerExample)

Note: After executing the join action against the conference, you should receive a new conference state (through the callback onConferenceStateReceived) with the state JOINING. Then, if everything goes well, you will receive another event with the state JOINED. In case of hanging up the conference, the conference state will change to FINISHED.

The listener can also be removed when it is no longer required.

ConferenceListenerExample conferenceListenerExample;
Conference conference;

conference.removeListener(conferenceListenerExample)

When an incoming conference is received, the application will be notified through the corresponding event if it is in foreground and with a push notification if the push token (from Firebase) has been registered previously.

If the application is not in foreground when the incoming conference is received, at the time the push notification arrives, it should be checked if the conference is still pending, either because the conference could have been canceled or because it might have already been answered on another device.

To check this issue:

String invitationId = "invitationId";

SippoClient.getClient().getConferences().isConferenceStillPending(invitationId, either -> {

    if(either.value() != null) {
        Boolean stillPending = either.value()
        // If true then the conference is still pending, otherwise it will be false
        ...

    } else {
        // An error has occurred
        ...
    }

});

Kotlin version

SippoClient example

This section explains how to create and register a SippoClient instance. First, you need to configure the client with the server URL. The static method “configure” in SippoClient creates and configures a new client instance. This instance is saved as a static property in the class so that it can be accessed from anywhere.

val serverUrl: URL

SippoClient.configure(serverUrl)

Important: If other client instance already exists, it will continue alive (an explicit disconnect is required).

The WebRTC protocol must also be configured for conference related features to work properly. This should be done only once during the application’s lifecycle.

SippoClient.configureRTC(applicationContext)

In order to receive the session state changes, it is necessary to implement the SessionsListener interface and add it as a listener through the Sessions service.

val sessionsListenerExample = object : SessionsListener {

    public override fun onSessionStateReceived(sessions: Sessions, state: SessionState.State) {
        // Do something
    }

}

SippoClient.client.sessions.addListener(sessionsListenerExample)

The listener can also be removed through the Sessions service.

val sessionsListenerExample : SessionsListener

SippoClient.client.sessions.removeListener(sessionsListenerExample)

At this point, if the user wants to establish a session, they need to authenticate. Basic, token or anonymous authentication can be used.

val authenticationType = Authentication.Basic("user","password")

SippoClient.client.sessions.connect(authenticationType, applicationContext)

If the request is processed correctly, the session state will be connected. If there is any problem, it will be error (we can have more information about the error by checking the field “reason” if needed).

In case the user has been previously authenticated, we can check if the session information is available and, if so, try to restore the former session.

if (SippoClient.client.sessions.canRestoreSession(applicationContext)) {

    // We can try to restore the session

    SippoClient.client.sessions.restore(applicationContext)

} else {

    // We need the user to authenticate as explained before

}

In this case, the session state will be connected if the session is successfully restored. Otherwise, it will be Error and the reason will be “RESTORE_NOT_POSSIBLE”.

When the application goes to background, if the session is already connected, it should be suspended. After this request, the session state will change to Disconnected with reason “CONNECTION_CLOSED”.

SippoClient.client.sessions.suspend()

To permanently disconnect the session it is necessary to do it explicitly.

IMPORTANT: After invoke this method, it is necessary to configure a new client instance again in order to start a new session.

SippoClient.client.sessions.disconnect(applicationContext)

After disconnecting the session, the state will also be disconnected but the reason will be different (it will be “LOGOUT” in this case).

In order to receive Firebase push notifications, a Firebase token must be configured. The SDK will automatically register this token in the server once the session is connected.

SippoClient.client.sessions.setPushToken(context, "token")

Conferences example

This section explains how to receive or create a new conference and how to interact with it. In case we want to create a new conference:

var conference: Conference

SippoClient.client.conferences.createConference { either ->

    either.onSuccess { conference ->
        // Conference has been successfully created
        this.conference = conference
        ...
    }

    either.onFailure {
        // An error has occurred
        ...
    }
}

Once the conference is created, we can join it directly and invite someone to the conference afterwards or the other way around.

var conference: Conference
val requestedMedia = listOf(MediaType.AUDIO, MediaType.VIDEO)

conference.inviteParticipant("participant", applicationContext, requestedMedia, true)

The “joinOnAnswer” parameter in the inviteParticipant method must be false if the user has already joined the conference explicitly before sending the invitation. Otherwise, we can set this parameter to true or invoke the method to join the conference after the invitation has been sent.

In order to cancel or left the conference:

var conference: Conference

conference.hangup()

To receive a new conference, first of all it is necessary to implement and add the related listener through the Conferences service.

val conferencesListenerExample = object : ConferencesListener {

    public override fun onNewConference(conferences: Conferences, conference: Conference) {
        // We can join the conference or decline it
        // If the user decides to join it, be sure to set up the listener for this particular conference
        ...
    }

}

SippoClient.client.conferences.addListener(conferencesListenerExample)

The listener can also be removed through the same service.

val conferencesListenerExample : ConferencesListener

SippoClient.client.conferences.removeListener(conferencesListenerExample)

When a conference is received, we can choose between joining it…

var conference: Conference
val sharedMedia = listOf(MediaType.AUDIO, MediaType.VIDEO)

conference.join(applicationContext, sharedMedia)

… or hanging up the conference as explained before.

var conference: Conference

conference.hangup()

Once we have a conference instance (created or received) and before doing any action over it, we should set the ConferenceListener to receive the related events, such as when its state changes, when a new participant is added or when the media shared by a participant is modified.

val conferenceListenerExample = object : ConferenceListener {

    public override fun onConferenceStateReceived(conference: Conference, state: State) {
        // Do something
    }

    public override fun onInvitationUpdated(conference: Conference, invitation: Invitation) {
        // Do something
    }

    public override fun onParticipantAdded(conference: Conference, participant: Participant) {
        // Do something
    }

    public override fun onParticipantRemoved(conference: Conference, participantName: String) {
        // Do something
    }

    public override fun onLocalVideoAdded(conference: Conference) {
        // We can display de local video using the proper method
        conference.displayLocalVideo(localVideoRenderer,RenderCommon.ScalingType.SCALE_ASPECT_BALANCED,false)
        ...
    }

    public override fun onRemoteVideoAdded(conference: Conference, participantName: String) {
        // We can display de remote video using the proper method
        conference.displayRemoteVideo(participantName, remoteVideoRenderer, RenderCommon.ScalingType.SCALE_ASPECT_BALANCED, false)
        ...
    }

    public override fun onRemoteVideoRemoved(participant: String) {
        // Do something
    }

}

conference.addListener(conferenceListenerExample)

Note: After executing the join action against the conference, you should receive a new conference state (through the callback onConferenceStateReceived) with the state JOINING. Then, if everything goes well, you will receive another event with the state JOINED. In case of hanging up the conference, the conference state will change to FINISHED.

The listener can also be removed when it is no longer required.

val conferenceListenerExample : ConferenceListener

conference.removeListener(conferenceListenerExample)

When an incoming conference is received, the application will be notified through the corresponding event if it is in foreground and with a push notification if the push token (from Firebase) has been registered previously.

If the application is not in foreground when the incoming conference is received, at the time the push notification arrives, it should be checked if the conference is still pending, either because the conference could have been canceled or because it might have already been answered on another device.

To check this issue:

val invitationId: String

SippoClient.client.conferences.isConferenceStillPending(invitationId) { either ->

    either.onSuccess { stillPending ->
        // If true then the conference is still pending, otherwise it will be false
        ...
    }

    either.onFailure {
        // An error has occurred
        ...
    }
}