Tech Talks

How to Build a 1-to-1 Video Chat App with Java or Kotlin

Published On September 5th, 2022 Tech Talks

In this article, you will learn about the basic steps in building a 1-to-1 video chat app on android using two programming languages – Java and Kotlin.

Throughout this article, I will explain the process of creating an app in the Android Studio IDE using Video Chat SDKs downloaded from MirrorFly.

Note: Java and Koltin are both well-suited for building Android apps. You may choose any one of these languages for your app development process, depending on your requirements.

What You’ll Need:

  • Android Lollipop 5.0 (API Level 21) or above
  • Java 7 or higher
  • Gradle 4.1.0 or higher

1. Create Your Android App Project 

To create an Android App, you’ll need the latest version of Android Studio IDE.

  • Download it from the Official Website of Android Studio
  • Install and Launch the IDE. A Welcome Window will appear
  • In this Window, select ‘Start a new Android Studio project’
  • Next, choose ‘Empty Activity’ from the list of templates
low latency
  • On choosing Empty Activity, the configuration window will open. 
  • Assign an App Name for your project
  • Now, you will have to choose the programming language to build your own 1-to-1 video chat app. You may choose Java or Kotlin as per your preference.
  • You’ll have to choose the minimum SDK level as Android Lollipop 5.0 (API Level 21) or above.
  • Leave the other fields to hold the default values.
  • Click on Next. Your App’s main menu will appear.
 
Looking to Experience Our HD Video Call Features?

2. Download Your Video Chat SDKs

Now that you’ve prepared the app, you’ll need the video chat functionality for integration. So let’s get ahead to download the Video Chat SDK from MirrorFly’s website. To do this, you need to create an account with MirrorFly.

  • Fill in all the required details in the Registration Page. You account will get created.
  • Verify you account using the official email address

In your Account dashboard,

  • Download the Android SDK from the ‘Application Info’ section
  • Make a note of your License key, which is essential to authenticate the chat SDK with the server.

On your device,

  • Locate the downloaded SDK folder.
  • Extract the AAR files.
appbase.aar
flycommons.aar
flynetwork.aar
flydatabase.aar
videocompression.aar
xmpp.aar

These files are the dependencies that will create the library folders of your project. These folders will sort the components of your app in an orderly manner.

3. Import the Dependencies into your Project

Now, let’s import these files into your app project

  • Navigate to Gradle Scripts > build.gradle
  • Here you will find a gradle file for the project and another for the app.
  • Import the dependency files into the app gradle folder app/build.gradle

The imported dependencies will appear in the form of  libraries as follows:

  • Next, inside the android {} tag, add the following lines:
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")
}
}
  • Next, add the configurations within the 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')

 }

4. Add the App Modules

