Medium

How to easily integrate MQTT CHAT android library version 1.1.0 in any android application from API 14.

PAR -

In this tutorial we will show you how to integrate mqtt chat android library version 1.1.0 in an android application. We will see the three integration methods: by activity, fragment or one to one dialog. We will see also some advanced integration options for specific needs.

TÉLÉCHARGER LE CODE
VIDEO DEMO

Please note that we will use in server side the same database and the same web application of the mqttchat web tutorial. We are going to add other PHP files in rest folder which will serve as intermediary between android application and Mysql database.

mqtt chat app credentials

Let’s start creating our Android application.

1- Creating New Project

1. Create a new project in Android Studio from File ⇒ New Project by filling the required details.

2. As we need to make network requests, we need to add INTERNET permission in AndroidManifest.xml.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.test.test123">
  <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:name=".mApplication"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="test123"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

3. Open app build.gradle and add MQTTCHAT vsersion 1.0.0 library dependencies. There are two sub-libraries: mqttchat-core which contains MQTTCHAT core (business layer) and mqttchat-gui which contains the graphical interfaces (representation layer).


dependencies {
    implementation 'com.telifoun.mqttchat:mqttchat-core:1.1.0'
    implementation 'com.telifoun.mqttchat:mqttchat-gui:1.1.0'
}     

4.To be able to access the MQTT CHAT libraries, you must add MQTTCHAT Artifactory repository to the list of Maven repositories in your top level build.gradle file.


allprojects {
    repositories {       
        maven {
            url "http://mqttchat.telifoun.com:8081/artifactory/libs-release-local"
            credentials {
                username = "mqttchat"
                password = "telifoun"
            }
        }
    }
}  

2- MQTT CHAT Initialisation

1. You must first retrieve APP_ID and APP_SECRET from your MQTTCHAT customer area.

mqtt chat app credentials

2. in Application class mApplication.java add mqtt chat initialisation.


 public class mApplication extends MultiDexApplication {   
    @Override
    public void onCreate() {
        super.onCreate();
        new Mqttchat.getBuilder()
                .context(this.getApplicationContext())
                .appName(getApplicationContext().getResources().getString(R.string.app_name))
                .appIcon(R.mipmap.ic_launcher)
                .domain("test123.com")
                .appId("mqttchat-04939886")
                .appSecret("mqttchat-7izmgu617jiti6s0")
                .debugMode(true)
                .build();
    }
}

3- HTTP Client

1. Any android application that needs to store or to get data from a database must use web services. In this tutorial, to simplify we will use PHP pages which return JSON data. But beware In a production application you must use secure REST services ...
There are several open source Android libraries that allow you to query web services. But since MQTT CHAT already use Google VOLLEY library in MQTTCHAT SDK. We will use this library as HTTP client.


public class restRequest {
    public void request(int method, String url, HashMap<String,Object> data, final Callback clb){

        JsonObjectRequest newReq = new JsonObjectRequest(method,
                url, (data!=null)?new JSONObject(data):null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            if(response.getString("ok").equals("true")){
                             clb.OK(response);
                            }else{
                             clb.KO(response.getString("error"));
                            }
                        } catch (Exception ex) {
                            ex.printStackTrace();
                         clb.KO(ex.getMessage());
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        try {
                            if (volleyError.networkResponse == null) {
                                clb.KO(volleyError.getMessage());
                            } else {
                               clb.KO(new JSONObject(new String(volleyError.networkResponse.data, "UTF-8")).getString("error"));
                            }
                        }catch (Exception ex) {
                            ex.printStackTrace();
                            clb.KO(ex.getMessage());
                        }

                    }
                });

        sdk.getInstance().addToRequestQueue(newReq);
    }

}

com.telifoun.mqttchat.core.Callback is a callback MQTT CHAT abstract class that return OK on success and KO on error.


public abstract class Callback {
    public Callback() {}  
    public abstract void OK(Object var1);
    public abstract void KO(String var1);
}    

4- Add Application Config

Under app package, create a class named Config.java. This class contains app configuration information related to php files urls.


public class Config {
    public static final String URL_REST_USER="http://localhost/mqtt_chat/rest/register.php";
    public static final String URL_REST_LOGIN="http://localhost/mqtt_chat/rest/login.php";
}    

5- Add new User

1. Add new empty activity RegisterActivity. Then Open the layout file for register activity (activity_register.xml).


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".RegisterActivity">

    <EditText
        android:id="@+id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        android:hint="Name"
         />

    <EditText
        android:id="@+id/surname"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        android:hint="SurName"
       />

    <EditText
        android:id="@+id/email"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Email"
        android:inputType="textEmailAddress"
       />

    <EditText
        android:id="@+id/password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Password"
        android:inputType="textPassword"
         />

    <Spinner
        android:id="@+id/gender"
        android:padding="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawSelectorOnTop="true"
        android:entries="@array/gender_arrays"
       />

    <Button
        android:layout_marginTop="20dp"
        android:id="@+id/registerBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Register"
        />

