Introduction

In this tutorial, you will learn how to build an Android app with Video Calling features, using Kotlin as the primary programming language.Throughout this guide, we have used Android Studio as the development environment and MirrorFly SDKs for adding the video call features.

Without any further ado, let’s get started!

MirrorFly Video Calling Features - An Overview

A video call on an Android app is one of the most reliable and easy-to-access communication features in recent years. Mobiles and web-apps have evolved with a rapid shift-over from audio to face-to-face virtual interactions with new age demands for technological advancements in communication. So here we talk about building in-app video calling feature within your Android app using MirrorFly’s APIs and SDKs

Pre-requisite for building a Video Chat App for Android:

To prepare for the video app building, it is important to check on the list of basic essentials required for the development process.

  • Android API Level 21 or above
  • Kotlin Support

With the checklist ticked, Gear up, Let’s build something exciting!

I. Create a MirrorFly Account

The first step in creating a reliable Video calling feature within your app is to sign-up for a MirrorFly account. This lets you access every essential feature needed to build a powerful video communication.

Let’s get started with the steps:

Step 1 : Sign up for a Free MirrorFly Account

Step 2 : Create an account with your basic details that include your name, organization details, work email and contact number.

#

You’re in!

You will now be able to access your MirrorFly account to download the Android SDKs necessary to build the video features. Proceed with the following steps to get ahead.

Step 3 : On the top of your account, you will be able to find the Application info under which you can copy the License Key

#
  • As you scroll down, you will see a list of SDKs available for download
#

Step 4 : Choose the Android SDK by clicking ‘Download’. This will take you to our docs page with the download link for our SDK along with guided instructions to start the implementation.

#

Step 5 : Once the SDK has been downloaded, extract the files from the ZIP folder.

Now that you have created the MirrorFly account and have the SDK along with the License Key, it’s time you create a new project to create a video chat app.

II . Create a New Project

In this part of the development process, you will carry out the installation and setup of the Video Call SDKs.

Installation

Let’s start the installation process by creating a new project with the following steps:

Step 1 : Create a new project.

Step 2 : Add the below mentioned libraries in app/libs folder within the project


                                 appbase.aar
                                 flycommons.aar
                                 flynetwork.aar
                                 flydatabase.aar
                                 videocompression.aar
                                 xmpp.aar
                                 Flywebrtc.aar 
                                
#

Step 3 : Add the below code in the app/build.gradle file


                            plugins {
                                ...
                                id 'kotlin-android'
                                id 'kotlin-kapt'
                                 }

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

                                        kotlinOptions {
                                            jvmTarget = '1.8'
                                             }

                                            packagingOptions {
                                                exclude 'META-INF/AL2.0'
                                                 exclude 'META-INF/DEPENDENCIES'
                                                exclude 'META-INF/LICENSE'
                                                  exclude 'META-INF/LICENSE.txt'
                                                exclude 'META-INF/license.txt'
                                                 exclude 'META-INF/NOTICE'
                                                 exclude 'META-INF/NOTICE.txt'
                                                 exclude 'META-INF/notice.txt'
                                                  exclude 'META-INF/ASL2.0'
                                                 exclude 'META-INF/LGPL2.1'
                                                exclude("META-INF/*.kotlin_module")
                                                  } 
                                                 }
                                

Step 4 : In the app/build.gradle file, add the following dependencies


                                   dependencies { 
                                               ... // your app dependencies 
                                             implementation files('libs/appbase.aar')
                                             implementation files('libs/flycommons.aar')
                                             implementation files('libs/flynetwork.aar')
                                             implementation files('libs/flydatabase.aar')
                                             implementation files('libs/videocompression.aar')
                                             implementation files('libs/xmpp.aar')
                                             implementation files('libs/flywebrtc.aar') 
                                     }
                                    
#

