1-to-1 Video Chat App on Android Using the Agora 4.x SDK Preview
Tags: agora, android, videocalling
Published: 2021-09-17 21:40:59

>  In this post, we’ll build a basic video chat app in 10 easy steps, using the Agora Video 4.0 SDK Preview for Android.

## Prerequisites

* Android Studio 
([https://developer.android.com/studio](https://developer.android.com/studio/))

* Basic knowledge of Java and the Android SDK
([https://developer.android.com/training/basics/firstapp](https://developer.android.com/training/basics/firstapp/))

* Agora.io developer account
(see: [How To Get Started with Agora](https://www.agora.io/en/blog/how-to-get-started-with-agora?utm_source=medium&utm_medium=blog&utm_campaign=de_content))

## Step 1: Getting your App ID

Once you finish the sign-up process, you are redirected to the Agora Console. Open the Projects tab in the left-hand nav to see your default project’s App ID.

## Step2: JCenter Integration

Add the following line in your project level **/app/build.gradle**:

    allprojects {
        repositories {    ...**
            ***// Jit pack
            *maven { url ‘[https://www.jitpack.io'](https://www.jitpack.io%27/) }
        }
    }

    

Add the following line in the **/app/build.gradle** file of your project:

    dependencies {
        ...**
        ***//Agora RTC 4.0 SDK for video call
        *implementation "com.github.agorabuilder:agora-full-preview:4.0.0"**
    **}

![build.gradle (module level)](https://cdn-images-1.medium.com/max/7160/1*PJam2lIiXtuKOsHLmHxyFA.png)

## Step 3: Setting up the Agora App ID

Now it’s time to add your Agora App ID (*see Step 1*) to the Android project’s *Strings.xml (app/src/main/res/values/Strings.xml)*.

    <resources>
        <string name="app_name">Agora-Android-Video-Tutorial</string>
        <string name="agora_app_id">#ADD YOUR APP ID HERE#</string>
    </resources>

![](https://cdn-images-1.medium.com/max/7156/1*-ejxNsfAXB8K9P8eY01YfA.png)
>  *Note: This guide does not implement token authentication which is recommended for all RTE apps running in production environments.*
>  *For more information about token based authentication within the Agora platform please refer to this guide: [https://bit.ly/3sNiFRs](https://bit.ly/3sNiFRs)*

The next step is to add the appropriate permissions within *Manifest.xml*

 {% gist https://gist.github.com/Meherdeep/4b2bb75e56ba41c544a1c213223a5c85 %}

The final step is to prevent obfuscation of the Agora classes. This might sound complex, but it’s really very simple. In the proguard-rules.pro file, add a
-keep class configuration for the Agora SDK.

    -keep class io.agora.**{*;}

![](https://cdn-images-1.medium.com/max/4000/0*zwYDfTMOj0DZAnxY.png)

This prevents obfuscation of the Agora SDK public class names.
>  Note: **Ensure that the Android NDK plug-in is installed and set up for this project.

## Step 4: Setting Up Views

Now that we have the Agora SDK integrated, let’s set up our UI. I will breeze through this portion since we are using standard UI elements.

![](https://cdn-images-1.medium.com/max/4000/0*tpaT4r7AkkHTfohI.png)

In the example, I chose to use ImageView instead of Button for the various UI elements. Either works. The important part is to note that there are functions that we link to using the onClick property.

## Step 5: Checking Permissions

I know what you must be thinking: “Didn’t we already set up the permissions?” Earlier, we let the application’s Manifest know which permissions our app plans to use, but we still have to explicitly request the user to grant these permissions. Don’t worry — this is the final step in getting the boilerplate project running, and it’s painless.

First, let’s declare which permissions we want to request:

    // Permissions
    private static final int *PERMISSION_REQ_ID *= 22;
    private static final String[] *REQUESTED_PERMISSIONS *= {Manifest.permission.*RECORD_AUDIO*, Manifest.permission.*CAMERA*};

Next, we set up a couple of functions to help us. First, we have a method that requests permissions for a given permission string and code.

 {% gist https://gist.github.com/Meherdeep/36791987b9f24dfa8cc7c3755130ec46 %}

Next, we have a callback method that gets called after the user has responded to the permissions request prompt.

 {% gist https://gist.github.com/Meherdeep/fd20a74b48ba8817dd2ae240ca856bc0 %}

Last, in our class’s onCreate we check if our permissions were granted. If they were not, the above methods handle the requests

 {% gist https://gist.github.com/Meherdeep/76502773087d0466773abd4650a99941 %}

## Step 6: Initializing the Agora SDK

Now that we have our view, we are ready to initialize the Agora SDK, set up the user profile, and set the video quality settings.

In the previous step, you may have noticed a couple of places that I call initAgoraEngine(). Before we can dive into the initialization, we need to make sure that our activity has access to an instance of the Agora *RtcEngine*.

![](https://cdn-images-1.medium.com/max/4000/0*z6OxbliF9_VlgKml.png)

In our MainActivity class, we need to declare a class property to store our instance of *RtcEngine:*

    private RtcEngine mRtcEngine;

Now it’s time to initialize. After all the boilerplate setup, we are finally at the step where we can start playing with the Agora engine!

Go ahead and declare your initAgoraEngine() method in your class. In this function, we will create a new instance of the RtcEngine using the baseContext, the Agora App ID (declared above), and an instance of the RtcEngineEventHandler (we’ll get into this a little later).

 {% gist https://gist.github.com/Meherdeep/e9fa5309774e9936f7e6f45e2a6b4b35 %}

Once we have our new instance, it’s time to set up our user’s session. Here we can set the Channel Profile to Communication, since this is a video chat and not a broadcasting application. This is also where we configure our video encoder settings.

 {% gist https://gist.github.com/Meherdeep/2a06a39e0be4fed00697eab9eccd124a %}

>  Note: At this phase of the build, we can use the emulator to test our work, but I am choosing to use a mobile device.

## Step 7: Connecting the Video Streams

Before we can join a call we need to be able to present the local video stream to the user via the UI elements we set up earlier ([step 4](https://medium.com/#366e)). For reference, below is the UI element’s ID that our local video will render into:

    android:id="@+id/floating_video_container"

 {% gist https://gist.github.com/Meherdeep/70429999a6be23ce10f9f53450ed9d54 %}

In the first line, we declare a [*SurfaceView](https://developer.android.com/reference/android/view/SurfaceView) that renders the stream from the camera. *The second step is to set up the layout and link it with our local or remote video container. We then add a view to our container where we add our SurfaceView. This lets us play the camera feed in that particular container. Last, we pass the localView or remoteView, which is the object of our SurfaceView, to the engine as part of a VideoCanvas object. We leave the *uid* parameter blank so that the SDK can handle creating a dynamic ID for each user.

Now, that we have our local video feed set up, we need to use a similar function to connect our remote video stream.

The main difference between the remote video and the local video is the user ID parameter that gets passed to the engine as part of the VideoCanvas object. The last line sets the fallback option: If the video degrades, the engine reverts to a low-quality video stream.

 {% gist https://gist.github.com/Meherdeep/3d56ae40ae86eb24e0f51e6d9435daea %}

## Step 8: Setting Up the SDK Event Handler

Earlier, I made a reference to the *RtcEngineEventHandler*, and now it’s time to declare it as a property of our MainActivity class. The engine will call these methods from the *RtcEngineEventHandler*.

 {% gist https://gist.github.com/Meherdeep/8b3ccd3ce70abcdecf8ef7571d4f65aa %}

Each event triggers some fairly straightforward functions, including one we wrote in the previous step. In the interest of brevity, I provide the code below, but I don’t give an in-depth breakdown.

 {% gist https://gist.github.com/digitallysavvy/2383f1e40294141ba1b7e163327eac9d %}

Feel free to leave a comment if anything is unclear.

## Step 9: Joining and Leaving Channels

I know what you’re thinking, step *9* ?! Don’t sweat it — the next two steps are very simple. Let’s start by joining a call.
>  Note: if you do not specify the uid when joining the channel, the engine will assign one

 {% gist https://gist.github.com/Meherdeep/65543166748dc82a0d9b6a66bc0882ea %}

As you can see from the first line, the Agora SDK makes it simple. The engine calls joinChannel, passing in the channel name followed by the call to set up our local video stream ([Step 7](https://medium.com/#aabb)).
>  Note: With the 4.0 SDK you need to add the StartPreview() method after setting up your local video in order to start your camera feed.

Note: The remove video method is the same used in step 8

 {% gist https://gist.github.com/Meherdeep/c9723d9b071c474670857fa7f2a5a22c %}

Leaving the channel is even simpler: The engine calls leaveChannel. Above, you’ll notice there are a few lines to remove the video stream subviews from each UI element.
>  Note: It is also important to use the stopPreview() method before leaving the channel in order to stop the camera feed.

## Step 10: Adding Other Functionality

The last remaining parts are related to connecting the UI elements for toggling the microphone and video streams on the local device. Let’s start with the audio toggle.

 {% gist https://gist.github.com/digitallysavvy/98b25603541e93a23777d65f4eeb5a77 %}

First, we get the reference to our button and then check if it has been toggled on or off using isSelected(). Once we have updated the UI element state, we pass the button’s updated state to the RtcEngine.

Moving on to the video toggle:

 {% gist https://gist.github.com/digitallysavvy/a40bb0380935876caa0207b77efa1d24 %}

As with the audio toggle, we check or update the button’s state using isSelected() and then pass that to the RtcEngine. To give a better visual representation of the video being muted, we hide or show the videoSurface.

![](https://cdn-images-1.medium.com/max/2000/0*AG_uZxifv_enHINQ)

I hope you enjoyed reading along and working together on creating a 1-to-1 video chat Android app using the Agora 4.0 SDK.

Full source code: *[*https://github.com/digitallysavvy/android-video-chat-demo/tree/ngsdk-update](https://github.com/digitallysavvy/android-video-chat-demo/tree/ngsdk-update)

If you have any questions or comments, I invite you to [join the Agora Developer Slack](https://www.agora.io/en/join-slack/) community.