Stepping ahead, we will add the various modules inside the dependency tag{} with the configurations mentioned below:

 dependencies {

 ... // your app dependencies

 configurations {
     all {
         exclude group: 'org.json', module: 'json'
         exclude group: 'xpp3', module: 'xpp3'
     }
 }

Continue adding the upcoming modules within the same tag.

  • Lifecycle Listener

This module has all the necessary information related to the app. It tracks and monitors the activities happening within the app.

        implementation 
  'android.arch.lifecycle:extensions:1.1.1'
        annotationProcessor 
  'android.arch.lifecycle:compiler:1.1.1'
  • GreenDao

This component is object-relational. It maps the app objects to SQLite databases

 implementation 'de.greenrobot:greendao:2.1.0'
  • gson parsing

You may use this process to convert the Java objects into respective JSON reps

   implementation 'com.google.code.gson:gson:2.8.1'
  • Smack Implementation

This module is an XMPP client library used for easy transfer of data

  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

These dependencies are modules that are used to mimic the programming codes during compile time.

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

These codes are used to make a block of codes concurrently within a project to keep the program running consistently

   implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.3'
  • API Calls
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

This interceptor is used to detect any issues with the network and send the data using HTTP websockets.

 implementation 
'com.facebook.stetho:stetho-okhttp3:1.3.1'
  • OkHttp Interceptor

When APIs are used, this module continuously tracks, rewrites and retries the call

        implementation
 'com.squareup.okhttp3:logging-interceptor:3.14.3'
  • Shared Preference Encryption

These objects contain small key-value pairs that encrypts the data and sets the privacy preferences as shared or private.

        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'
  • Close the dependency tag. 
  • Next, add the below code to gradle.properties file to prevent any conflicts among the library files imported from the SDK
android.enableJetifier=true
  • Resolve the WebRTC dependencies by adding the below line within the dependencyResolutionManagement{} tag
dependencyResolutionManagement {
 repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
 repositories {
 google()
 mavenCentral()
 jcenter()
 }
}

5. Provide Manifest Permissions

A manifest is used in a program to define each component of an app. These modules require specific permissions so that the library conflicts can be avoided among the dependency files.

Add the below permission:

<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" />

Now, Go to app > manifests > AndroidManifest.xml and update the network access permissions

6. Authenticate the Video Chat SDK

At the stage when you’ve got our app prepared for the SDK integration, you need to update the  License key details in the builder configuration of the project as follows:

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"'
  }
}

Once you’ve updated it, you need to perform the gradle sync operation.

How to Perform the gradle sync?

Locate the gradle sync as shown in the picture

Otherwise, Go to File > Sync Project with Gradle Files

Note: Restart Android studio after gradle sync to see the changes take effect.

7. Initialize Your Chat SDK

The builder class of the app is used to construct the object step by step. This simplifies the entire SDK initialization process. Let’s begin the steps by starting the SDK.

  • Go to the  Application Class
  • Call the onCreate() method

Note: Below, I will use the codes of both Kotlin and Java to build your own 1-to-1 video chat app. You may use the one as per your requirement.

To debug if the codes that contain heavy system logs and data, we’ll use the below code:

Java
//For chat logging
LogMessage.enableDebugLogging(BuildConfig.DEBUG);

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

8. Register an App User

Add a user in sandbox/ live mode using the following code:

Java
  FlyCore.registerUser(USER_IDENTIFIER, (isSuccess, throwable, data ) -> {
    if(isSuccess) {
        Boolean isNewUser = (Boolean) data.get("is_new_user");
        JSONObject responseObject = (JSONObject) data.get("data");
       // Get Username and password from the object
    } else {
       // Register user failed print throwable to find the exception details.
    }
   });
Kotlin
  FlyCore.registerUser(USER_IDENTIFIER) { isSuccess, throwable, data ->
    if(isSuccess) {
        val isNewUser = data["is_new_user"] as Boolean
        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.
    }   
 }

9. Connect Chat SDK to MirrorFly Server

The Chat SDK must be connected to the MirrorFly server so that your one on one video chat app can send and receive messages. The below code is used to achieve this:

Java
ChatManager.connect(new ChatConnectionListener() {
     @Override
     public void onConnected() {
         // Write your success logic here to navigate Profile Page or
         // To Start your one-one chat with your friends
     }

     @Override
     public void onDisconnected() {
        // Connection disconnected
        //No need implementations
     }

    @Override
     public void onConnectionNotAuthorized() {
        // Connection Not authorized
        //No need implementations
    }
});
Kotlin
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
   }
   })

10. Initialize Call SDK

Within the onCreate() method of your Application Class, add the below line:

Java
@Override
public void onCreate() {
super.onCreate();
//Initialize call manager
CallManager.init(this);
//set your call activity
CallManager.setCallActivityClass(CALL_UI_ACTIVITY.class);
CallManager.setMissedCallListener((isOneToOneCall, userJid, groupId, callType, userList) -> {
  //show missed call notification
});

CallManager.setCallHelper(new CallHelper() {
  @NonNull
  @Override
  public String getNotificationContent(@NonNull String callDirection) {
      return CallNotificationHelper.getNotificationMessage();
  }

  @Override
  public void sendCallMessage(@NotNull GroupCallDetails details, @NotNull List<String> users, @NotNull List<String> invitedUsers) {
      CallMessenger.sendCallMessage(details, users, invitedUsers);
  }
  });

CallManager.setCallNameHelper(new CallNameHelper() {
  @NonNull
  @Override
  public String getDisplayName(@NonNull String jid) {
      return ContactManager.getDisplayName(jid);
  }
  });
}
Kotlin
@Override
public void onCreate() {
super.onCreate();
//Initialize call manager
CallManager.init(this)
//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<String>) {
               //show missed call notification
           }
     })
     
CallManager.setCallHelper(object : CallHelper {
    override fun getNotificationContent(callDirection: String): String {
        return CallNotificationHelper.getNotificationMessage()
    }

    override fun sendCallMessage(details: GroupCallDetails, users: List<String>, invitedUsers: List<String>) {
        CallMessenger.sendCallMessage(details, users, invitedUsers)
    }
  })

CallManager.setCallNameHelper(object : CallNameHelper {
    override fun getDisplayName(jid: String): String {
      return ContactManager.getDisplayName(jid)
    }
  })

  }

11. Set Up Call Activity

In your manifest, define your UI call activity as follows:

 <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" />

Next, configure the call activity within the onCreate() method 

Java
CallManager.configureCallActivity(ACTIVITY);
Kotlin
CallManager.configureCallActivity(ACTIVITY)

To notify the Call SDK to remove the ongoing call notifications, you need to call the below method on the onStart() of your call activity 

Java
CallManager.bindCallService();
Kotlin
CallManager.bindCallService()

Similarly, to show the call notification, add the below line within the onStop() method of your call activity.

Java
CallManager.unbindCallService();
Kotlin
CallManager.unbindCallService()

Required Run-time Permissions

To make a one on one video call, you need to grant the below permissions:

Manifest.permission.RECORD_AUDIO
Manifest.permission.CAMERA
Manifest.permission.READ_PHONE_STATE

Check the permission using the below code:

Java
CallManager.isVideoCallPermissionsGranted();
Kotlin
CallManager.isVideoCallPermissionsGranted()

12. Make a Video call

To make a video call to another SDK user, you need to add the following code to your project:

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

13. Answer the Video Call

When a user presses the ‘Accept’ key on their device UI, the below method will notify the caller that the call has been answered. 

Java
  CallManager.answerCall((isSuccess, message) -> {
        
    });
Kotlin
   CallManager.answerCall(object : CallActionListener {
      override fun onResponse(isSuccess: Boolean, message: String) {
    
      }
  })

14. Decline an Incoming Call

When a user calls declines an incoming call from another SDK user, the caller will be notified that their call has been declined using the following method:

Java
  CallManager.declineCall();
Kotlin
  CallManager.declineCall()

15. Disconnect the Ongoing Video Call

When a user has to disconnect from an ongoing call with another SDK user, the latter will be notified about the disconnection using the following code:

Java

  CallManager.disconnectCall();

Kotlin

  CallManager.disconnectCall()

Conclusion

That’s great! You’ve come through all the steps of building a 1-to-1 video chat app.

To recap, we created an android app project in Android Studio, downloaded the Video Chat SDKs from MirrorFly and integrated them. After establishing a server connection, we added the codes to enable video calling functionalities to make one-to-one video chat, call answer, decline and disconnection. 

Aspiring to do more with your app? Explore the many possibilities of adding interesting chat features from MirrorFly.  Need more help? Click here to talk with our team.

Krushi Shivasangaran

Krushi is a Digital Marketer by choice & profession. She munches on topics relating to Technology, E-Commerce, Enterprise Mobility, Cloud Solutions and Internet of Things.

