Tech Talks

How To Build An Android Voice and Video Calling App Using Java?

Published On May 25th, 2023 Tech Talks

Voice and video calling apps have become an essential part of businesses these days. While there are so many options like Zoom, Skype, Google Duo, and Discord to choose from, most entrepreneurs and tech enthusiasts have started creating apps for their brands.  

Moving smart ahead, developers choose to add communication features to their apps instead of building a whole app from scratch. If you are interested on the same, this article is definitely for you.  

Check For Pre-Requisites

We will be building an android app with voice and video call capabilities by integrating MirrorFly’s SDKs. 

With no further ado, let’s get ahead and create a video chat app in minutes!

Before you start, make sure you have:

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

Prepare Your Application

If you are planning to build an app, you have 2 options:

  1. Build an app from scratch
  2. Develop an app on top of our sample app.

If you are opting for the latter, download our sample app for free here.

Create An Account With Mirrorfly

When you integrate the MirrorFly SDK into your app, it has to be authenticated by the MirrorFly server. For this, you will need a License Key.

To acquire the License key:

  • Go to MirrorFly’s console page – https://console.mirrorfly.com/register
  • Add the basic details including name, business email, contact and organization details
  • Click on SignUp and your account gets created.

Get The License Key

Once you sign into your account, you will be taken to the overview page.

In the ‘Application info’ section,  you will be able to find the ‘License Key’ needed for the authentication process

Download SDKs

Once you’ve noted down the License Key, 

  • Navigate below where you will have the Android SDK available for download
  • Click on ‘Download’
  • Find the downloaded SDK folder on your device
  • Extract the AAR files and get them ready for the integration process.

SDK Integration to Add Voice and Video Capabilities

The SDKs are already available as AAR files. They just need to be imported into the Android Project for the integration process to commence.

1. Create a new project in the Android Studio IDE or open an existing project

2. In the project window, add the downloaded library files to the app/libs folder.

  • appbase.aar
  • flycommons.aar
  • flynetwork.aar
  • flydatabase.aar
  • videocompression.aar
  • xmpp.aar
  • flywebrtc.aar

3. Next, add the below code to 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")
    }
}

4. In the same app/build.gradle file, add the below dependencies that are needed by SDKs

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')
 }
dependencies {

	configurations 	{ 
	    all {
		exclude group: 'org.json', module: 'json' 
	        exclude group: 'xpp3', module: 'xpp3'
       	}
}	
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')
}

5. Continue to add the next set of dependencies

 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'

 }

6. To avoid imported library conflicts, you will need to add the below code to the gradle.properties file

android.enableJetifier=true

7. In order to resolve the WebRTC dependencies, add the below line in the setting.gradle file

dependencyResolutionManagement {
 repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
 repositories {
     google()
     mavenCentral()
     jcenter()
 }
}

8. Add the below permissions to the AndroidManifest.xml. This manifests helps describe the characteristic feature of every element involved in the integration process

<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

Configure the elements in buildConfigField that includes License Key, acquired in the previous steps

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

Intialization of Data for Voice and Video Calls

A call SDK needs specific data to perform its operations effectively. To do this, get into the onCreate() method of the Application class and define the ChatSDK Builder as follows


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

ChatSDK.Builder()
    .setDomainBaseUrl(BuildConfig.SDK_BASE_URL)
    .setLicenseKey(BuildConfig.LICENSE)
    .setIsTrialLicenceKey(true)
    .build(); 

Chat Builder Function Description

FunctionParameter TypeDescription
setDomainBaseUrlStingUrl is provided to make API calls
setLicenseKeyStingLicense key is required to proceed with registration
setIsTrialLicenseKeyBooleanIf the provided license key is for trial version, display the text as ‘true’ else ‘false’
buildn/aInitializes the chat configuration

Note: When you enter the setDomainBaseUrl the http/ https must close with a slash (/). Otherwise an exception – bug message may appear.

Configure your app’s backup rules and themes by using the code below, as mentioned in the image.

Register a User

Based on the setIsTrialLicenceKey method, you need to register a user in the sandbox live mode. During this process, the FCM_TOKEN will be accepted as an optional parameter by the  registerUser method. Here, you will have to call the function FlyCore.registerUser() in the main activity () as below:

  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.
        }
   });
ArgumentTypeDescription
USER_IDENTIFIERStringA unique Id to Register the User
FCM_TOKENStringA registration token that is generated by FCM SDK for the user’s app instance to send message for free
CALLBACKFlyCallbackFlyCallback is used as a callback, implemented and expressed as lambda expression for easy reading

