Fetching and listing conversations for an Android chat application

This tutorial continues the development of an Android chat application. Here, we’ll add the ability for registered users to retrieve their chat conversations.

The sections covered in this tutorial are as follows:

  • Fetching Conversations from the Server
  • Editing the Android App for Receiving Conversations
  • ChatListViewActivity

Let’s get started.

Fetching Conversations from the Server

In a chat application, a user might start multiple conversations, and each conversation will inevitably have a number of sent and received messages.

It is not a good design to show all messages in all conversations together and it is better to organize the application to first fetch the conversations started between users. The conversations will be listed in an Android ListView. When the user clicks a conversation, then the messages sent and received within it will be fetched.

In this section, we’re going to edit the Flask server to respond to the requests to fetch the conversations.

First of all, it’s very important to highlight that all requests received by the server are processed by the chat() function. This function then calls the appropriate function that processes the request. All requests have a field named subject that explains the purpose of the request, and thus helps to select the appropriate function that handles the request.

To allow our app to handle requests that ask for receiving the conversations, the chat() function is edited as shown in the below code. When the subject field is set to receive_chats, this informs the server that the request asks for receiving the conversations for a specific user. This user is the one logged into the Android app.

@app.route('/', methods = ['GET', 'POST'])
def chat():
    msg_received = flask.request.get_json()
    msg_subject = msg_received["subject"]

    if msg_subject == "register":
        return register(msg_received)
    elif msg_subject == "login":
        return login(msg_received)
    elif msg_subject == "verify":
        return verify(msg_received)
    elif msg_subject == "send":
        return send(msg_received)
    elif msg_subject == "receive_chats":
        return receive_chats(msg_received)
    else:
        return "Invalid request."

When the subject is set to receive_chats, then the receive_chats() function will be called to handle the request. The implementation of this function is given below. Let’s discuss the lines within this function.

def receive_chats(msg_received):
    receiver_username = msg_received["receiver_username"]

    select_query = "SELECT first_name, last_name FROM users where username = " + "'" + receiver_username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) == 0:
        return "Invalid receiver username."

    select_query = "SELECT DISTINCT sender_username FROM messages where receiver_username = " + "'" + receiver_username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) == 0:
        print("No messages delivered for username " + receiver_username)
        return "0"

    all_chats = {}
    for record_idx in range(len(records)):
        curr_record = records[record_idx]
        sender_username = curr_record[0]
        
        curr_chat = {}
        curr_chat["username"] = sender_username

        all_chats[str(record_idx)] = curr_chat

    all_chats = json.dumps(all_chats)
    print("Sending Chat(s) :", all_chats)
    return all_chats

The first line in the function returns the username that we will fetch his/her conversations.

In order to make sure that the username already exists in the database, the following code executes a SELECT query based on the username returned. If there are no records returned, then the username doesn’t exist, and thus the response to the Android client is a text message signifying that the username is invalid.

After making sure the username is valid, the conversations between this user and all other users will be fetched according to the SELECT query shown in the code below.

By fetching the conversations, we mean fetching the usernames of the other registered users that at least sent a single message to that user [logged in user]. Note that this logged in username is regarded as the receiver, and all other users are regarded as the senders.

To fetch the usernames that sent at least one message, the messages table is queried. Because one user might have sent multiple messages, then the DISTINCT clause is used to just return each username only once. If no messages are sent to the user, then there are no conversations, and thus the receive_chats() function returns 0.

If there are conversations between the logged in user and the other users, then the following code creates a dictionary named all_chats that holds the username of the senders.

The prepared dictionary is then converted into a JSON object using the json library, as given in the next line. This JSON object is what’s returned by the receive_chats() function.

Now that we’ve discussed the receive_chats() function, here’s the entire implementation of the Flask server. You’ll need to make a few specific edits in the server, including specifying the e-mail ID and password from which e-mails will be sent to the users that register into the app, the IPv4 address and port number to which the server will listen for incoming requests, and keys used for encryption and decryption.

import flask
import mysql.connector
import sys
import json
import smtplib, ssl
from email.mime.text import MIMEText
import cryptography.fernet

app = flask.Flask(__name__)

