In this tutorial, you will learn how to implement the read receipt feature on your Android app with the help of MirrorFly SDKs. This entire tutorial is coded in Java, and the steps are illustrated to develop apps in Android Studio.
Please note that this guide assumes that you have a basic familiarity with Javascript . With no further ado, Let’s begin!
Read receipts is a chat app feature that lets senders know when the message they’ve sent is opened or read by the recipient. To implement this feature, you’ll need a ready-to-integrate SDK, which is available to download instantly from MirrorFly.
Let’s take a closer look into the steps to build read receipts into Android apps:
Step 1 : Go to the Signup Page
Step 2 : Sign up using your Google or LinkedIn account or,
Step 3 : Fill in the sign up details. An account confirmation link will be sent to your email.
Step 4 : Click the link and verify your account.
Step 5 : On confirmation, you will be taken to the Account Dashboard
Step 6 : Extract the dependencies from the ZIP folder. We’ll use these files in Part 2
Step 7 : Next, scroll down to find the License Key
Step 8 : You’ll need this License key in Part 3
In this step, we’ll create a New Android App project.
Step 1 : Open the Android Studio IDE
Step 2 : Fill in the details of your project on the Welcome Page
Step 3 : Select the programming language as Java
Step 4 : The project dashboard will open. On this page, go to the project menu on the left side
Step 5 : Select the App folder
Step 6 : Import all the dependencies downloaded in Part 1
Once the dependencies are added to the project,
Step 1 : Add the below code to the build gradle of your app folder
plugins {
...
id 'kotlin-android'
id 'kotlin-kapt'
}
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
packagingOptions {
exclude 'META-INF/AL2.0'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
exclude 'META-INF/LGPL2.1'
exclude("META-INF/*.kotlin_module")
}
}
Step 2 : Next, add the dependencies to the app/build.gradle file
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')
}
Step 3 : Add the below modules to the app/build.gradle file
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.8'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.3.8'
//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'
//for mobile number formatting
implementation 'io.michaelrocks:libphonenumber-android:8.10.1'
}
Step 4 : In order to refrain from conflict among the imported library files, we’ll need to add the below code to the gradle.properties file
android.enableJetifier=true
Step 5 : Next, add the permissions to AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Step 6 : Now, we need to add the License key to the app/build.gradle file
buildTypes {
debug {
buildConfigField 'String', 'SDK_BASE_URL', '"https://api-preprod-sandbox.mirrorfly.com/api/v1/"'
buildConfigField 'String', 'LICENSE', '"xxxxxxxxxxxxxxxxxxxxxxxxx"'
buildConfigField 'String', 'WEB_CHAT_LOGIN', '"https://webchat-preprod-sandbox.mirrorfly.com/"'
buildConfigField "String", "SUPPORT_MAIL", '"contussupport@gmail.com"'
}
}
This step will collect all the essential data like client and server details to start the data exchange between user devices.
Step 1 : To kickstart, add the below code to the onCreate() method of the Application class
//For chat logging
LogMessage.enableDebugLogging(BuildConfig.DEBUG);
new ChatSDK.Builder()
.setDomainBaseUrl(BuildConfig.SDK_BASE_URL)
.setLicenseKey(BuildConfig.LICENSE)
.setIsTrialLicenceKey(true)
.build();
This step is used to register the user in the sandbox or live mode. The below code will check if the license key is on trial and register the user
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.
}
});
To connect the client-side apps, we’ll need a central server that can execute data exchange between the devices. The below SDK method will set up the server connection and start receiving and sending the data on client requests from user devices.
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
}
});
Once, the server connection is established, you can start sending messages from a device through the SDK by implementing the following method
FlyMessenger.sendTextMessage(TO_JID, TEXT, new SendMessageListener() {
@Override
public void onResponse(boolean isSuccess, @Nullable ChatMessage chatMessage) {
// you will get the message sent success response
}
});
This method will be used to notify the user device when new incoming messages are received on the user device.
@Override
public void onMessageReceived(@NonNull ChatMessage message) {
super.onMessageReceived(message);
// received message object
}
});
Once the app can send and receive messages, the user needs the status of the message delivery on the UI. The below method will notify the user when the recipient has opened the sent message.
Before setting this up, we’ll need to make a few configurations with the user jid. Here are the steps:
Step 1 : We’ll need to set the user jid as ongoing chat user in the activity/fragment onResume
@Override
public void onResume() {
super.onResume();
ChatManager.setOnGoingChatUser(JID);
}
Step 2 : Next, we’ll need to clear the ongoing chat user in the activity/fragment onPause
@Override
public void onPause() {
super.onPause();
ChatManager.setOnGoingChatUser("");
}
Step 3 : Now, when the chat window is opened, the recipient jid will be passed to the below method
Step 4 : The SDK will start using the user jid set by the ChatManager.setOnGoingChatUser(jid: String)
ChatManager.markAsRead(JID)
Using the below method, we can register a listener to update the user UI immediately on any message related events. When a message is sent via the SDK, the message status events will give the respective callbacks.
ChatEventsManager.setupMessageEventListener(new MessageEventsListener() {
@Override
public void onMessageReceived(@NotNull ChatMessage message) {
//called when the new message is received
}
@Override
public void onMessageStatusUpdated(@NotNull String messageId) {
//called when the message status is updated
//find the index of message object in list using messageId
//then fetch message object from db using `FlyMessenger.getMessageOfId(messageId)` and notify the item in list
}
@Override
public void onMediaStatusUpdated(@NotNull ChatMessage message) {
//called when the message status is updated
//find the index of message object in list using messageId
//then fetch message object from db using `FlyMessenger.getMessageOfId(messageId)` and notify the item in list
}
@Override
public void onUploadDownloadProgressChanged(@NotNull String messageId, int progressPercentage) {
//called when the media message progress is updated
}
@Override
public void onMessagesClearedOrDeleted(@NotNull ArrayList messageIds) {
//called when the message is deleted
}
});
Through this tutorial, we have seen the steps to implement read receipts in an Android chat app , including the respective code samples. To explore more features for your app, we encourage you to check out our Features page.
Also, you can also gain further details and support with the implementation from our team of experts. Contact us now!
Add chat features to your Flutter apps - in 10 minutes - with just a few lines of code.
Request DemoDrive 1 billion + conversations on any Android, iOS, or Web app with 500+ chat features & 100+ UI components.