</LinearLayout>

2. Now open the RegisterActivity.java and modify the code as below.

    
public class RegisterActivity extends AppCompatActivity {

    private EditText name,surname,email,password;
    private Spinner gender;
    private Button registerButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register);
        setTitle("Register");

        name=(EditText) findViewById(R.id.name);
        surname=(EditText) findViewById(R.id.surname);
        email=(EditText) findViewById(R.id.email);
        password=(EditText) findViewById(R.id.password);
        gender=(Spinner) findViewById(R.id.gender);

        registerButton=(Button) findViewById(R.id.registerBtn);
        registerButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                registerAction();
            }
        });
    }

    public void registerAction(){

        boolean cancel = false;
        View focusView = null;

        if (TextUtils.isEmpty(name.getText().toString()) ||
                (name.getText().length()<2)) {
            name.setError(getString(R.string.error_field_required));
            cancel=true;
            focusView=name;
        }
        if (TextUtils.isEmpty(surname.getText().toString()) ||
                (surname.getText().length()<2)) {
            surname.setError(getString(R.string.error_field_required));
            cancel=true;
            focusView=surname;
        }
        if (TextUtils.isEmpty(email.getText().toString())) {
            email.setError(getString(R.string.error_field_required));
            cancel=true;
            focusView=email;
        }
        if (TextUtils.isEmpty(password.getText().toString())) {
            password.setError(getString(R.string.error_field_required));
            cancel=true;
            focusView=password;
        }

        if(cancel){
            focusView.requestFocus();
        }else{
            restRegister();
        }

    }

    private void restRegister(){

        final ProgressDialog mProgressDialog = ProgressDialog.show(this, "register",
               "registring new user", true);

        HashMap<String,Object> user_data=new HashMap<String,Object>();
        user_data.put("name", name.getText().toString());
        user_data.put("surname",surname.getText().toString());
        user_data.put("email", email.getText().toString());
        user_data.put("password",password.getText().toString());
        user_data.put("gender",gender.getSelectedItemPosition());

        (new restRequest()).request(JsonObjectRequest.Method.POST, Config.URL_REST_USER, user_data, new Callback() {
            @Override
            public void OK(Object o) { // register success

                try {
                    
                    JSONObject userJson = ((JSONObject) o).getJSONObject("response");
                    final int userId= userJson.getInt("id");

                    /** Add user to MQTTCHAT **/
                    sdkUser user =new sdkUser();
                    user.Set(userId,
                            userJson.getString("name"),
                            userJson.getString("surname"),
                            "",
                            "",
                            userJson.getInt("gender"));                   
                    user.Add(new sdkCallback() {
                        @Override
                        public void OK(RestResponse restResponse) {
                            /** logIn user to MQTTCHAT **/
                            Mqttchat.getmInstance().logIn(getApplicationContext(),userId, new Callback(){
                                @Override
                                public void OK(Object o) {
                                    mProgressDialog.dismiss();
                                    finish();
                                    Intent myIntent = new Intent(RegisterActivity.this, MainActivity.class);
                                    startActivity(myIntent);
                                }
                                @Override
                                public void KO(String s) {
                                    mProgressDialog.dismiss();
                                    Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
                                }
                            });
                        }
                        @Override
                        public void KO(RestResponse restResponse) {
                            mProgressDialog.dismiss();
                            Toast.makeText(getApplicationContext(),restResponse.getError().getError(),Toast.LENGTH_SHORT).show();
                        }
                    });

                }catch(Exception ex){
                    mProgressDialog.dismiss();
                    Toast.makeText(getApplicationContext(),ex.getMessage(),Toast.LENGTH_SHORT).show();
                }

            }

            @Override
            public void KO(String s) { //register fail
                mProgressDialog.dismiss();
                Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
                Log.i(Config.app_tag,s);
            }
        });
    }
}
mqtt chat app register

As you can see in the register.java activity we have:

+ Saved the new user in the Mysql database using the HTTP Client seen in section 3. In server side we used the file register.php below.