@app.route('/', methods = ['GET', 'POST'])
def chat():
    msg_received = flask.request.get_json()
    msg_subject = msg_received["subject"]

    if msg_subject == "register":
        return register(msg_received)
    elif msg_subject == "login":
        return login(msg_received)
    elif msg_subject == "verify":
        return verify(msg_received)
    elif msg_subject == "send":
        return send(msg_received)
    elif msg_subject == "receive_chats":
        return receive_chats(msg_received)
    else:
        return "Invalid request."

def register(msg_received):
    first_name = msg_received["first_name"]
    lastname = msg_received["last_name"]
    username = msg_received["username"]
    email = msg_received["email"]

    select_query = "SELECT * FROM users where username = " + "'" + username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "username" # "Username already exists. Please chose another username."

    select_query = "SELECT * FROM users where email = " + "'" + email + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "email" # "E-mail is already registered."

    send_verification_code(first_name, lastname, username, email) # Encrypt e-mail using 2 keys and send the code to the user e-mail.

    return "success"

def verify(msg_received):
    firstname = msg_received["firstname"]
    lastname = msg_received["lastname"]
    username = msg_received["username"]
    email = msg_received["email"]
    password = msg_received["password"]
    verification_code = msg_received["verification_code"]

    select_query = "SELECT * FROM users where username = " + "'" + username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "Another user just used the username. Please chose another username."

    select_query = "SELECT * FROM users where email = " + "'" + email + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) != 0:
        return "Another user just registered using the e-mail entered."

    verification_state = verify_code(email, verification_code)

    if verification_state == True:
        insert_query = "INSERT INTO users (first_name, last_name, username, email, password, email_confirmed) VALUES (%s, %s, %s, %s, MD5(%s), %s)"
        insert_values = (firstname, lastname, username, email, password, True)
        try:
            db_cursor.execute(insert_query, insert_values)
            chat_db.commit()
            print("This e-mail", email, " is verified and user is registered successfully.")
            subject = "Welcome to HiAi"
            body = "Hi " + firstname + " " + lastname + ",nnYour account is created successfully at HiAi. You can login with your username and password into the Android app to send and receive messages. nnYour username is " + username + "nnIf you forgot your password, just contact [email protected] for resetting it. nnGood luck.nHiAi [email protected]"
            send_email(subject, body, email)
            return "success"
        except Exception as e:
            print("Error while inserting the new record :", repr(e))
            return "Error while processing the request."
    else:
        print("This e-mail", email, " verification failed.")
        return "failure"

def verify_code(email, verification_code):
    decoded_email = decrypt_text(verification_code)

    if decoded_email == email:
        return True # Email verification succeeded.
    else:
        return False # Email verification failed.

def send(msg_received):
    text_msg = msg_received["msg"]
    sender_username = msg_received["sender_username"]
    sender_username = decrypt_text(sender_username)

    receiver_username = msg_received["receiver_username"]

    select_query = "SELECT * FROM users where username = " + "'" + receiver_username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) == 0:
        return "Invalid receiver username."

    select_query = "SELECT * FROM users where username = " + "'" + sender_username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) == 0:
        return "Invalid sender username."

    insert_query = "INSERT INTO messages (sender_username, receiver_username, message) VALUES (%s, %s, %s)"
    insert_values = (sender_username, receiver_username, text_msg)

    try:
        db_cursor.execute(insert_query, insert_values)
        chat_db.commit()
        print(db_cursor.rowcount, "New record inserted successfully.")
    except Exception as e:
        print("Error while inserting the new record :", repr(e))
        return "Error while processing the request."

    print("Received message from :", sender_username, "(", text_msg, ") to be sent to ", receiver_username)
    return "success"

def receive_chats(msg_received):
    receiver_username = msg_received["receiver_username"]

    select_query = "SELECT first_name, last_name FROM users where username = " + "'" + receiver_username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) == 0:
        return "Invalid receiver username."

    select_query = "SELECT DISTINCT sender_username FROM messages where receiver_username = " + "'" + receiver_username + "'"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()
    if len(records) == 0:
        print("No messages delivered for username " + receiver_username)
        return "0"

    all_chats = {}
    for record_idx in range(len(records)):
        curr_record = records[record_idx]
        sender_username = curr_record[0]

        curr_chat = {}
        curr_chat["username"] = sender_username 

        all_chats[str(record_idx)] = curr_chat

    all_chats = json.dumps(all_chats)
    print("Sending Chat(s) :", all_chats)
    return all_chats