Step 5 : Next, you will continue adding the dependencies required by the app/build.gradle

                             
                              dependencies {
                                 ... // your app dependencies
                                 configurations {
                                      all {
                                          exclude group: 'org.json', module: 'json'
                                          exclude group: 'xpp3', module: 'xpp3'
                                         }
                                        }
                                         //For lifecycle listener
                                         implementation 'android.arch.lifecycle:extensions:1.1.1'
                                         annotationProcessor 'android.arch.lifecycle:compiler:1.1.1'
                                         //For GreenDao
                                         implementation 'de.greenrobot:greendao:2.1.0'
                                         //For gson parsing
                                         implementation 'com.google.code.gson:gson:2.8.1'
                                         //for smack implementation
                                         implementation 'org.igniterealtime.smack:smack-android:4.4.4'
                                         implementation 'org.igniterealtime.smack:smack-tcp:4.4.4'
                                         implementation 'org.igniterealtime.smack:smack-im:4.4.4'
                                         implementation 'org.igniterealtime.smack:smack-extensions:4.4.4'
                                         implementation 'org.igniterealtime.smack:smack-sasl-provided:4.4.4'
                                         implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
                                         implementation 'androidx.multidex:multidex:2.0.1'
                                         implementation 'com.google.android.gms:play-services-location:17.0.0'
                                         //Dagger Dependencies
                                          api 'com.google.dagger:dagger:2.40.5'
                                          kapt 'com.google.dagger:dagger-compiler:2.40.5'
                                          api 'com.google.dagger:dagger-android:2.40.5'
                                          api 'com.google.dagger:dagger-android-support:2.40.5'
                                          kapt 'com.google.dagger:dagger-android-processor:2.40.5'
                                          //coroutines
                                         implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
                                         implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.3'
                                         //apicalls
                                         implementation 'com.squareup.retrofit2:retrofit:2.6.1'
                                         implementation 'com.squareup.retrofit2:converter-gson:2.6.1'
                                          implementation 'com.squareup.okhttp3:okhttp:4.2.0'
                                          implementation 'com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2'
                                          //stetho interceptor
                                          implementation 'com.facebook.stetho:stetho-okhttp3:1.3.1'
                                         //okhttp interceptor
                                          implementation 'com.squareup.okhttp3:logging-interceptor:3.14.3'
                                          //shared preference encryption
                                          implementation 'androidx.security:security-crypto:1.1.0-alpha03'
                                          //Socket - versions.gradle
                                          implementation 'com.github.nkzawa:socket.io-client:0.6.0'                                    
                                         //Google - versions.gradle
                                         implementation 'org.webrtc:google-webrtc:1.0.32006'
                                         implementation 'androidx.core:core-ktx:+'
                                         implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.4.31'
                                         implementation 'androidx.media:media:1.0.0'
                                          //room database
                                          implementation 'androidx.room:room-runtime:2.2.5'
                                          kapt 'androidx.room:room-compiler:2.2.5'
                                          implementation "androidx.room:room-ktx:2.2.5"
                                         // Lifecycle
                                         implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
                                         kapt 'androidx.lifecycle:lifecycle-compiler:2.2.0' 
                                           }
                                

Step 6 : In order to avoid imported library conflicts, add the following code into the gradle properties file


                                android.enableJetifier=true
                                

Step 7 : Add the below permissions to AndroidManifest.xml


                                                <uses-permission android:name="android.permission.INTERNET" /	>
                                                <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
                                                <uses-permission android:name="android.permission.RECORD_AUDIO" />
                                                <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
                                                <uses-permission android:name="android.permission.CAMERA" />
                                                <uses-permission android:name="android.permission.READ_PHONE_STATE" />
                                                <uses-permission android:name="android.permission.WAKE_LOCK" />
                                        

Configuration of app/build.gradle file


                                        buildTypes {
                                             debug {
                                                buildConfigField 'String', 'SDK_BASE_URL', '"https://api-preprod-sandbox.mirrorfly.com/api/v1/"'
                                                buildConfigField 'String', 'LICENSE', '"xxxxxxxxxxxxxxxxxxxxxxxxx"'
                                                buildConfigField 'String', 'WEB_CHAT_LOGIN', '"https://webchat-preprod-sandbox.mirrorfly.com/"'
                                                buildConfigField "String", "SUPPORT_MAIL", '"contussupport@gmail.com"'
                                                  }
                                                }
                                         

Data Initialization

In your Application class, inside the onCreate() method, include the following ChatSDK.Builder() class. This will allow you to add the essential data needed for the initialization process.

   
                                                 //For chat logging
                                                 LogMessage.enableDebugLogging(BuildConfig.DEBUG) 
                                                  ChatSDK.Builder()
                                                     .setDomainBaseUrl(BuildConfig.SDK_BASE_URL)
                                                     .setLicenseKey(BuildConfig.LICENSE)
                                                         .setIsTrialLicenceKey(true)
                                                         .build()
                                         
#

User Registration

Based on the setIsTrialLicenceKey provided, register a user in the sandbox Live mode

   
                                         FlyCore.registerUser(USER_IDENTIFIER) { isSuccess, throwable, data ->
                                            if(isSuccess) {
                                                 val responseObject = data.get("data") as JSONObject
                                                 // Get Username and password from the object
                                                 } else {
                                                    // Register user failed print throwable to find the exception details.
                                                    }       
                                                     }
                                        

Establishing Connection to the Chat Server

The Chat SDKs must be connected to the Server in order to enable sending and receiving messages.

   
                                                     ChatManager.connect(object : ChatConnectionListener {
                                                          override fun onConnected() {
                                                              // Write your success logic here to navigate Profile Page or
                                                               // To Start your one-one chat with your friends
                                                               }
                                                               override fun onDisconnected() {
                                                                     // Connection disconnected
                                                                      //No need implementations
                                                                  }
                                                                  override fun onConnectionNotAuthorized() {
                                                                        // Connection Not authorized
                                                                       //No need implementations
                                                                        }
                                                                       })
                                                    

SDK Initialization

