Skip to content

infobip/infobip-rtc-android-1.x-deprecated

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 

Repository files navigation

Introduction

Infobip RTC is an Android SDK which enables you to take advantage of Infobip platform since it gives you the ability to enrich your Android applications with real-time communications in minimum time, allowing you to focus on your application's user experience and business logic. We currently support audio and video calls between two web or app users, and phone calls between a web or an app user and an actual phone device.

Here you will find an overview and a quick guide on how to connect to Infobip platform. There is also an in-depth reference documentation available.

First-time setup

In order to use Infobip RTC, you need to have Web and In-app Calls enabled on your account and that's it! You are ready to make Web and In-app calls. To learn how to enable them see the documentation.

Getting SDK

You can get our SDK through Gradle dependency which you pull from the Maven Central repository. Just add this snippet to your build.gradle:

dependencies {
    implementation ('com.infobip:infobip-rtc:+@aar') {
            transitive = true
    }
}

Authentication

Since Infobip RTC is an SDK, it means you develop your own application, and you only use Infobip RTC as a dependency. Your application has your own users, which we will call subscribers throughout this guide. So, in order to use Infobip RTC, you need to register your subscribers on our platform. The credentials your subscribers use to connect to your application are irrelevant to Infobip. We only need the identity they will use to present themselves. When we have the subscriber's identity, we can generate a token assigned to that specific subscriber. With that token, your subscribers can connect to our platform (using Infobip RTC SDK).

To generate these tokens for your subscribers, you need to call our /webrtc/1/token HTTP API method using proper parameters. There you authenticate yourself against Infobip platform, so we can relate the subscriber's token to you. Typically, generating a token occurs after your subscribers are authenticated inside your application. You will receive the token in a response that you will use to make and receive calls via InfobipRTC client in your Android application.

Permissions

The only dangerous SDK permissions needed are the RECORD_AUDIO and CAMERA permissions. That means you need to ask for them in runtime, inside your application. Here is how you can do that for record audio and how for camera. There are also three permissions with the normal protection level that are included in the SDK's manifest:

Making a call

You can call another subscriber if you know their identity. It is done via call method:

String token = obtainToken();
CallRequest callRequest = new CallRequest(
    token,
    getApplicationContext(),
    "Alice",
    new DefaultCallEventListener()
);

OutgoingCall call = InfobipRTC.call(callRequest);

Or if you want to initiate video call:

String token = obtainToken();
CallRequest callRequest = new CallRequest(
    token,
    getApplicationContext(),
    "Alice",
    new DefaultCallEventListener()
);
CallOptions callOptions = CallOptions.builder().video(true).build();

OutgoingCall call = InfobipRTC.call(callRequest, callOptions);

As you can see, call method returns an instance of OutgoingCall as a result. With it, you can track status of your call and invoke call actions.

In order to respond to certain actions during the call, you need to set up event handlers. You can forward said listener through the parameter callEventListener in the call request when making a call (as shown in previous example), or you can set it up when call is created via the setEventListener method as shown in the following example:

CallEventListener callEventListener = new CallEventListener() {
    @Override
    public void onRinging(CallRingingEvent callRingingEvent) {
        Log.d("WebRTC", "Call is ringing on Alice's device!");
    }

    @Override
    public void onEarlyMedia(CallEarlyMediaEvent callEarlyMediaEvent) {
        Log.d("WebRTC", "Ringback tone received!");
    }

    @Override
    public void onEstablished(CallEstablishedEvent callEstablishedEvent) {
        Log.d("WebRTC", "Alice answered call!");
    }

    @Override
    public void onHangup(CallHangupEvent callHangupEvent) {
        Log.d("WebRTC", "Call is done! Status: " + callHangupEvent.getErrorCode().toString());
    }

    @Override
    public void onError(CallErrorEvent callErrorEvent) {
        Log.d("WebRTC", "Oops, something went very wrong! Message: " + callErrorEvent.getReason().toString());
    }
};

outgoingCall.setEventListener(callEventListener);

To get the current event listener, use the getEventListener method:

CallEventListener callEventListener = outgoingCall.getEventListener();

The most important part of the call is definitely the media that travels between subscribers. It starts after the established event is received. In case of audio call, you don’t have to do anything to enable the media flow (receive the caller audio and send your audio to the caller), it is done automatically. In case of video call, you need to attach the video track received in established event to video UI element. You can use com.infobip.webrtc.sdk.api.video.VideoRenderer class to display remote video (and local, if you wish) on the UI:

<com.infobip.webrtc.sdk.api.video.VideoRenderer
  android:id="@+id/remote_video"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" />

Then, in your code, set up this renderer:

@Override
protected void onCreate(Bundle savedInstanceState) {
    //...
    VideoRenderer remoteVideoRenderer = findViewById(R.id.remote_video);
    remoteVideoRenderer.init();
    remoteVideoRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT); // choose scaling type that best fits your needs
}