Establish the Chat Server Connection

A Chat SDK needs a server connection to enable your app to send/ receive messages. The SDK provides methods to start the chat connection to the server. Here we use the ChatManager.connect() function to start a connection between the Chat server and the SDK.

    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
        }
    });
ArgumentTypeDescription
CALLBACKChatConnectionListenercallback listener for chat connection

Initialize the SDK for Voice and Video Calls

Only when the SDK is initialized, you application will be able to run. To perform this, you’ll need to start the call SDK in the onCreate() method as follows

ArgumentTypeDescription
CALL_UI_ACTIVITYClassActivity which needs to be invoked during incoming calls. when a incoming call is received Call SDK will start this activity with the call details
@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);
      }
  });
}

Call Activity Setup

In your manifest, you need to define the Call UI activity using the below method

     <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, you’ll have to configure the call activities in activityonCreate() as done below

CallManager.configureCallActivity(ACTIVITY);
ArgumentTypeDescription
ACTIVITYActivityInstance of the call activity

If you’ve decided not to show the ongoing call notification, you must remove it in the onStart() method and notify the call SDK as follows

CallManager.bindCallService();

Similarly, if you need to show the ongoing call notification, notify the call SDK by calling the onStop() method

CallManager.unbindCallService();

Make the first Voice/ Video Call from Your App

If users need to make a live voice call or live video call from the client’s app, it will ask for runtime permissions when launched for the first time. These permissions must be  requested before the calling the SDKs. Otherwise, it might lead to an error message in the callback, in the absence of required permissions.

You need the below permissions to make a voice call

Manifest.permission.RECORD_AUDIO
Manifest.permission.READ_PHONE_STATE

Next, you’ll have to check for the voice/ audio permissions using the below method

 CallManager.isAudioCallPermissionsGranted();

You need the below permissions to make a video call

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

Next, you’ll have to check for the video permissions using the below method

 CallManager.isVideoCallPermissionsGranted();

Next, for easy audio routing and gsm call handling,

  • Check if android.permission.BLUETOOTH_CONNECT is provided to ensure that the bluetooth connectivity is routed.
  • Also, check whether the android.permission.READ_PHONE_STATE is provided for recording audio and other gsm related functionalities.
  • Having provided the permissions, use the below code to allow users to make a direct/ one-to-one voice call to other SDK users
 CallManager.makeVoiceCall("TO_JID", (isSuccess, message) -> {       
                    });
ArgumentTypeDescription
TO_JIDStringjid of the call receiver
CALLBACKCallActionListenercallback to observe the action status

Similarly, to make a video call, call the below method

 CallManager.makeVideoCall("TO_JID", (isSuccess, message) -> {
                    });

Receive a Voice/ Video Call

When your Android version is greater than Android 10 (API level 29), a pop-up notification will appear when you receive a call. Otherwise, the CallManager.setCallActivityClass() method that you’ve set during the intialisation process will automatically start using the available call details.

Answer the Voice/ Video Call

Whenever a user receives a call from another user, he/ she will be notified by the call SDK, in the UI. When the call is accepted by clicking on the ‘Accept’ button, the call will be answered.

ArgumentTypeDescription
CALLBACKCallActionListenercallback to observe the action status
  CallManager.answerCall((isSuccess, message) -> {
                    });

Decline the Voice/ Video Call

When a user declines an incoming call, the below SDK method will be called and the other user will be notified that the call has been declined.

  CallManager.declineCall();

Disconnect the ongoing voice call

When a user needs to disconnect from an ongoing call or is cut off by factors like weak network or low battery, the below SDK method will disconnect the call and notify the user at the other end

  CallManager.disconnectCall();

Conclusion

Remember, video chat apps are everywhere. But, building an efficient one requires upskilling along with the right tools. The steps mentioned above is a quick and easy way to add voice and video calling capabilities to your Android app, provided you have an account with MirrorFly.

To help you further, we offer a customizable chat solution that includes perks like 100% customization, on-premise hosting, and white-label chat solution that you can learn from our official website. If you’ll need guided assistance for adding chat features to your app, our team is here to help – contact them now!

Ready to Get Started with Our Self-hosted Video, Voice & Chat Solution?
  • 100% Customizable
  • One-time License Cost
  • Hire Dedicated Team

Krishi Shivasangaran

Krishi Shivasangaran is a digital nomad and a veteran of Digital Marketing strategies. She is passionate about learning the newest trends in Live Video Call. And, when she's off-role, she loves to sketch and make people realize the true color of nature.