<?php
   include("../include/db_connect.php");    
   $data=json_decode($HTTP_RAW_POST_DATA,true);   

   $name = mysqli_real_escape_string($dbh,$data['name']);
   $surname = mysqli_real_escape_string($dbh,$data['surname']);
   $mail = mysqli_real_escape_string($dbh,$data['email']);
   $password = mysqli_real_escape_string($dbh,$data['password']); 
   $gender= mysqli_real_escape_string($dbh,$data['gender']);
      
   $sql = "INSERT INTO users (id, name, surname,mail,password,gender)
             VALUES (null,'$name', '$surname', '$mail' ,'$password',$gender)";

   if (mysqli_query($dbh,$sql) === TRUE) {
       $result=array("ok"=>true,"response"=>array("id"=>$dbh->insert_id,
                                                  "name"=>$name,
                                                  "surname"=>$surname,
                                                  "gender"=>$gender));
   } else {
        $result=array("ok"=>false,"error"=>$dbh->error);
   }  
    
  header('Content-type: application/json; charset=utf-8');
  echo json_encode($result);
  exit;
?>    

+ When saving new user in database is successfully performed, the user is then added to MQTT CHAT using SDK Add function.

+ Finally when user is successfully added to MQTT CHAT, he is logged to MQTT CHAT using MQTT CHAT logIn function and can start chating.

6- User Login

1. For a user already registered, we use LoginActivity to authenticate it to our application and to MQTT CHAT. So add new empty activity LoginActivity. Then Open the layout file for login activity (activity_login.xml).


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".LoginActivity">

    <EditText
        android:id="@+id/email"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Email"
        android:inputType="textEmailAddress"
        />

    <EditText
        android:id="@+id/password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="Password"
        android:inputType="textPassword"
        />


    <Button
        android:layout_marginTop="20dp"
        android:id="@+id/loginBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Login"
        />


    <Button
        android:layout_marginTop="20dp"
        android:id="@+id/registerBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Register"
        />

</LinearLayout>

2. Now open the LoginActivity.java and modify the code as below.

 
package com.test.test123;

import androidx.appcompat.app.AppCompatActivity;

import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.telifoun.mqttchat.core.Callback;
import com.telifoun.mqttchat.gui.Mqttchat;
import com.telifoun.mqttchat.volley.toolbox.JsonObjectRequest;

import org.json.JSONObject;

import java.util.HashMap;

public class LoginActivity extends AppCompatActivity {
    private EditText mail;
    private EditText password;
    private Button registerBtn;
    private Button loginBtn;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_login);
        mail=(EditText) findViewById(R.id.email);
        password=(EditText) findViewById(R.id.password);

        Button loginBtn=(Button) findViewById(R.id.loginBtn);
        loginBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                checkLogIn();
            }
        });

        Button registerBtn=(Button) findViewById(R.id.registerBtn);
        registerBtn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                Intent myIntent = new Intent(LoginActivity.this, RegisterActivity.class);
                startActivity(myIntent);
            }
        });
    }

    private void checkLogIn(){

        boolean cancel = false;
        View focusView = null;

        if (TextUtils.isEmpty(mail.getText().toString()) ||
                (mail.getText().length()<5)) {
            mail.setError(getString(R.string.error_field_email));
            cancel=true;
            focusView=mail;
        }

        if (TextUtils.isEmpty(password.getText().toString()) ||
                (password.getText().length()<4)) {
            password.setError(getString(R.string.error_field_password));
            cancel=true;
            focusView=password;
        }

        if(cancel){
            focusView.requestFocus();
        }else{
            logIn();
        }

    }


    private void logIn(){

        final ProgressDialog mProgressDialog = ProgressDialog.show(this, "User Login",
               "Login user to APP", true);

        HashMap<String,Object> user_data=new HashMap<String,Object>();
        user_data.put("mail", mail.getText().toString());
        user_data.put("password",password.getText().toString());

        (new restRequest()).request(JsonObjectRequest.Method.POST, Config.URL_REST_LOGIN, user_data, new Callback(){
            @Override
            public void OK(Object o) {
                try {
                    Log.i(Config.app_tag,((JSONObject) o).toString());
                    /** Get user Id **/
                    JSONObject userJson = ((JSONObject) o).getJSONObject("response");
                    final int userId= userJson.getInt("id");

                    /** Login to MQTTCHAT **/
                    Mqttchat.getmInstance().logIn(getApplicationContext(),userId, new Callback(){
                        @Override
                        public void OK(Object o) {
                            mProgressDialog.dismiss();
                            finish();
                            Intent myIntent = new Intent(LoginActivity.this, MainActivity.class);
                            startActivity(myIntent);

                        }
                        @Override
                        public void KO(String s) {
                            mProgressDialog.dismiss();
                            Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
                        }
                    });

                }catch (Exception e){
                    mProgressDialog.dismiss();
                    Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void KO(String s) {
                mProgressDialog.dismiss();
                Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
            }
        });
    }
}
mqtt chat app register

As you can see in the login.java activity we have:

+ Used the HTTP Client seen in section 3 to check user login and password. In server side we used the file login.php that return user Id in case authentication success.


<?php
   include("../include/db_connect.php");    
   $data=json_decode($HTTP_RAW_POST_DATA,true);   

    $mail = mysqli_real_escape_string($dbh,$data['mail']);
    $password = mysqli_real_escape_string($dbh,$data['password']); 
      
    $sql = "SELECT id FROM users WHERE mail = '$mail' and password = '$password'";
    $result = mysqli_query($dbh,$sql);
    $row = mysqli_fetch_array($result,MYSQLI_ASSOC);      
     
      // If result matched $myusername and $mypassword, table row must be 1 row
      if($row["id"]>0) {        
       $result=array("ok"=>true,"response"=>array("id"=>$row["id"]));
      }else {
       $result=array("ok"=>false);
      }
    
  header('Content-type: application/json; charset=utf-8');
  echo json_encode($result);
  exit;
?>

+ When remote authentication succeeded, the user is then logged to MQTT CHAT using MQTT CHAT logIn function and can start chating.

7- Use of Splash Activity

To prevent user from logging in each time the application is launched. You can use a sharedprefrences file to save user id when authentication succeeded. You can then use a splash activity SplashActivity to check if user id is already saved on it. If yes then you can redirect him to the chat interface directly otherwise it is redirected to LoginActivity.
SplashActivity should be configured as louncher activity of the application in the AndroidManifest.xml file. The java code that can be used looks like the code below:


private void logIn(){
        int userId= getApplicationContext().getSharedpreferences().getInt("UserId",0);
        if(userId>0){
                Mqttchat.getmInstance().logIn(getApplicationContext(), userId, new Callback() {
                    @Override
                    public void OK(Object o) {
                        Intent myIntent = new Intent(SplashActivity.this, MainActivity.class);
                        startActivity(myIntent);
                        finish();
                    }

                    @Override
                    public void KO(String s) {                                         
                        Toast.makeText(getApplicationContext(),s,Toast.LENGTH_SHORT).show();
                    }
                });
        }else{

            Intent myIntent = new Intent(SplashActivity.this, LoginActivity.class);
            startActivity(myIntent);
            finish();
        }
    } 

8- Show Chat GUI

1. To louch chat GUI in separate Activity use the code below in MainActivity.java.


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Mqttchat.getmInstance().lounchMqttChat(getApplicationContext(), new Callback() {
            @Override
            public void OK(Object o) {
            }
            @Override
            public void KO(String s) {
            }
        });
    }
}  