Add the following code in the onCreate() method of your Application class

   
                                          @Override
                                           public void onCreate() {
                                               super.onCreate();
                                              //set your call activity
                                              CallManager.setCallActivityClass(CALL_UI_ACTIVITY::class.java)
                                              CallManager.setMissedCallListener(object : MissedCallListener {
                                                  override fun onMissedCall(isOneToOneCall: Boolean, userJid: String, groupId: String?,    callType: String, userList: ArrayList?) {
                                                       //show missed call notification
                                                    }
                                                     })                                                    
                                                    CallManager.setCallHelper(object : CallHelper {
                                                        override fun getDisplayName(jid: String): String {
                                                             return ContactManager.getDisplayName(jid)
                                                            }
                                                             override fun getNotificationContent(callDirection: String): String {
                                                                    return CallNotificationHelper.getNotificationMessage()
                                                                   }
                                                                override fun isDeletedUser(jid: String): Boolean {
                                                                         return ContactManager.getProfileDetails(jid)?.contactType == ContactType.DELETED_CONTACT
                                                                     }
                                                                     override fun sendCallMessage(details: GroupCallDetails, users: List, invitedUsers: List) {
                                                                          CallMessenger.sendCallMessage(details, users, invitedUsers)
                                                                        }
                                                                        })
                                                    
                                                    

Call Activity Setup

In your Manifest, add the belor Call UI Activity

  
                                                                         <activity
                                                                        android:name="YOUR_CALL_ACTIVITY"
                                                                        android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation"
                                                                        android:excludeFromRecents="true"
                                                                        android:launchMode="singleTask"
                                                                        android:resizeableActivity="false"
                                                                        android:screenOrientation="portrait"
                                                                        android:supportsPictureInPicture="true"
                                                                        android:showOnLockScreen="true"
                                                                        android:turnScreenOn="true"
                                                                        android:taskAffinity="call.video"
                                                                        tools:targetApi="o_mr1" />
                                                                        

To configure the call activity, call the below method

  
                                                                        CallManager.configureCallActivity()
                                                                        

To notify the call SDK to remove the ongoing call notification call the below method on onStart()

  
                                                                        CallManager.bindCallService()
                                                                        

To notify the call SDK to show the ongoing call notification call the below method on onStop()

  
                                                                        CallManager.bindCallService()
                                                                        

III. Implementation Of Video Calling

Making a call

To make a video call, it is necessary to ensure that both the audio and video permissions are granted.

The code below is for audio permissions


                   Manifest.permission.RECORD_AUDIO
                   Manifest.permission.READ_PHONE_STATE 
              

Use the code below to make one-to-one calling


               CallManager.makeVideoCall("TO_JID", object : CallActionListener{
                  override fun onResponse(isSuccess: Boolean, message: String) {
                      }
                     })
                

Receive an Incoming Video Call

When a user receives a video call from another user, the Call SDK quickly checks on the Android Version and notifies it. Else, the Call SDK initialises the task you’ve set using the CallManager.setCallActivityClass() method.

Answer an Incoming Video Call

When the user presses the ‘Accept’ button, the call must be answered and notified to the caller. Without the grant of permission, the SDK must decline the call automatically. This can be performed by the below SDK method.

Request Parameters:

Argument Type Description
CALLBACK CallActionListener callback to observe the action status

                            CallManager.answerCall(object : CallActionListener {
                             override fun onResponse(isSuccess: Boolean, message: String) {
                                 }
                                 })
                                 })
                            

Decline a Video Call

Inorder to decline an incoming call, the user presses the decline button. During this situation, the following method is called


                                 CallManager.declineCall()
                                

Disconnect an Ongoing Call

When a user disconnects from an ongoing call by pressing on the disconnect button, the call connection is no longer active. To perform this action, the following method is called.


                                 CallManager.disconnectCall()
                                

Now that we have implemented a Video Calling App, it is necessary to add the essential features for your users.

Conclusion

That's a wrap! You’ve come all way along here, understanding the steps to build an iOS app with video calling enabled in it. To give a quick recap, we downloaded the MirrorFly SDKs, acquired the trial license key, integrated the SDKs into your iOS app and connected it to the server. Finally, we’ve created a simple iOS video call app that can make or receive virtual calls to other MirrorFly SDK users.

Like to extend video call features in your app? Discover our full-length code at MirrorFly’s Github Repository to add more interactive features to your app. Happy developing!

mirrorfly

Looking To Build a Kotlin Video Chat App?

Drive 1 billion + conversations on any Android, iOS, or Web app with 500+ chat features & 100+ UI components.

  • Topic-based Chat
  • Upload Large Files
  • Multi-tenancy support
  • Lite Chat App
  • Hire Dedicated Team
mirrorfly support team
Integrate Our Chat SDK In Just 10 Mins!

Start adding our messaging APis & SDK to any app right away!

Get Started

Need SDK integration support? Hire our developers!

mirrorfly sales team
Get Started With Our Self-hosted Chat Solution Today!

Get Full Access To Our Customizable Video, Voice & Chat SDKs!

Request Demo

Let us build your chat app. Hire dedicated team!

Request Demo