How to Use WebRTC Android SDK to share peer to peer Live data in Android?

Abhishek Meharia
4 min readApr 11, 2020

--

You can use WebRTC SDK in Android Environment with the help of Gradle dependency management.

WebRTC (AppRTC so-called in native environments) SDK provides peer to peer communication across devices (without using any third-party servers). This document describes how to use the SDK in android and how you can send data across devices in realtime.

WebRTC for Android

How WebRTC works?

WebRTC has many moving parts in it. If you look below the hood, there’s a lot going on in there.

I am going to explain the working of WebRTC very briefly if you want to know the working in detail just go through this article.

Suppose UserA app wants to connect with UserB app,

  1. UserA app will create an offer and generate a SessionDescription Object also called SDP which contains information about the network and its working environment.
  2. Now we(App developer) have to deliver this info SessionDescription Object to UserB app (Firebase realtime database can be used or any third party servers can be used).
  3. After receiving the SDP Offer from UserA, UserB will accept the offer and generate its own SessionDescription Object (UserB gives the answer to UserA offer).
  4. SDP Object generated by UserB is delivered to UserA where UserA will accept UserB answer.
  5. Next, UserA and UserB will generate their own ICE Candidates which contains the information about the networks to connect to.
  6. We have to deliver the ICE Candidates generated by UserA to UserB and vice versa.

Prerequisites

First, open your module-level build.gradle file and add the following Gradle dependency.

implementation 'org.webrtc:google-webrtc:1.0.22672'

Next, in the same file add below lines under Android heading

Android { 
...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
}
}

Here is the code snippet of my build.gradle file

build.gradle file

Don’t forget to add internet permission in the Manifest file.

<uses-permission android:name="android.permission.INTERNET" />

Add Observers

First, create a java class with the name CustomDataChannelObserver.java and copy-paste the below code.

Next, create a java class CustomPeerConnectionObserver.java and copy-paste the below code.

Next, create one more class with the name CustomSdpObserver.java and copy-paste the below code.

You can also add Log messages in each of the functions above for debugging purposes. Above Observers will listen to connectivity changes and you can use them to check the connection state.

Initialization

First, create one method with the name initialize() in your activity class and copy-paste the below code.

PeerConnectionFactory.InitializationOptions initializationOptions =                PeerConnectionFactory.InitializationOptions.builder(context)                        .createInitializationOptions();        PeerConnectionFactory.initialize(initializationOptions);        PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();    

peerConnectionFactory = PeerConnectionFactory.builder().setOptions(options) .createPeerConnectionFactory();
List<PeerConnection.IceServer> iceServers = new ArrayList<>(); iceServers.add(PeerConnection.IceServer.builder("stun:stun2.1.google.com:19302").createIceServer()); iceServers.add(PeerConnection.IceServer.builder("turn:numb.viagenie.ca").setUsername("webrtc@live.com") .setPassword("muazkh").createIceServer()); PeerConnection.RTCConfiguration rtcConfig = new PeerConnection.RTCConfiguration(iceServers);

In the above code, we initialize PeerConnectionFactory class.

Now from PeerConnectionFactory class, we will initialize PeerConnection object.

In the above code, we used CustomPeerConnectionObserver.java class and overrides three methods.

  • onIceCandidate: This function will be called whenever WebRTC will generate Ice Candidates and we need to share the IceCandidate with another user. Now you must be wondering about how to send this custom object over the network. IceCandidate consist of three different values:
iceCandidate.sdp; // string value (which you can share over network)iceCandidate.sdpMid; // String value (which is shareable)iceCandidate.sdpMLineIndex; //Integer value(which is also shareable)

On the other side, IceCandidate sent by another app needs to be added and the below code can be used to add it.

public void setIceCandidate(String candidate, String sdpmid, int sdpmlineIndex){                peerConnection.addIceCandidate(new IceCandidate(sdpmid, sdpmlineIndex, candidate));  }
  • onDataChannel: This function will be called when another peer will create a data channel. After the data channel is created, we can send string data by using the below code.
ByteBuffer buffer = ByteBuffer.wrap(message.getBytes()); // message is string 
dataChannel.send(new DataChannel.Buffer(buffer, false));
  • onIceConnectionChange: This function will be called whenever the connection state is changed. It can be used to check the status of peer to peer connection.
if(iceConnectionState==PeerConnection.IceConnectionState.CONNECTED){  // when connection is established
}
if(iceConnectionState == PeerConnection.IceConnectionState.CLOSED || iceConnectionState == PeerConnection.IceConnectionState.FAILED){
// when connection is failed or closed
}

Next, to create a data channel add the below code in the initialize method.

onMessage function will be called when any data is sent by another peer. CustomDataChannelObserver.java class is used which we have already declared.

Complete initialize() function

Create Offer

After initialize() function is called, the createOffer() method will be called to create an offer and the below code can be used to create an offer.

After the offer is created, we need to set sessionDescription object as localDescription and sessionDescription.description (which is a string) needs to be shared by another peer over the network.

On the other side, another peer has to add sessionDescription.description (which is a string) as remoteDescription like the below code.

peerConnection.setRemoteDescription(new CustomSdpObserver(), new SessionDescription(SessionDescription.Type.OFFER, sessionDescription)); // sessionDescription is the same string sent over the network

Generate Answer

After the offer is accepted by another peer and added as remoteDescription, the answer is generated by another peer and share it with the first peer like the below code.

After the answer is created, we need to set sessionDescription object as localDescription and sessionDescription.description (which is a string) needs to be shared by another peer over the network.

On the other side, another peer has to add sessionDescription.description (which is a string) as remoteDescription like the below code.

peerConnection.setRemoteDescription(new CustomSdpObserver(), new SessionDescription(SessionDescription.Type.ANSWER, sessionDescription)); // sessionDescription is the same string sent over the network

Close

The below code can be used to close the data channel and close the peer to peer connection.

Complete code

Here is the complete code used above:

Summary

You will be informed by the onIceConnectionChange method about any change in the connection(whether connected or closed). When the status is CONNECTED, it means that connection is established and you can send data using the data channel and when the status is FAILURE or CLOSED, it means the network is disconnected and you can’t send any more data. Furthermore, you can use Observer functions declared above to know more about the status and states of the connection.

--

--