Voice and video calling apps have become an essential part of businesses these days. While there are so many options like Zoom, Skype, Google Duo, and Discord to choose from, most entrepreneurs and tech enthusiasts have started creating apps for their brands.  

Moving smart ahead, developers choose to add communication features to their apps instead of building a whole app from scratch. If you are interested on the same, this article is definitely for you.  

Check For Pre-Requisites

We will be building an android app with voice and video call capabilities by integrating MirrorFly’s SDKs. 

With no further ado, let’s get ahead and create a video chat app in minutes!

Before you start, make sure you have:

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

Prepare Your Application

If you are planning to build an app, you have 2 options:

  1. Build an app from scratch
  2. Develop an app on top of our sample app.

If you are opting for the latter, download our sample app for free here.

Create An Account With Mirrorfly

When you integrate the MirrorFly SDK into your app, it has to be authenticated by the MirrorFly server. For this, you will need a License Key.

To acquire the License key:

  • Go to MirrorFly’s console page – https://console.mirrorfly.com/register
  • Add the basic details including name, business email, contact and organization details
  • Click on SignUp and your account gets created.

Get The License Key

Once you sign into your account, you will be taken to the overview page.

In the ‘Application info’ section,  you will be able to find the ‘License Key’ needed for the authentication process

Download SDKs

Once you’ve noted down the License Key, 

  • Navigate below where you will have the Android SDK available for download
  • Click on ‘Download’
  • Find the downloaded SDK folder on your device
  • Extract the AAR files and get them ready for the integration process.

SDK Integration to Add Voice and Video Capabilities

The SDKs are already available as AAR files. They just need to be imported into the Android Project for the integration process to commence.

1. Create a new project in the Android Studio IDE or open an existing project

2. In the project window, add the downloaded library files to the app/libs folder.

  • appbase.aar
  • flycommons.aar
  • flynetwork.aar
  • flydatabase.aar
  • videocompression.aar
  • xmpp.aar
  • flywebrtc.aar

3. Next, add the below code to 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")
    }
}

4. In the same app/build.gradle file, add the below dependencies that are needed by SDKs

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')
 }
dependencies {

	configurations 	{ 
	    all {
		exclude group: 'org.json', module: 'json' 
	        exclude group: 'xpp3', module: 'xpp3'
       	}
}	
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')
}

5. Continue to add the next set of dependencies

 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'

 }

6. To avoid imported library conflicts, you will need to add the below code to the gradle.properties file

android.enableJetifier=true

7. In order to resolve the WebRTC dependencies, add the below line in the setting.gradle file

dependencyResolutionManagement {
 repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
 repositories {
     google()
     mavenCentral()
     jcenter()
 }
}

8. Add the below permissions to the AndroidManifest.xml. This manifests helps describe the characteristic feature of every element involved in the integration process

<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

Configure the elements in buildConfigField that includes License Key, acquired in the previous steps

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

Intialization of Data for Voice and Video Calls

A call SDK needs specific data to perform its operations effectively. To do this, get into the onCreate() method of the Application class and define the ChatSDK Builder as follows


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

ChatSDK.Builder()
    .setDomainBaseUrl(BuildConfig.SDK_BASE_URL)
    .setLicenseKey(BuildConfig.LICENSE)
    .setIsTrialLicenceKey(true)
    .build(); 

Chat Builder Function Description

FunctionParameter TypeDescription
setDomainBaseUrlStingUrl is provided to make API calls
setLicenseKeyStingLicense key is required to proceed with registration
setIsTrialLicenseKeyBooleanIf the provided license key is for trial version, display the text as ‘true’ else ‘false’
buildn/aInitializes the chat configuration

Note: When you enter the setDomainBaseUrl the http/ https must close with a slash (/). Otherwise an exception – bug message may appear.

Configure your app’s backup rules and themes by using the code below, as mentioned in the image.

Register a User

Based on the setIsTrialLicenceKey method, you need to register a user in the sandbox live mode. During this process, the FCM_TOKEN will be accepted as an optional parameter by the  registerUser method. Here, you will have to call the function FlyCore.registerUser() in the main activity () as below:

  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.
        }
   });
ArgumentTypeDescription
USER_IDENTIFIERStringA unique Id to Register the User
FCM_TOKENStringA registration token that is generated by FCM SDK for the user’s app instance to send message for free
CALLBACKFlyCallbackFlyCallback is used as a callback, implemented and expressed as lambda expression for easy reading

Establish the Chat Server Connection