In this article, you will learn about the basic steps in building a 1-to-1 video chat app on android using two programming languages – Java and Kotlin.

Throughout this article, I will explain the process of creating an app in the Android Studio IDE using Video Chat SDKs downloaded from MirrorFly.

Note: Java and Koltin are both well-suited for building Android apps. You may choose any one of these languages for your app development process, depending on your requirements.

What You’ll Need:

  • Android Lollipop 5.0 (API Level 21) or above
  • Java 7 or higher
  • Gradle 4.1.0 or higher

1. Create Your Android App Project 

To create an Android App, you’ll need the latest version of Android Studio IDE.

  • Download it from the Official Website of Android Studio
  • Install and Launch the IDE. A Welcome Window will appear
  • In this Window, select ‘Start a new Android Studio project’
  • Next, choose ‘Empty Activity’ from the list of templates
low latency
  • On choosing Empty Activity, the configuration window will open. 
  • Assign an App Name for your project
  • Now, you will have to choose the programming language to build your own 1-to-1 video chat app. You may choose Java or Kotlin as per your preference.
  • You’ll have to choose the minimum SDK level as Android Lollipop 5.0 (API Level 21) or above.
  • Leave the other fields to hold the default values.
  • Click on Next. Your App’s main menu will appear.
 
Looking to Experience Our HD Video Call Features?

2. Download Your Video Chat SDKs

Now that you’ve prepared the app, you’ll need the video chat functionality for integration. So let’s get ahead to download the Video Chat SDK from MirrorFly’s website. To do this, you need to create an account with MirrorFly.

  • Fill in all the required details in the Registration Page. You account will get created.
  • Verify you account using the official email address

In your Account dashboard,

  • Download the Android SDK from the ‘Application Info’ section
  • Make a note of your License key, which is essential to authenticate the chat SDK with the server.

On your device,

  • Locate the downloaded SDK folder.
  • Extract the AAR files.
appbase.aar
flycommons.aar
flynetwork.aar
flydatabase.aar
videocompression.aar
xmpp.aar

These files are the dependencies that will create the library folders of your project. These folders will sort the components of your app in an orderly manner.

3. Import the Dependencies into your Project

Now, let’s import these files into your app project

  • Navigate to Gradle Scripts > build.gradle
  • Here you will find a gradle file for the project and another for the app.
  • Import the dependency files into the app gradle folder app/build.gradle

The imported dependencies will appear in the form of  libraries as follows:

  • Next, inside the android {} tag, add the following lines:
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")
}
}
  • Next, add the configurations within the 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')

 }

4. Add the App Modules

Stepping ahead, we will add the various modules inside the dependency tag{} with the configurations mentioned below:

 dependencies {

 ... // your app dependencies

 configurations {
     all {
         exclude group: 'org.json', module: 'json'
         exclude group: 'xpp3', module: 'xpp3'
     }
 }

Continue adding the upcoming modules within the same tag.

  • Lifecycle Listener

This module has all the necessary information related to the app. It tracks and monitors the activities happening within the app.

        implementation 
  'android.arch.lifecycle:extensions:1.1.1'
        annotationProcessor 
  'android.arch.lifecycle:compiler:1.1.1'
  • GreenDao

This component is object-relational. It maps the app objects to SQLite databases

 implementation 'de.greenrobot:greendao:2.1.0'
  • gson parsing

You may use this process to convert the Java objects into respective JSON reps

   implementation 'com.google.code.gson:gson:2.8.1'
  • Smack Implementation

This module is an XMPP client library used for easy transfer of data

  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

These dependencies are modules that are used to mimic the programming codes during compile time.

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

These codes are used to make a block of codes concurrently within a project to keep the program running consistently

   implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.3'
 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.3'
  • API Calls
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

This interceptor is used to detect any issues with the network and send the data using HTTP websockets.

 implementation 
'com.facebook.stetho:stetho-okhttp3:1.3.1'
  • OkHttp Interceptor

When APIs are used, this module continuously tracks, rewrites and retries the call

        implementation
 'com.squareup.okhttp3:logging-interceptor:3.14.3'
  • Shared Preference Encryption

These objects contain small key-value pairs that encrypts the data and sets the privacy preferences as shared or private.

        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'
  • Close the dependency tag. 
  • Next, add the below code to gradle.properties file to prevent any conflicts among the library files imported from the SDK
android.enableJetifier=true
  • Resolve the WebRTC dependencies by adding the below line within the dependencyResolutionManagement{} tag
dependencyResolutionManagement {
 repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
 repositories {
 google()
 mavenCentral()
 jcenter()
 }
}

5. Provide Manifest Permissions

A manifest is used in a program to define each component of an app. These modules require specific permissions so that the library conflicts can be avoided among the dependency files.

Add the below permission:

<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" />

Now, Go to app > manifests > AndroidManifest.xml and update the network access permissions

6. Authenticate the Video Chat SDK

At the stage when you’ve got our app prepared for the SDK integration, you need to update the  License key details in the builder configuration of the project as follows:

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"'
  }
}