When established event is received, connect the video track to renderer:

@Override
public void onEstablished(CallEstablishedEvent callEstablishedEvent) {
    Log.d("WebRTC", "Alice answered call!");
    VideoRenderer remoteVideoRenderer = findViewById(R.id.remote_video);
    RTCVideoTrack remoteRTCVideoTrack = callEstablishedEvent.getRemoteRTCVideoTrack();
    remoteRTCVideoTrack.addSink(remoteVideoRenderer);
    // do same for local video, if needed
}

When event handlers are set up and the call is established, there are a few things that you can do with the actual call. One of them, of course, is to hang up. That can be done via the hangup method on the call, and after that, both parties receive hangup event upon hang up completion.

outgoingCall.hangup();

You can simulate a digit press during the call, by sending DTMF codes (Dual-Tone Multi-Frequency). This is achieved via sendDTMF method. Valid DTMF codes are digits from 0-9, * and #.

outgoingCall.sendDTMF("*");

During the call, you can also mute (and unmute) your audio:

outgoingCall.mute(true);

To check if audio is muted, call muted method in the following manner:

boolean audioMuted = outgoingCall.muted();

Sound can also be played on the speakerphone during the call. That option can be toggled as many times as you like, just call the speakerphone method with the appropriate parameter. By default, it is disabled, you can enable it as shown below:

outgoingCall.speakerphone(true);

To check if the speakerphone is enabled, call the speakerphone method as shown in the example below:

boolean speakerphoneEnabled = outgoingCall.speakerphone();

Also, you can check the call status:

CallStatus status = outgoingCall.status();

Also, you can check information such as duration, start time, establish time and end time by calling these methods:

int duration = outgoingCall.duration();
Date startTime = outgoingCall.startTime();
Date establishTime = outgoingCall.establishTime();
Date endTime = outgoingCall.endTime();

Calling phone number

It is very much similar to calling a regular WebRTC user, you just use the callPhoneNumber method instead of a call. There is also the method overload that accepts a second parameter, where you can define the from parameter. Its value will display the calling phone device as the Caller ID. The result of the callPhoneNumber is also the OutgoingCall with which you can do everything as when using the call method:

String token = obtainToken();
CallRequest callRequest = new CallRequest(
    token,
    getApplicationContext(),
    "41793026727",
    new DefaultCallEventListener()
);
CallPhoneNumberOptions callPhoneNumberOptions = CallPhoneNumberOptions.builder().from("33712345678").build();

OutgoingCall call = InfobipRTC.callPhoneNumber(callRequest, callPhoneNumberOptions);

Receiving a call

There are two ways of receiving a call. Each one requires you to listen for incoming calls.

Receiving a call via push notification

Note: In order for push notifications to work, they have to be enabled for your application, as explained in the documentation.

The first way is to listen for push notifications which we send from our platform on your behalf to the correct device and in that case you need to provide us your FCM server key. After that, you handle them in your application by extending FirebaseMessagingService and overriding the onMessageReceived method. There you can relay push notification to our SDK via handleIncomingCall method. Here you can find complete tutorial on how to add Firebase to your app.

This is the recommended approach since it doesn't use much battery, as the connection is not kept alive, it only listens for incoming push notifications.

This is an example how to listen for push notifications:

String token = obtainToken();
InfobipRTC.enablePushNotification(
    token,
    getApplicationContext()
);

After which you can handle that in your application as shown below:

class FcmService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Map<String, String> payload = remoteMessage.getData();
        InfobipRTC.handleIncomingCall(
            payload,
            getAplicationContext(),
            new IncomingCallEventListener() {
                @Override
                public void onIncomingCall(IncomingCallEvent incomingCallEvent) {
                    IncomingCall incomingCall = incomingCallEvent.getIncomingCall();
                    Log.d("WebRTC", "Received incoming call from:  " + incomingCall.source().getIdentity() + " " + incomingCall.source().getDisplayName() );
                    incomingCall.setEventListener(new DefaultCallEventListener());
                    incomingCall.accept(); // or incomingCall.decline();
                }
            }
        );
    }
}

If you take a closer look at how to implement FCM in your application, you will see that there is a unique device token associated with one app installation on a single device. When you call the enablePushNotification method on a device, we take that device's token and associate it with an identity on our Infobip WebRTC platform.

As device tokens can change during app lifetime, you need to handle these changes. We implemented an Android service named FcmTokenRefresher that handles changes, you just need to include it in your app's manifest:

<application>
    <service
        android:name="com.infobip.webrtc.sdk.impl.fcm.FcmTokenRefresher"
        android:exported="false" />
</application>

Receiving a call via active connection