A Chat SDK needs a server connection to enable your app to send/ receive messages. The SDK provides methods to start the chat connection to the server. Here we use the ChatManager.connect() function to start a connection between the Chat server and the SDK.

    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
        }
    });
ArgumentTypeDescription
CALLBACKChatConnectionListenercallback listener for chat connection

Initialize the SDK for Voice and Video Calls

Only when the SDK is initialized, you application will be able to run. To perform this, you’ll need to start the call SDK in the onCreate() method as follows

ArgumentTypeDescription
CALL_UI_ACTIVITYClassActivity which needs to be invoked during incoming calls. when a incoming call is received Call SDK will start this activity with the call details
@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);
      }
  });
}

Call Activity Setup

In your manifest, you need to define the Call UI activity using the below method

     <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, you’ll have to configure the call activities in activityonCreate() as done below

CallManager.configureCallActivity(ACTIVITY);
ArgumentTypeDescription
ACTIVITYActivityInstance of the call activity

If you’ve decided not to show the ongoing call notification, you must remove it in the onStart() method and notify the call SDK as follows

CallManager.bindCallService();

Similarly, if you need to show the ongoing call notification, notify the call SDK by calling the onStop() method

CallManager.unbindCallService();

Make the first Voice/ Video Call from Your App

If users need to make a live voice call or live video call from the client’s app, it will ask for runtime permissions when launched for the first time. These permissions must be  requested before the calling the SDKs. Otherwise, it might lead to an error message in the callback, in the absence of required permissions.

You need the below permissions to make a voice call

Manifest.permission.RECORD_AUDIO
Manifest.permission.READ_PHONE_STATE

Next, you’ll have to check for the voice/ audio permissions using the below method

 CallManager.isAudioCallPermissionsGranted();

You need the below permissions to make a video call

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

Next, you’ll have to check for the video permissions using the below method

 CallManager.isVideoCallPermissionsGranted();

Next, for easy audio routing and gsm call handling,

  • Check if android.permission.BLUETOOTH_CONNECT is provided to ensure that the bluetooth connectivity is routed.
  • Also, check whether the android.permission.READ_PHONE_STATE is provided for recording audio and other gsm related functionalities.
  • Having provided the permissions, use the below code to allow users to make a direct/ one-to-one voice call to other SDK users
 CallManager.makeVoiceCall("TO_JID", (isSuccess, message) -> {       
                    });
ArgumentTypeDescription
TO_JIDStringjid of the call receiver
CALLBACKCallActionListenercallback to observe the action status

Similarly, to make a video call, call the below method

 CallManager.makeVideoCall("TO_JID", (isSuccess, message) -> {
                    });

Receive a Voice/ Video Call

When your Android version is greater than Android 10 (API level 29), a pop-up notification will appear when you receive a call. Otherwise, the CallManager.setCallActivityClass() method that you’ve set during the intialisation process will automatically start using the available call details.

Answer the Voice/ Video Call

Whenever a user receives a call from another user, he/ she will be notified by the call SDK, in the UI. When the call is accepted by clicking on the ‘Accept’ button, the call will be answered.

ArgumentTypeDescription
CALLBACKCallActionListenercallback to observe the action status
  CallManager.answerCall((isSuccess, message) -> {
                    });

Decline the Voice/ Video Call

When a user declines an incoming call, the below SDK method will be called and the other user will be notified that the call has been declined.

  CallManager.declineCall();

Disconnect the ongoing voice call

When a user needs to disconnect from an ongoing call or is cut off by factors like weak network or low battery, the below SDK method will disconnect the call and notify the user at the other end

  CallManager.disconnectCall();

Conclusion

Remember, video chat apps are everywhere. But, building an efficient one requires upskilling along with the right tools. The steps mentioned above is a quick and easy way to add voice and video calling capabilities to your Android app, provided you have an account with MirrorFly.

To help you further, we offer a customizable chat solution that includes perks like 100% customization, on-premise hosting, and white-label chat solution that you can learn from our official website. If you’ll need guided assistance for adding chat features to your app, our team is here to help – contact them now!

Ready to Get Started with Our Self-hosted Video, Voice & Chat Solution?
  • 100% Customizable
  • One-time License Cost
  • Hire Dedicated Team

Krishi Shivasangaran

Krishi Shivasangaran is a digital nomad and a veteran of Digital Marketing strategies. She is passionate about learning the newest trends in Live Video Call. And, when she's off-role, she loves to sketch and make people realize the true color of nature.

Leave a Reply

Your email address will not be published. Required fields are marked *

Request Demo