On the left the android chat GUI, on the right the web chat GUI already seen in mqttchat web tutorial

mqtt chat app android 1
mqtt chat app web 1

2. To louch chat GUI as embedded fragment in MainActivity. First open the layout file for main activity (activity_main.xml) and add the following XML code.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Top Activity textview content. "
      />

    <FrameLayout
        android:name="com.telifoun.mqttchat.gui.MqttchatFragment"
        android:id="@+id/mqttchatFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout> 

Use the code below in MainActivity.java to show MQTT CHAT Fragment.


public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getSupportFragmentManager().beginTransaction().add(R.id.mqttchatFragment, MqttchatFragment.newInstance(), "mqttchat").commit();
    }
}    
mqtt chat app android 2
mqtt chat app web 2

You can try audio and video calls between WEB application and Android application.

mqtt chat app android 3
mqtt chat app web 3

9- Offline Calls and Notifications

MQTT CHAT uses FCM (Firebase Cloud Messaging) to send notifications when messages are received and the android application is closed and to route audio and video calls when the application is closed.

FCM functionality is not activated by default, to activate it for your application, you must follow all steps indicated in the FCM section of the Android documentation

Don't forget to add FCM Server key to your MQTT CHAT FCM settings in client Area.

mqtt chat app android 3

If all config is ok you will automatically receive notifications and calls even if your android application is closed.

mqtt chat app android 4
mqtt chat app web 4

10- Custom colors

You can customize Mqttchat GUI colors to match your android application theme. For more information please read custom colors android documentation section. In this tutorial we will change our MQTT CHAT GUI colors by editing color.xml ressource file as below


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#008577</color>
    <color name="colorPrimaryDark">#00574B</color>
    <color name="colorAccent">#3D99D7</color>
    <color name="colorWhite">#FFFFFF</color>
    <color name="mqttchat_colorPrimary">#FFF</color>
    <color name="mqttchat_textColorPrimary">#1B71A5</color>
</resources>

GUI Result is as below:

mqtt chat app android 5

That's it for this tutorial. I hope that through a practical example MQTT CHAT android library integration is clearer. Do not forget to minimize the size of your android application before publishing it to Google Play. Please read Decreasing Application size documentation section. If you are facing any issue in this tutorial, please comment in below discussions.


2020 © MQTT-CHAT.com Inc.