Introduction

This tutorial will walk you through the complete process of integrating MirrorFly’s SDKs into Android video chat apps using Kotlin

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

So yes, that's how you build a video app with MirrorFly! We hope that this guide has covered the complete process of video app development right from the start of the project to the deployment with features.

As a closure - Building a Video requires immense efforts and the right support. We take care of the latter by providing interesting video calling features for your app that you can try with ease with a clear guidance. Explore more with us!

Looking To Build a Kotlin Video Chat App?

Build a Video Chat experience by integrating real-time video, chat and voice features into any iOS, Android and Web App.

  • Average API response 3s
  • 100ms worldwide latency
  • 1 Billion+ concurrent users
Try for free
#
Start your 21-Day Free Trial today

Create immersive chat, video & voice calling experiences that skyrocket engagement and increase your app stickiness with our APIs & SDKs.

  • Dedicated Cloud Server
  • API Response 3 Seconds
  • 99.999% Uptime SLA
Try it free *No Credit Card Required Contact Sales