def encrypt_text(text_to_encrypt):
    key_file1 = open("encryption_key1.key", "rb")
    encryption_key1 = key_file1.read()
    key_file1.close()
    
    key_file2 = open("encryption_key2.key", "rb")
    encryption_key2 = key_file2.read()
    key_file2.close()

    encoded_email = text_to_encrypt.encode()

    f = cryptography.fernet.MultiFernet([cryptography.fernet.Fernet(encryption_key1), cryptography.fernet.Fernet(encryption_key2)])
    
    encrypted_text = f.encrypt(encoded_email)
    
    return encrypted_text

def decrypt_text(text_to_decrypt):
    key_file1 = open("encryption_key1.key", "rb")
    encryption_key1 = key_file1.read()
    key_file1.close()
    
    key_file2 = open("encryption_key2.key", "rb")
    encryption_key2 = key_file2.read()
    key_file2.close()
    
    f = cryptography.fernet.MultiFernet([cryptography.fernet.Fernet(encryption_key1), cryptography.fernet.Fernet(encryption_key2)])

    try:
        decrypted_text = f.decrypt(text_to_decrypt.encode('utf-8'))
    except:
        return False # Email verification failed.

    decoded_text = decrypted_text.decode()

    return decoded_text

def send_verification_code(firstname, lastname, username, email):
    
    encrypted_email = encrypt_text(email)
    
    body = "Hi " + firstname + " " + lastname + ",nnThanks for registering for HiAi Chat System.nnYour username is " + username + ".nTo verify your account, just copy the verification code found below, return back to the Android app, paste the code, and finally click the Verify button.nnn" + encrypted_email.decode()
    subject = "HiAi Verification"

    send_email(subject, body, email)

def login(msg_received):
    username = msg_received["username"]
    password = msg_received["password"]

    select_query = "SELECT first_name, last_name FROM users where username = " + "'" + username + "' and password = " + "MD5('" + password + "')"
    db_cursor.execute(select_query)
    records = db_cursor.fetchall()

    if len(records) == 0:
        return "failure"
    else:
        return "success"

def send_email(subject, body, email):
    port = 465  # For SSL
#    smtp_server = "smtp.gmail.com"
    smtp_server = "hiai.website"
    sender_email = "[email protected]"  # Enter your address
#    sender_email = "[email protected]"  # Enter your address
    password = "..."

    msg_body = body
    
    msg = MIMEText(msg_body, 'plain', 'utf-8')

    # add in the actual person name to the message template
    msg['From'] = sender_email
    msg['To'] = email
    msg['Subject'] = subject

    context = ssl.create_default_context()
    with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:
        server.login(sender_email, password)
        server.sendmail(sender_email, email, msg.as_string())

try:
    chat_db = mysql.connector.connect(host="localhost", user="root", passwd="ahmedgad", database="chat_db")
except:
    sys.exit("Error connecting to the database. Please check your inputs.")

db_cursor = chat_db.cursor()

app.run(host="0.0.0.0", port=5000, debug=True, threaded=True) # Run in development server.
# waitress.serve(app=app, host="0.0.0.0", port=5000) # Run in production server.

After editing the server to allow the Android app to receive messages sent for a given username, we’ll now edit the Android app so that it’s able to send the request, receive the response, and display the conversations in a ListView.

Editing the Android app to receive conversations

Below, the main activity layout of the Android app is edited to include a new Button view that displays the conversations when clicked:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#EAF2F3"
    android:orientation="vertical">
<Button
        android:id="@+id/register"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:background="#D7E2B8"
        android:onClick="register"
        android:text="Register"
        android:textStyle="bold" />
<Button
        android:id="@+id/login"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:background="#D7E2B8"
        android:onClick="login"
        android:text="Login"
        android:textStyle="bold" />
<Button
        android:id="@+id/sendMessage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:background="#D7E2B8"
        android:onClick="sendMessage"
        android:text="Send Message"
        android:textAllCaps="false"
        android:textStyle="bold" />
<Button
        android:id="@+id/receiveChat"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:background="#D7E2B8"
        android:onClick="receiveChat"
        android:text="Show Your Conversations"
        android:textAllCaps="false"
        android:textStyle="bold" />
<TextView
        android:id="@+id/responseText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:text="Connection Status."
        android:textAlignment="center"
        android:textColor="#FF0000"
        android:textStyle="bold" />
</LinearLayout>

The screen of the activity is shown in the next figure:

When the new Button is clicked, the receiveChat() method is called. The implementation of this method is given below. The method starts with an if statement that checks whether or not there’s a user logged in:

public void receiveChat(View v) {
    TextView responseText = findViewById(R.id.responseText);
    if (loginUsername.equals("")) {
        responseText.setText("Please login first.");
        return;
    }
responseText.setText("Fetching conversations. Please wait ...");
JSONObject messageContent = new JSONObject();
    try {
        messageContent.put("subject", "receive_chats");
        messageContent.put("receiver_username", loginUsername);
    } catch (JSONException e) {
        e.printStackTrace();
    }
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), messageContent.toString());
postRequest(MainActivity.postUrl, body);
}

When the user is already logged in, a JSON object is created in the messageContent variable that holds 2 fields, which are:

  1. subject: Subject of the message that tells the server how to handle the request. To receive the conversations, the subject is set to receive_chats.
  2. receiver_username: Username of the logged in user, used to receive its conversations.

After the JSON object is created, the request body is created as an instance of the RequestBody class, and finally the postRequest() method is called, which accepts the body as an argument. This method is responsible for sending the request and receiving the response. Its implementation is given in the following code.

As usual, the newCall() method is called to send the request, and the onResponse() callback method receives the response.

public void postRequest(String postUrl, RequestBody postBody) {
        OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
                .url(postUrl)
                .post(postBody)
                .header("Accept", "application/json")
                .header("Content-Type", "application/json")
                .build();
client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // Cancel the post on failure.
                call.cancel();
                Log.d("FAIL", e.getMessage());
// In order to access the TextView inside the UI thread, the code is executed inside runOnUiThread()
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        TextView responseText = findViewById(R.id.responseText);
                        responseText.setText("Failed to Connect to Server. Please Try Again.");
                    }
                });
            }
@Override
            public void onResponse(Call call, final Response response) {
                // In order to access the TextView inside the UI thread, the code is executed inside runOnUiThread()
                TextView responseText = findViewById(R.id.responseText);
                try {
                    String responseString = response.body().string().trim();
                    if (responseString.equals("0")) {
                        responseText.setText("No conversations."); // A message indicating that no messages are delivered for the user.
                        return;
                    }
Intent showChatsIntent = new Intent(getApplicationContext(), ChatListViewActivity.class);
                    ArrayList<String> sendersUsernames = new ArrayList<>();
JSONObject messageContent = new JSONObject(responseString);
                    try {
                        for (int i = 0; i < messageContent.length(); i++) {
                            JSONObject currMessage = messageContent.getJSONObject(i + "");
                            String senderUsername = currMessage.getString("username");
                            sendersUsernames.add(senderUsername);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
Log.d("CHATS", sendersUsernames.toString());
                    showChatsIntent.putExtra("receivedChats", sendersUsernames);
                    responseText.setText("Conversations Fetched.");
                    startActivity(showChatsIntent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

If there are no conversations for the user, then the Android app will receive 0 from the server. As a result, the app displays a message informing the user that there are no conversations available. If there are conversations, then an Intent is created that starts the ChatListViewActivity activity. The Intent passes a single variable to this activity as an extra which is receivedChats. It’s an ArrayList holding the usernames of the other participants in the conversations.

Before discussing the implementation of the ChatListViewActivity activity in the next section, which is pretty simple, here’s the complete code for the main activity. You just need to change the postUrl class variable to set the IPv4 address and port number of the Flask server.

package gad.hiai.chat.hiaichat;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
    public static Context mainActivityContext;
public static String loginUsername = "";
static String postUrl = "http://192.168.16.102:5000/";
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.INTERNET}, 0);
mainActivityContext = this;
    }
public void login(View v) {
        Intent intent = new Intent(this, LoginActivity.class);
        startActivityForResult(intent, 2);
    }
public void register(View v) {
        Intent intent = new Intent(this, RegisterActivity.class);
        startActivity(intent);
    }
public void sendMessage(View v) {
        TextView responseText = findViewById(R.id.responseText);
        if (loginUsername.equals("")) {
            responseText.setText("Please login first.");
            return;
        }
Intent intent = new Intent(this, SendMessageActivity.class);
        startActivity(intent);
    }
@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        TextView responseText = findViewById(R.id.responseText);
        if (requestCode == 2) { // Login
            responseText.setText("Successful Login.");
        } else {
            responseText.setText("Invalid or no data entered. Please try again.");
        }
    }
public void receiveChat(View v) {
        TextView responseText = findViewById(R.id.responseText);
        if (loginUsername.equals("")) {
            responseText.setText("Please login first.");
            return;
        }
responseText.setText("Fetching conversations. Please wait ...");
JSONObject messageContent = new JSONObject();
        try {
            messageContent.put("subject", "receive_chats");
            messageContent.put("receiver_username", loginUsername);
        } catch (JSONException e) {
            e.printStackTrace();
        }
RequestBody body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), messageContent.toString());
postRequest(MainActivity.postUrl, body);
    }
