How to Build a 1-to-1 Video Chat App with Java or Kotlin?
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.
Table of Contents
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
- 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.
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()
Recommended Reading
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.
Get Started with MirrorFly’s Modern Video Chat API!
Drive 1+ billions of conversations on your apps with highly secure 250+ real-time Communication Features.
Contact Sales- 200+ Happy Clients
- Topic-based Chat
- Multi-tenancy Support
We are looking for a video chat app using java video SDK for our website. We are a tutoring agency and the service would be for communication between students and faculties
Hi Johny, thanks for your interest in MirrorFly’s one-on-one video call solution. We offer 2 flexible pricing models – SaaS and SaaP (self-hosted solution) at users’ convenience. You may choose our SaaS solution if you would like to use our features for a monthly subscription fee. On the other hand, our self-hosted video calling solution renders you 100% customizable video, voice, and chat features for a one-time license cost. To know more about our pricing details, please visit our pricing page.
Our aim is we have to call to our customers from our java video chat application and from number will show to destination mobile number. And From Number will change not fixed.
Hi Antony, thanks for your interest in MirrorFly’s javascript video call solution. If you are interested to know more details, please contact our sales team.
Hi. I am starting my own video chat app using java SDK, and I have some doubts. My app is join ONLY 2 people for 1 or 2 hours and I want to record the session only 1 user: 1) I would like to know how much money is the cost for recording and video call?
Hi Santia! Nice to know that you are building a video char app using Java and appreciate your interest in MirrorFly’s in-app video chat SDKs. We will email you the full details.
Hi, We are interested in getting your best pricing for integrating video chat ( one on one and groups) into our app (Kotlin) We are a start up company.Do you offer any stickers, filters and emojis with your video chat?
Hello Naavjit, it is really amazing news that you are building a video call app using kotlin. We offer SaaS and self-hosted pricing models for users based on their needs. To know more about our pricing, please visit our pricing page.
Just looking for a simple communication platform, similar to Upwork, in order to do one-on-one video chats with clients. Your video api with some customization might be something I am interested depending on the cost. Needs to be easy to manage permissions. I’d prefer kotlin video SDK or java video sdk
Hi Lawrence, thanks for your interest in MirrorFly’s video call solution. We will share all the features details to your email id.
A software developer is working on my application for e-commerce but he needs support on how to integrate a kotlin video sdk. How much is your package and how can we add your video call and voice API to the application.
Hi Tewee, thanks for your interest in MirrorFly’s Kotlin video SDK. We offer 2 flexible pricing models – SaaS and SaaP (self-hosted solution) at users’ convenience. You may choose our SaaS solution if you would like to use our features for a monthly subscription fee. On the other hand, our self-hosted video calling solution renders you 100% customizable video, voice, and chat features for a one-time license cost. To know more about our pricing details, please visit our pricing page.