Once you’ve updated it, you need to perform the gradle sync operation.

How to Perform the gradle sync?

Locate the gradle sync as shown in the picture

Otherwise, Go to File > Sync Project with Gradle Files

Note: Restart Android studio after gradle sync to see the changes take effect.

7. Initialize Your Chat SDK

The builder class of the app is used to construct the object step by step. This simplifies the entire SDK initialization process. Let’s begin the steps by starting the SDK.

  • Go to the  Application Class
  • Call the onCreate() method

Note: Below, I will use the codes of both Kotlin and Java to build your own 1-to-1 video chat app. You may use the one as per your requirement.

To debug if the codes that contain heavy system logs and data, we’ll use the below code:

Java
//For chat logging
LogMessage.enableDebugLogging(BuildConfig.DEBUG);

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

8. Register an App User

Add a user in sandbox/ live mode using the following code:

Java
  FlyCore.registerUser(USER_IDENTIFIER, (isSuccess, throwable, data ) -> {
    if(isSuccess) {
        Boolean isNewUser = (Boolean) data.get("is_new_user");
        JSONObject responseObject = (JSONObject) data.get("data");
       // Get Username and password from the object
    } else {
       // Register user failed print throwable to find the exception details.
    }
   });
Kotlin
  FlyCore.registerUser(USER_IDENTIFIER) { isSuccess, throwable, data ->
    if(isSuccess) {
        val isNewUser = data["is_new_user"] as Boolean
        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.
    }   
 }

9. Connect Chat SDK to MirrorFly Server

The Chat SDK must be connected to the MirrorFly server so that your one on one video chat app can send and receive messages. The below code is used to achieve this:

Java
ChatManager.connect(new ChatConnectionListener() {
     @Override
     public void onConnected() {
         // Write your success logic here to navigate Profile Page or
         // To Start your one-one chat with your friends
     }

     @Override
     public void onDisconnected() {
        // Connection disconnected
        //No need implementations
     }

    @Override
     public void onConnectionNotAuthorized() {
        // Connection Not authorized
        //No need implementations
    }
});
Kotlin
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
   }
   })

10. Initialize Call SDK

Within the onCreate() method of your Application Class, add the below line:

Java
@Override
public void onCreate() {
super.onCreate();
//Initialize call manager
CallManager.init(this);
//set your call activity
CallManager.setCallActivityClass(CALL_UI_ACTIVITY.class);
CallManager.setMissedCallListener((isOneToOneCall, userJid, groupId, callType, userList) -> {
  //show missed call notification
});

CallManager.setCallHelper(new CallHelper() {
  @NonNull
  @Override
  public String getNotificationContent(@NonNull String callDirection) {
      return CallNotificationHelper.getNotificationMessage();
  }

  @Override
  public void sendCallMessage(@NotNull GroupCallDetails details, @NotNull List<String> users, @NotNull List<String> invitedUsers) {
      CallMessenger.sendCallMessage(details, users, invitedUsers);
  }
  });

CallManager.setCallNameHelper(new CallNameHelper() {
  @NonNull
  @Override
  public String getDisplayName(@NonNull String jid) {
      return ContactManager.getDisplayName(jid);
  }
  });
}
Kotlin
@Override
public void onCreate() {
super.onCreate();
//Initialize call manager
CallManager.init(this)
//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<String>) {
               //show missed call notification
           }
     })
     
CallManager.setCallHelper(object : CallHelper {
    override fun getNotificationContent(callDirection: String): String {
        return CallNotificationHelper.getNotificationMessage()
    }

    override fun sendCallMessage(details: GroupCallDetails, users: List<String>, invitedUsers: List<String>) {
        CallMessenger.sendCallMessage(details, users, invitedUsers)
    }
  })

CallManager.setCallNameHelper(object : CallNameHelper {
    override fun getDisplayName(jid: String): String {
      return ContactManager.getDisplayName(jid)
    }
  })

  }

11. Set Up Call Activity

In your manifest, define your UI call activity as follows:

 <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" />

Next, configure the call activity within the onCreate() method 

Java
CallManager.configureCallActivity(ACTIVITY);
Kotlin
CallManager.configureCallActivity(ACTIVITY)

To notify the Call SDK to remove the ongoing call notifications, you need to call the below method on the onStart() of your call activity 

Java
CallManager.bindCallService();
Kotlin
CallManager.bindCallService()

Similarly, to show the call notification, add the below line within the onStop() method of your call activity.

Java
CallManager.unbindCallService();
Kotlin
CallManager.unbindCallService()

Required Run-time Permissions

To make a one on one video call, you need to grant the below permissions:

Manifest.permission.RECORD_AUDIO
Manifest.permission.CAMERA
Manifest.permission.READ_PHONE_STATE

Check the permission using the below code:

Java
CallManager.isVideoCallPermissionsGranted();
Kotlin
CallManager.isVideoCallPermissionsGranted()

12. Make a Video call

To make a video call to another SDK user, you need to add the following code to your project:

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

13. Answer the Video Call

When a user presses the ‘Accept’ key on their device UI, the below method will notify the caller that the call has been answered. 

Java
  CallManager.answerCall((isSuccess, message) -> {
        
    });
Kotlin
   CallManager.answerCall(object : CallActionListener {
      override fun onResponse(isSuccess: Boolean, message: String) {
    
      }
  })

14. Decline an Incoming Call

When a user calls declines an incoming call from another SDK user, the caller will be notified that their call has been declined using the following method:

Java
  CallManager.declineCall();
Kotlin
  CallManager.declineCall()

15. Disconnect the Ongoing Video Call

When a user has to disconnect from an ongoing call with another SDK user, the latter will be notified about the disconnection using the following code:

Java

  CallManager.disconnectCall();

Kotlin

  CallManager.disconnectCall()

Conclusion

That’s great! You’ve come through all the steps of building a 1-to-1 video chat app.

To recap, we created an android app project in Android Studio, downloaded the Video Chat SDKs from MirrorFly and integrated them. After establishing a server connection, we added the codes to enable video calling functionalities to make one-to-one video chat, call answer, decline and disconnection. 

Aspiring to do more with your app? Explore the many possibilities of adding interesting chat features from MirrorFly.  Need more help? Click here to talk with our team.

Krushi Shivasangaran

Krushi is a Digital Marketer by choice & profession. She munches on topics relating to Technology, E-Commerce, Enterprise Mobility, Cloud Solutions and Internet of Things.

Leave a Reply

Your email address will not be published.