public void postRequest(String postUrl, RequestBody postBody) {
        OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
                .url(postUrl)
                .post(postBody)
                .header("Accept", "application/json")
                .header("Content-Type", "application/json")
                .build();
client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // Cancel the post on failure.
                call.cancel();
                Log.d("FAIL", e.getMessage());
// In order to access the TextView inside the UI thread, the code is executed inside runOnUiThread()
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        TextView responseText = findViewById(R.id.responseText);
                        responseText.setText("Failed to Connect to Server. Please Try Again.");
                    }
                });
            }
@Override
            public void onResponse(Call call, final Response response) {
                // In order to access the TextView inside the UI thread, the code is executed inside runOnUiThread()
                TextView responseText = findViewById(R.id.responseText);
                try {
                    String responseString = response.body().string().trim();
                    if (responseString.equals("0")) {
                        responseText.setText("No conversations."); // A message indicating that no messages are delivered for the user.
                        return;
                    }
Intent showChatsIntent = new Intent(getApplicationContext(), ChatListViewActivity.class);
                    ArrayList<String> sendersUsernames = new ArrayList<>();
JSONObject messageContent = new JSONObject(responseString);
                    try {
                        for (int i = 0; i < messageContent.length(); i++) {
                            JSONObject currMessage = messageContent.getJSONObject(i + "");
                            String senderUsername = currMessage.getString("username");
                            sendersUsernames.add(senderUsername);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
Log.d("CHATS", sendersUsernames.toString());
                    showChatsIntent.putExtra("receivedChats", sendersUsernames);
                    responseText.setText("Conversations Fetched.");
                    startActivity(showChatsIntent);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

ChatListViewActivity

The ChatListViewActivity is responsible for listing the conversations between the user that logged into the Android app and the other users.

The layout of this activity is shown below. It just has a single ListView for listing the usernames.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/chatListView"/>
</LinearLayout>

The implementation of the activity is shown below. The Intent that started this activity is returned in the intent variable. From such an Intent, the receivedChats ArrayList is returned using the getStringArrayListExtra() method.

In order to list the contents of this ArrayList into the ListView, an instance of the ArrayAdapter class is created. The constructor of this class accepts the layout of each list item. There’s no need to create a custom layout because there’s an already existing layout named simple_list_item_1 that fits our purpose.

package gad.hiai.chat.hiaichat;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
public class ChatListViewActivity extends AppCompatActivity {
    Intent intent;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat_list_view);
ListView messageListView = findViewById(R.id.chatListView);
intent = getIntent();
        ArrayList<String> receivedChats = intent.getStringArrayListExtra("receivedChats");
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, receivedChats);
        messageListView.setAdapter(adapter);
}
}

After creating the ArrayAdapter, the adapter of the ListView is set using the setAdapter() method. The last thing to do in order to make the application work is to declare the ChatListViewActivity class inside the Manifest file. This is done by adding the next line within the <Application> element of the file. You need to change the package name to match yours.

ِAfter running the application and clicking on the Show Your Conversations button, the usernames of the conversation participants will be fetched and displayed according to the next figure. In my case, I have 3 users, which are aabb, ahmedgad, and t.

Conclusion

This tutorial extended both the client and server of the chat project to support fetching conversations between the user that logged into the Android app and all participants of the conversations. The conversations are listed in a ListView.

Currently, there’s no way to see the messages inside the conversations. The next tutorial adds an OnItemClickListener to each of the list items. By clicking on a given conversation, a request will be sent to the server that fetches all messages within this conversation.

Avatar photo

Fritz

Our team has been at the forefront of Artificial Intelligence and Machine Learning research for more than 15 years and we're using our collective intelligence to help others learn, understand and grow using these new technologies in ethical and sustainable ways.

Comments 0 Responses

Leave a Reply

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