The second way to receive a call is to connect once via WebSocket connection to our Infobip WebRTC platform, keep it active, and receive calls via that connection. All this is implemented in our SDK, you just need to call the registerForActiveConnection method to actually start listening for incoming calls. The third parameter is the listener that is fired upon the incoming call.

The downside of this approach is that your app will consume a significant amount of battery, because it persists the connection. We recommend the first approach.

String token = obtainToken();
InfobipRTC.registerForActiveConnection(
    token,
    getApplicationContext(),
    new IncomingCallEventListener() {
        @Override
        public void onIncomingCall(IncomingCallEvent incomingCallEvent) {
            IncomingCall incomingCall = incomingCallEvent.getIncomingCall();
            Log.d("WebRTC", "Received incoming call from:  " + incomingCall.source().getIdentity() + " " + incomingCall.source().getDisplayName() );
            incomingCall.setEventListener(new DefaultCallEventListener());
            incomingCall.accept(); // or incomingCall.decline();
        }
    }
);

Conference call

You can have a conference call with other participants that are also in the same conference room. The conference call will start as soon as at least one participant joins.

Conference call is in the beta stage and available for audio only, with a maximum limit of 12 participants.

Joining the room is done via the joinConference method:

String token = obtainToken();
String conferenceId = "conference-demo"
ConferenceRequest conferenceRequest = new ConferenceRequest(
    getApplicationContext(), 
    conferenceId, 
    token,
    new DefaultConferenceEventListener()
);
Conference conference = InfobipRTC.joinConference(conferenceRequest);

After the user successfully joined the conference, the JoinedEvent event with a list of users that are already in that conference room, will be emitted, so that you can show those users on his screen. Also, the rest of the users will receive the UserJoinedEvent event, with information about the user that just joined the conference, so that you could show that user on their screens.

As you can see, the joinConference method returns an instance of Conference as the result. With it, you can track the status of your conference call and there are a few actions (mute, leave, speakerphone...) that you can do with the actual conference.

In order to respond to certain actions during the conference call, you need to set up event handlers. You can forward said listener through the parameter conferenceEventListener in the conference request when joining a conference (as shown in previous example), or you can set it up when conference call is created via the setEventListener method as shown in the following example:

ConferenceEventListener conferenceEventListener = new ConferenceEventListener() {
    @Override
    public void onJoined(JoinedEvent joinedEvent) {
        Toast.makeText(getApplicationContext(), "You have joined the conference!", Toast.LENGTH_LONG);
    }
    
    @Override
    public void onLeft(LeftEvent leftEvent) {
        Toast.makeText(getApplicationContext(), "You left the conference!", Toast.LENGTH_LONG);
    }
    
    @Override
    public void onUserJoined(UserJoinedEvent userJoinedEvent) {
        Toast.makeText(getApplicationContext(), userJoinedEvent.getUser().getIdentity() + " joined the conference!", Toast.LENGTH_LONG);
    }
    
    @Override
    public void onUserMuted(UserMutedEvent userMutedEvent) {
        Toast.makeText(getApplicationContext(), userMutedEvent.getIdentity() + " muted himself!", Toast.LENGTH_LONG);
    }
    
    @Override
    public void onUserUnmuted(UserUnmutedEvent userUnmutedEvent) {
        Toast.makeText(getApplicationContext(), userMutedEvent.getIdentity() + " unmuted himself!", Toast.LENGTH_LONG);
    }
    
    @Override
    public void onUserLeft(UserLeftEvent userLeftEvent) {
        Toast.makeText(getApplicationContext(), userMutedEvent.getIdentity() + " left the conference!", Toast.LENGTH_LONG);
    }
    
    @Override
    public void onError(ErrorEvent errorEvent) {
        Toast.makeText(getApplicationContext(), "Conference error!", Toast.LENGTH_LONG);
    }
};

conference.setEventListener(conferenceEventListener);

To get the current event listener, use the getEventListener method:

ConferenceEventListener conferenceEventListener = conference.getEventListener();

Leaving the conference can be done via the leave method at the conference. On the side of the other participants, the UserLeftEvent event will be fired upon leave completion.

conference.leave();

During the conference call, you can also mute (and unmute) your audio, by calling the mute(shouldMute) method in the following way:

conference.mute(true);

On the side of the other participants, the UserMutedEvent or UserUnmutedEvent event will be fired.

To check if the audio is muted, call the muted() method in the following way:

boolean audioMuted = conference.muted();

During the conference call, you can play audio on the speakerphone, by calling the speakerphone(enabled) method in the following way:

conference.speakerphone(true);

To check if audio is on the speakerphone, call the speakerphone() method in the following way:

boolean speakerphone = conference.speakerphone();

Supported API Levels

The SDK supports Android API Level 21 (Lollipop) and higher.

Java Compatibility

The SDK source and target compatibility is set to Java 8. Reference the following snippet:

android {
    compileOptions {
        sourceCompatibility 1.8
        targetCompatibility 1.8
    }
}