Android Learning
HomeBlogAbout

Android Learning

Learn Android development with comprehensive tutorials, guides, and best practices. From beginner to advanced Android programming.

Quick Links

  • Home
  • Blog
  • About
  • Contact
  • Newsletter

Resources

  • Android Developers
  • Kotlin Docs
  • Jetpack Compose

© 2026 Android Learning. All rights reserved.

Privacy PolicyTerms of Service
Back to Blog
March 21, 2017
73 min read
Akshay Raj

Android Login Registration System with PHP, MySQL and Sqlite

Android Login Registration System with PHP, MySQL and Sqlite

Akshay Raj

Android development expert

In this tutorials, you will learn how to develop a complete Android Login Registration System with PHP, MySQL, and SQLite Databases.

Complete features in our Login System:

*Login, Registration, Reset Password, Change Password. *Email Notification for Registration *Password Reset through Email. *PHP API to handle the JSON Login requests. *MySQL database to store the user data. *SQLite database to store Login data. In other words similar to the cookie in web browsers.

API (Application Programming Interface)

To interact with MySQL database we need to build a REST API first. REST API job is to get the request from the client, interact with the database and finally give the response back to the client. So we’ll create a simple PHP, MySQL API first. Our API do’s below jobs. ⇒ Accepts requests in GET/POST methods ⇒ Interact with the database by inserting/fetching data. ⇒ Finally will give response back in JSON format

1. Downloading & Installing WAMP

Download & Install WAMP server from www.wampserver.com/en/. Once installed, launch the program from Start ⇒ All Programs ⇒ WampServer ⇒ StartWampServer. If you are on Mac, alternatively you can use MAMP for the same. You can test your server by opening the address http://localhost/ in your browser. Also, you can check phpmyadmin by opening http://localhost/phpmyadmin Following is a screencast of Downloading and Installing WAMP Server.

2. Creating MySQL Database and Tables

Open phpmyadmin and execute below queries to create necessary database and table. Here we are creating only one table users to store users login information.
create database android_login /** Creating Database **/
use android_login /** Selecting Database **/
create table users(
   `id` int(11) primary key auto_increment,
   `unique_id` varchar(23) not null unique,
   `name` varchar(50) not null,
   `email` varchar(100) not null unique,
   `encrypted_password` varchar(250) not null,
   `otp` int(6) NOT NULL,
   `verified` int(1) NOT NULL DEFAULT '0',
   `created_at` datetime DEFAULT NULL
); /** Creating Users Table **/

3. Creating PHP Project

Go to the location where wamp installed and open www folder. The default installation location of wamp would be C:/wamp. Below is the final PHP project structure we are going to create in this article. Android Login and Registration Stracture 1. Go into www folder and create a folder named android_login. This will be the root directory of our project. 2. Now inside android_login, create a PHP file named config.php and add below content.
config.inc.php
<?php
    $username = "root";
    $password = "";
    $host = "localhost";
    $dbname = "android_login";
    $options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8');
    try {
        $db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $options);
    } catch(PDOException $ex) {
        die("Failed to connect to the database: " . $ex->getMessage());
    }
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
    if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) {
        function undo_magic_quotes_gpc(&$array) {
            foreach($array as &$value) {
                if(is_array($value)) {
                    undo_magic_quotes_gpc($value);
                }
                else {
                    $value = stripslashes($value);
                }
            }
        }
        undo_magic_quotes_gpc($_POST);
        undo_magic_quotes_gpc($_GET);
        undo_magic_quotes_gpc($_COOKIE);
    }
    header('Content-Type: text/html; charset=utf-8');
    session_start();
?>

3.1 Registration Endpoint

Now we have all the required classes ready. Let’s start creating the endpoint for user registration. This endpoint accepts name, email, and password as POST parameters and stores the user in MySQL database. In android_login root directory, create register.php with below code.
register.php
<?php
    require("config.php");
    if (!empty($_POST)) {
        $response = array(
            "error" => FALSE
        );
        $query = " SELECT 1 FROM users WHERE email = :email";
        //now lets update what :user should be
        $query_params = array(
            ':email' => $_POST['email']
        );
        try {
            $stmt = $db->prepare($query);
            $result = $stmt->execute($query_params);
        }
        catch (PDOException $ex) {
            $response["error"] = TRUE;
            $response["message"] = "Database Error1. Please Try Again!";
            die(json_encode($response));
        }
        $row = $stmt->fetch();
        if ($row) {
            $response["error"] = TRUE;
            $response["message"] = "I'm sorry, this email is already in use";
            die(json_encode($response));
        } else {
            $query = "INSERT INTO users ( unique_id, name, email, encrypted_password, otp, created_at ) VALUES ( :uuid, :name, :email, :encrypted_password, :otp, NOW() )";
         $otp = rand(100000, 999999);
         $verified = 0;
            $query_params = array(
                ':uuid' => uniqid('', true),
                ':name' => $_POST['name'],
                ':email' => $_POST['email'],
                ':encrypted_password' => password_hash($_POST['password'], PASSWORD_DEFAULT),
                ':otp' => $otp
            );
            try {
                $stmt = $db->prepare($query);
                $result = $stmt->execute($query_params);
            }
            catch (PDOException $ex) {
                $response["error"] = TRUE;
                $response["message"] = "Database Error2. Please Try Again!";
                die(json_encode($response));
            }
            $name = $_POST['name'];
            $email = $_POST['email'];
            $subject = "Android Learning Email Verification";
            $message = "Hello $name,\n\nVerify that you own $email.\n\nYou may be asked to enter this confirmation code:\n\n$otp\n\nRegards,\nAndroid Learning.";
            $from = "support@androidlearning.in";
            $headers = "From:" . $from;
            mail($email,$subject,$message,$headers);
            $response["error"] = FALSE;
            $response["message"] = "Register successful!";
            echo json_encode($response);
        }
    } else {
        echo 'Android Learning';
    }

3.2 Email Reset

Create a PHP file named reset-password.php with below code.
reset-password.php
<?php
require("config.php");
if (isset($_POST['tag']) && $_POST['tag'] != '') {
    $tag = $_POST['tag'];
    $response = array("tag" => $tag, "error" => FALSE);
    $query = "SELECT * FROM users WHERE email = :email";
        $query_params = array(
            ':email' => $_POST['email']
        );
        try {
            $stmt   = $db->prepare($query);
            $result = $stmt->execute($query_params);
        }
        catch (PDOException $ex) {
            $response["error"] = true;
            $response["message"] = "Database Error1. Please Try Again!";
            die(json_encode($response));
        }
        $success = false;
        $row = $stmt->fetch();
        $email = $_POST['email'];
    // Forgot Password
    if ($tag == 'forgot_pass') {
        $pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 6);            // Generate new password
        $newPassword = password_hash($pass, PASSWORD_DEFAULT);                                                                     // Encrypted Password
        if ($row) {
            $stmt = $db->prepare("UPDATE users SET encrypted_password = :newPass WHERE email = :email");
            $stmt->bindparam(":newPass", $newPassword);
            $stmt->bindparam(":email",$email);
            $stmt->execute();
            $success = true;
        }
        if ($success == true) {
            $name = $row['name'];
            $subject = "New Password Request";
            $message = "Hello $name.\n\nWe received a request to change your password on Android Learning\n\nYour new password:\n\n $pass\n\nRegards,\nAndroid Learning.";
            $from = "support@androidlearning.in";
            $headers = "From:" . $from;
            mail($email,$subject,$message,$headers);
            $response["error"] = false;
            $response["message"] = "A new password has been sent to your e-mail address.";
            die(json_encode($response));
        } else {
            $response["error"] = true;
            $response["message"] = "Invalid Credentials!";
            die(json_encode($response));
        }
    }
    // Change Password
    else if ($tag == 'change_pass') {
        $oldPassword = $_POST['old_password'];
        $newPassword = password_hash($_POST['password'], PASSWORD_DEFAULT);
        if ($row) {
            if (password_verify($oldPassword, $row['encrypted_password'])) {
                $stmt = $db->prepare("UPDATE users SET encrypted_password = :password WHERE email = :email");
                $stmt->bindparam(":password", $newPassword);
                $stmt->bindparam(":email",$email);
                $stmt->execute();
                $success = true;
            }
        }
        if ($success == true) {
            $response["error"] = false;
            $response["message"] = "Your Password has been changed!.";
            die(json_encode($response));
        } else {
            $response["error"] = true;
            $response["message"] = "Invalid Credentials!";
            die(json_encode($response));
        }
    }
} else {
    echo "Android Learning";
}

3.3 Verify Email Address

Create a PHP file named verification.php with below code.
verification.php
<?php
require("config.php");
if (isset($_POST['tag']) && $_POST['tag'] != '') {
    $tag = $_POST['tag'];
    $response = array("tag" => $tag, "error" => FALSE);
    $query = "SELECT * FROM users WHERE email = :email";
    $query_params = array(
        ':email' => $_POST['email']
    );
    try {
        $stmt   = $db->prepare($query);
        $result = $stmt->execute($query_params);
    }
    catch (PDOException $ex) {
        $response["error"] = true;
        $response["message"] = "Database Error1. Please Try Again!";
        die(json_encode($response));
    }
   $otp_ok = false;
    $success = false;
   $email = $_POST['email'];
   $statusY = 1;
    $row = $stmt->fetch();
    // Forgot Password
    if ($tag == 'verify_code') {
        if ($row) {
            if ($_POST['otp'] === $row['otp']) {
                $otp_ok = true;
                $stmt = $db->prepare("UPDATE users SET verified = :status WHERE email = :email");
                $stmt->bindparam(":status", $statusY);
                $stmt->bindparam(":email", $email);
                $stmt->execute();
            }
        }
        $query = "SELECT * FROM users WHERE email = :email";
        $query_params = array(
            ':email' => $_POST['email']
        );
        try {
            $stmt   = $db->prepare($query);
            $result = $stmt->execute($query_params);
        }
        catch (PDOException $ex) {
            $response["error"] = true;
            $response["message"] = "Database Error1. Please Try Again!";
            die(json_encode($response));
        }
        $user = $stmt->fetch();
        if ($otp_ok == true) {
            $response["error"] = false;
            $response["message"] = "Verify successful!";
            $response["user"]["uid"] = $user["unique_id"];
            $response["user"]["name"] = $user["name"];
            $response["user"]["email"] = $user["email"];
            $response["user"]["verified"] = $user["verified"];
            $response["user"]["created_at"] = $user["created_at"];
            die(json_encode($response));
        } else {
            $response["error"] = true;
            $response["message"] = "Invalid Credentials!";
            die(json_encode($response));
        }
    }
    // Change Password
    else if ($tag == 'resend_code') {
        $otp = rand(100000, 999999);
        if ($row) {
            $stmt = $db->prepare("UPDATE users SET otp = :otp WHERE email = :email");
            $stmt->bindparam(":otp", $otp);
            $stmt->bindparam(":email",$email);
            $stmt->execute();
            $success = true;
        }
        if ($success == true) {
            $name = $row['name'];
            $email = $_POST['email'];
            $subject = "Android Learning Email Verification";
            $message = "Hello $name,\n\nVerify that you own $email.\n\nYou may be asked to enter this confirmation code:\n\n$otp\n\nRegards,\nAndroid Learning.";
            $from = "support@androidlearning.in";
            $headers = "From:" . $from;
            mail($email,$subject,$message,$headers);
            $response["error"] = false;
            $response["message"] = "New otp has been sent to your e-mail address.";
            die(json_encode($response));
        }
    }
} else {
    echo 'Android Learning';
}

4. Create Android Project

1. In Android Studio, create a new project from File ⇒ New Project and fill all the required details. more details go to Create New Android Project. 2. Open build.gradle and add volley library support under dependencies.
build.gradle
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'com.google.android.material:material:1.0.0'

    implementation 'com.android.volley:volley:1.1.0'
}
3. Under helper package, create a class named Functions.java and add below code. In this class we declare the login, registration, email verifies and reset password URLs. While testing you need to replace the IP address with your localhost PC IP.
Functions.java
public class Functions {
    //Main URL
    private static String MAIN_URL = "http://192.168.225.46/android_login/";
    // Login URL
    public static String LOGIN_URL = MAIN_URL + "login.php";
    // Register URL
    public static String REGISTER_URL = MAIN_URL + "register.php";
    // OTP Verification
    public static String OTP_VERIFY_URL = MAIN_URL + "verification.php";
    // Forgot Password
    public static String RESET_PASS_URL = MAIN_URL + "reset-password.php";
......
4. Create a class named MyApplication.java. This class extends from Application which should be executed on app launch. In this class, we initiate all the volley core objects.
MyApplication.java
package org.snowcorp.login;
import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
/**
 * Created by Akshay Raj on 6/16/2016.
 * akshay@snowcorp.org
 * www.snowcorp.org
 */
public class MyApplication extends Application {
    public static final String TAG = MyApplication.class.getSimpleName();
    private RequestQueue mRequestQueue;
    private static MyApplication mInstance;
    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }
    public static synchronized MyApplication getInstance() {
        return mInstance;
    }
    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getApplicationContext());
        }
        return mRequestQueue;
    }
    public  void addToRequestQueue(Request req, String tag) {
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }
    public  void addToRequestQueue(Request req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }
    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}
5. Under helper package, create a class named SessionManager.java and add below code. This class maintains session data across the app using the SharedPreferences. We store a boolean flag isLoggedIn in shared preferences to check the login status.
SessionManager.java
package org.snowcorp.login.helper;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.util.Log;
public class SessionManager {
    // LogCat tag
    private static String TAG = SessionManager.class.getSimpleName();
    // Shared Preferences
    SharedPreferences pref;
    Editor editor;
    Context _context;
    // Shared pref mode
    int PRIVATE_MODE = 0;
    // Shared preferences file name
    private static final String PREF_NAME = "AndroidLogin";
    private static final String KEY_IS_LOGGEDIN = "isLoggedIn";
    public SessionManager(Context context) {
        this._context = context;
        pref = _context.getSharedPreferences(PREF_NAME, PRIVATE_MODE);
        editor = pref.edit();
    }
    public void setLogin(boolean isLoggedIn) {
        editor.putBoolean(KEY_IS_LOGGEDIN, isLoggedIn);
        // commit changes
        editor.commit();
        Log.d(TAG, "User login session modified!");
    }
    public boolean isLoggedIn(){
        return pref.getBoolean(KEY_IS_LOGGEDIN, false);
    }
}
6. Under helper package, create a class named DatabaseHandler.java and paste the below code. This class takes care of storing the user data in SQLite database. Whenever we need to get the logged in user information, we fetch from SQLite instead of making a request to the server.
DatabaseHandler.java
package org.snowcorp.login.helper;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.HashMap;
/**
 * Created by Akshay Raj on 13-03-2016.
 * Snow Corporation Inc.
 * www.snowcorp.org
 */
public class DatabaseHandler extends SQLiteOpenHelper {
    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 1;
    // Database Name
    private static final String DATABASE_NAME = "AndroidLogin";
    // Login table name
    private static final String TABLE_LOGIN = "login";
    // Login Table Columns names
    private static final String KEY_ID = "id";
    private static final String KEY_UID = "uid";
    private static final String KEY_NAME = "name";
    private static final String KEY_EMAIL = "email";
    private static final String KEY_CREATED_AT = "created_at";
    public DatabaseHandler(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    // Table Create Statements
    private static final String CREATE_LOGIN_TABLE = "CREATE TABLE " + TABLE_LOGIN + "("
            + KEY_ID + " INTEGER PRIMARY KEY,"
            + KEY_UID + " TEXT,"
            + KEY_NAME + " TEXT,"
            + KEY_EMAIL + " TEXT UNIQUE,"
            + KEY_CREATED_AT + " TEXT" + ")";
    // Creating Tables
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_LOGIN_TABLE);
    }
    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_LOGIN);
        // Create tables again
        onCreate(db);
    }
    /**
     * Storing user details in database
     * */
    public void addUser(String uid, String name, String email, String created_at) {
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(KEY_UID, uid); // uid
        values.put(KEY_NAME, name); // FirstName
        values.put(KEY_EMAIL, email); // Email
        values.put(KEY_CREATED_AT, created_at); // Created At
        // Inserting Row
        db.insert(TABLE_LOGIN, null, values);
        db.close(); // Closing database connection
    }
    /**
     * Getting user data from database
     * */
    public HashMap<String, String> getUserDetails(){
        HashMap<String,String> user = new HashMap<>();
        String selectQuery = "SELECT  * FROM " + TABLE_LOGIN;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(selectQuery, null);
        // Move to first row
        cursor.moveToFirst();
        if(cursor.getCount() > 0){
            user.put("uid", cursor.getString(1));
            user.put("name", cursor.getString(2));
            user.put("email", cursor.getString(3));
            user.put("created_at", cursor.getString(4));
        }
        cursor.close();
        db.close();
        // return user
        return user;
    }
    /**
     * Re crate database
     * Delete all tables and create them again
     * */
    public void resetTables(){
        SQLiteDatabase db = this.getWritableDatabase();
        // Delete All Rows
        db.delete(TABLE_LOGIN, null, null);
        db.close();
    }
}

4.1 Reset Password Screen

7. Create an XML layout named reset_password.xml under res ⇒ layout.
reset_password.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp">

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/editEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp" >

        <com.google.android.material.textfield.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="@string/hint_email"
            android:inputType="textEmailAddress"
            android:padding="20dp"/>

    </com.google.android.material.textfield.TextInputLayout>

</LinearLayout>

4.2 Adding the Login Screen

My previous article Android Login and Registration with PHP & MySQL gives you a good and simple overview of Login and Registration System. 8. Create an XML file named activity_login.xml under res ⇒ layout.
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"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="10dp"
    android:gravity="center">

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/lTextEmail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp" >

        <com.google.android.material.textfield.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/lEditEmail"
            android:hint="@string/hint_email"
            android:inputType="textEmailAddress"
            android:padding="20dp"/>

    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/lTextPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp" >

        <com.google.android.material.textfield.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/lEditPassword"
            android:hint="@string/hint_password"
            android:inputType="textPassword"
            android:padding="20dp"/>

    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.button.MaterialButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/login"
        android:layout_marginTop="20dp"
        app:backgroundTint="@color/colorPrimary"
        android:textColor="@color/white"
        android:id="@+id/btnLogin"/>

    <com.google.android.material.button.MaterialButton
        style="@style/Widget.MaterialComponents.Button.TextButton"
        android:id="@+id/btnLinkToRegisterScreen"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="40dip"
        android:text="Register"
        android:textAllCaps="false"
        android:textColor="@color/colorPrimary"
        android:textSize="13sp" />

    <com.google.android.material.button.MaterialButton
        style="@style/Widget.MaterialComponents.Button.TextButton"
        android:id="@+id/btnForgotPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:text="Forgot Password"
        android:textAllCaps="false"
        android:textColor="@color/colorPrimary"
        android:textSize="13sp" />

</LinearLayout>
Android Login Screen Registration Screen 9. Create an activity class named LoginActivity.java.
LoginActivity.java
package org.snowcorp.login;

import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.textfield.TextInputLayout;

import org.json.JSONException;
import org.json.JSONObject;
import org.snowcorp.login.helper.DatabaseHandler;
import org.snowcorp.login.helper.Functions;
import org.snowcorp.login.helper.SessionManager;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Akshay Raj on 6/16/2016.
 * akshay@snowcorp.org
 * www.snowcorp.org
 */
public class LoginActivity extends AppCompatActivity {
    private static final String TAG = LoginActivity.class.getSimpleName();

    private static String KEY_UID = "uid";
    private static String KEY_NAME = "name";
    private static String KEY_EMAIL = "email";
    private static String KEY_CREATED_AT = "created_at";

    private MaterialButton btnLogin, btnLinkToRegister, btnForgotPass;
    private TextInputLayout inputEmail, inputPassword;
    private ProgressDialog pDialog;

    private SessionManager session;
    private DatabaseHandler db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        inputEmail = findViewById(R.id.lTextEmail);
        inputPassword = findViewById(R.id.lTextPassword);
        btnLogin = findViewById(R.id.btnLogin);
        btnLinkToRegister = findViewById(R.id.btnLinkToRegisterScreen);
        btnForgotPass = findViewById(R.id.btnForgotPassword);

        // Progress dialog
        pDialog = new ProgressDialog(this);
        pDialog.setCancelable(false);

        // create sqlite database
        db = new DatabaseHandler(getApplicationContext());

        // session manager
        session = new SessionManager(getApplicationContext());

        // check user is already logged in
        if (session.isLoggedIn()) {
            Intent i = new Intent(LoginActivity.this, HomeActivity.class);
            startActivity(i);
            finish();
        }

        // Hide Keyboard
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        init();
    }

    private void init() {
        // Login button Click Event
        btnLogin.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                // Hide Keyboard
                Functions.hideSoftKeyboard(LoginActivity.this);

                String email = inputEmail.getEditText().getText().toString().trim();
                String password = inputPassword.getEditText().getText().toString().trim();

                // Check for empty data in the form
                if (!email.isEmpty() && !password.isEmpty()) {
                    if (Functions.isValidEmailAddress(email)) {
                        // login user
                        loginProcess(email, password);
                    } else {
                        Toast.makeText(getApplicationContext(), "Email is not valid!", Toast.LENGTH_SHORT).show();
                    }
                } else {
                    // Prompt user to enter credentials
                    Toast.makeText(getApplicationContext(), "Please enter the credentials!", Toast.LENGTH_LONG).show();
                }
            }

        });

        // Link to Register Screen
        btnLinkToRegister.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                Intent i = new Intent(LoginActivity.this, RegisterActivity.class);
                startActivity(i);
            }
        });

        // Forgot Password Dialog
        btnForgotPass.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                forgotPasswordDialog();
            }
        });
    }

    private void forgotPasswordDialog() {
        final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
        LayoutInflater inflater = getLayoutInflater();
        View dialogView = inflater.inflate(R.layout.reset_password, null);

        dialogBuilder.setView(dialogView);
        dialogBuilder.setTitle("Forgot Password");
        dialogBuilder.setCancelable(false);

        final TextInputLayout mEditEmail = dialogView.findViewById(R.id.editEmail);

        dialogBuilder.setPositiveButton("Reset",  new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                // empty
            }
        });

        dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });

        final AlertDialog alertDialog = dialogBuilder.create();

        mEditEmail.getEditText().addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                if(mEditEmail.getEditText().getText().length() > 0){
                    alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
                } else {
                    alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
                }
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });

        alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
            @Override
            public void onShow(final DialogInterface dialog) {
                final Button b = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
                b.setEnabled(false);

                b.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        String email = mEditEmail.getEditText().getText().toString();

                        if (!email.isEmpty()) {
                            if (Functions.isValidEmailAddress(email)) {
                                resetPassword(email);
                                dialog.dismiss();
                            } else {
                                Toast.makeText(getApplicationContext(), "Email is not valid!", Toast.LENGTH_SHORT).show();
                            }
                        } else {
                            Toast.makeText(getApplicationContext(), "Fill all values!", Toast.LENGTH_SHORT).show();
                        }

                    }
                });
            }
        });

        alertDialog.show();
    }

    private void loginProcess(final String email, final String password) {
        // Tag used to cancel the request
        String tag_string_req = "req_login";

        pDialog.setMessage("Logging in ...");
        showDialog();

        StringRequest strReq = new StringRequest(Request.Method.POST,
                Functions.LOGIN_URL, new Response.Listener() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Login Response: " + response);
                hideDialog();

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    // Check for error node in json
                    if (!error) {
                        // user successfully logged in
                        JSONObject json_user = jObj.getJSONObject("user");

                        Functions logout = new Functions();
                        logout.logoutUser(getApplicationContext());

                        if(Integer.parseInt(json_user.getString("verified")) == 1){
                            db.addUser(json_user.getString(KEY_UID), json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json_user.getString(KEY_CREATED_AT));
                            Intent upanel = new Intent(LoginActivity.this, HomeActivity.class);
                            upanel.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(upanel);

                            session.setLogin(true);
                            finish();
                        } else {
                            Bundle b = new Bundle();
                            b.putString("email", email);
                            Intent upanel = new Intent(LoginActivity.this, EmailVerify.class);
                            upanel.putExtras(b);
                            upanel.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                            startActivity(upanel);
                            finish();
                        }

                    } else {
                        // Error in login. Get the error message
                        String errorMsg = jObj.getString("message");
                        Toast.makeText(getApplicationContext(), errorMsg, Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    // JSON error
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Login Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map getParams() {
                // Posting parameters to login url
                Map params = new HashMap();
                params.put("email", email);
                params.put("password", password);

                return params;
            }

        };

        // Adding request to request queue
        MyApplication.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void resetPassword(final String email) {
        // Tag used to cancel the request
        String tag_string_req = "req_reset_pass";

        pDialog.setMessage("Please wait...");
        showDialog();

        StringRequest strReq = new StringRequest(Request.Method.POST,
                Functions.RESET_PASS_URL, new Response.Listener() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Reset Password Response: " + response);
                hideDialog();

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    if (!error) {
                        Toast.makeText(getApplicationContext(), jObj.getString("message"), Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(getApplicationContext(), jObj.getString("message"), Toast.LENGTH_LONG).show();
                    }

                } catch (JSONException e) {
                    // JSON error
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Reset Password Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map getParams() {
                // Posting parameters to login url
                Map params = new HashMap<>();

                params.put("tag", "forgot_pass");
                params.put("email", email);

                return params;
            }

            @Override
            public Map getHeaders() throws AuthFailureError {
                Map params = new HashMap<>();
                params.put("Content-Type", "application/x-www-form-urlencoded");
                return params;
            }

        };

        // Adding request to volley request queue
        strReq.setRetryPolicy(new DefaultRetryPolicy(5 * DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, 0, 0));
        strReq.setRetryPolicy(new DefaultRetryPolicy(0, 0, 0));
        MyApplication.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void showDialog() {
        if (!pDialog.isShowing())
            pDialog.show();
    }

    private void hideDialog() {
        if (pDialog.isShowing())
            pDialog.dismiss();
    }
}

4.3 Adding the Email Verify Screen

10. Create an XML layout named activity_email_verify.xml under res ⇒ layout.
activity_email_verify.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"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="16dp">

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/verify_code"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="30dp">

        <com.google.android.material.textfield.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="20dp"
            android:hint="Verification Code"
            android:inputType="number"
            android:maxLength="6" />

    </com.google.android.material.textfield.TextInputLayout>

    <com.google.android.material.button.MaterialButton
        android:id="@+id/btnVerify"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:backgroundTint="@color/colorPrimary"
        android:textColor="@color/white"
        android:text="Verify"/>

    <com.google.android.material.button.MaterialButton
        style="@style/Widget.MaterialComponents.Button.TextButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:textColor="@color/borderless_button"
        android:text="Resend Code"
        android:id="@+id/btnResendCode" />

    <TextView
        android:id="@+id/otpCountDown"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:gravity="center"/>

</LinearLayout>
Email Verify 11. Create an activity class named EmailVerify.java db.addUser() – Will insert the user in SQLite database once he is successfully verified his Email.
EmailVerify.java
package org.snowcorp.login;

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.textfield.TextInputLayout;

import org.json.JSONException;
import org.json.JSONObject;
import org.snowcorp.login.helper.DatabaseHandler;
import org.snowcorp.login.helper.Functions;
import org.snowcorp.login.helper.SessionManager;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Created by Akshay Raj on 06-02-2017.
 * akshay@snowcorp.org
 * www.snowcorp.org
 */
public class EmailVerify extends AppCompatActivity {
    private static final String TAG = EmailVerify.class.getSimpleName();

    private TextInputLayout textVerifyCode;
    private MaterialButton btnVerify, btnResend;
    private TextView otpCountDown;

    private SessionManager session;
    private DatabaseHandler db;
    private ProgressDialog pDialog;

    private static final String FORMAT = "%02d:%02d";

    Bundle bundle;

    private static String KEY_UID = "uid";
    private static String KEY_NAME = "name";
    private static String KEY_EMAIL = "email";
    private static String KEY_CREATED_AT = "created_at";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_email_verify);

        textVerifyCode = findViewById(R.id.verify_code);
        btnVerify = findViewById(R.id.btnVerify);
        btnResend = findViewById(R.id.btnResendCode);
        otpCountDown = findViewById(R.id.otpCountDown);

        bundle = getIntent().getExtras();

        db = new DatabaseHandler(getApplicationContext());
        session = new SessionManager(getApplicationContext());

        pDialog = new ProgressDialog(this);
        pDialog.setCancelable(false);

        // Hide Keyboard
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        init();
    }

    private void init() {
        btnVerify.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Hide Keyboard
                Functions.hideSoftKeyboard(EmailVerify.this);

                String email = bundle.getString("email");
                String otp = textVerifyCode.getEditText().getText().toString();
                if (!otp.isEmpty()) {
                    verifyCode(email, otp);
                    textVerifyCode.setErrorEnabled(false);
                } else {
                    textVerifyCode.setError("Please enter verification code");
                }
            }
        });

        btnResend.setEnabled(false);
        btnResend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String email = bundle.getString("email");
                resendCode(email);
            }
        });

        countDown();
    }

    private void countDown() {
        new CountDownTimer(70000, 1000) { // adjust the milli seconds here

            @SuppressLint({"SetTextI18n", "DefaultLocale"})
            public void onTick(long millisUntilFinished) {
                otpCountDown.setVisibility(View.VISIBLE);
                otpCountDown.setText(""+String.format(FORMAT,
                        TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished),
                        TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(
                                TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished)) ));
            }

            public void onFinish() {
                otpCountDown.setVisibility(View.GONE);
                btnResend.setEnabled(true);
            }
        }.start();
    }

    private void verifyCode(final String email, final String otp) {
        // Tag used to cancel the request
        String tag_string_req = "req_verify_code";

        pDialog.setMessage("Checking in ...");
        showDialog();

        StringRequest strReq = new StringRequest(Request.Method.POST,
                Functions.OTP_VERIFY_URL, new Response.Listener() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Verification Response: " + response);
                hideDialog();

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    // Check for error node in json
                    if (!error) {
                        JSONObject json_user = jObj.getJSONObject("user");

                        Functions logout = new Functions();
                        logout.logoutUser(getApplicationContext());
                        db.addUser(json_user.getString(KEY_UID), json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json_user.getString(KEY_CREATED_AT));
                        session.setLogin(true);
                        Intent upanel = new Intent(EmailVerify.this, HomeActivity.class);
                        upanel.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        startActivity(upanel);
                        finish();

                    } else {
                        Toast.makeText(getApplicationContext(), "Invalid Verification Code", Toast.LENGTH_LONG).show();
                        textVerifyCode.setError("Invalid Verification Code");
                    }
                } catch (JSONException e) {
                    // JSON error
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Verify Code Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map getParams() {
                // Posting parameters to login url
                Map params = new HashMap<>();

                params.put("tag", "verify_code");
                params.put("email", email);
                params.put("otp", otp);

                return params;
            }

            @Override
            public Map getHeaders() throws AuthFailureError {
                Map params = new HashMap();
                params.put("Content-Type","application/x-www-form-urlencoded");
                return params;
            }

        };
        // Adding request to request queue
        MyApplication.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void resendCode(final String email) {
        // Tag used to cancel the request
        String tag_string_req = "req_resend_code";

        pDialog.setMessage("Resending code ...");
        showDialog();

        StringRequest strReq = new StringRequest(Request.Method.POST,
                Functions.OTP_VERIFY_URL, new Response.Listener() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Resend Code Response: " + response);
                hideDialog();

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    // Check for error node in json
                    if (!error) {
                        Toast.makeText(getApplicationContext(), "Code successfully sent to your email!", Toast.LENGTH_LONG).show();
                        btnResend.setEnabled(false);
                        countDown();
                    } else {
                        Toast.makeText(getApplicationContext(), "Code sending failed!", Toast.LENGTH_LONG).show();
                    }
                } catch (JSONException e) {
                    // JSON error
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), "Json error: " + e.getMessage(), Toast.LENGTH_LONG).show();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Resend Code Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map getParams() {
                // Posting parameters to login url
                Map params = new HashMap();

                params.put("tag", "resend_code");
                params.put("email", email);

                return params;
            }

            @Override
            public Map getHeaders() throws AuthFailureError {
                Map params = new HashMap();
                params.put("Content-Type","application/x-www-form-urlencoded");
                return params;
            }

        };
        // Adding request to request queue
        MyApplication.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void showDialog() {
        if (!pDialog.isShowing())
            pDialog.show();
    }

    private void hideDialog() {
        if (pDialog.isShowing())
            pDialog.dismiss();
    }

    @Override
    public void onResume(){
        super.onResume();
        countDown();
    }
}

4.4 Adding the Home Screen

Until now we are done with login, registration and email verify screen. Now we’ll add the final screen to show the logged in user information. This information will be fetched from SQLite database once user is logged in. Here are two buttons for logout for destroy current session and change password for change old password. 12. Create an xml file named activity_home.xml under res ⇒ layout and add below code.
activity_home.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="20dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="top|center">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/welcome"
            android:textSize="20sp" />

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:textSize="24sp" />

        <TextView
            android:id="@+id/email"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="13sp"/>

    </LinearLayout>

    <com.google.android.material.button.MaterialButton
        android:id="@+id/change_password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/logout"
        android:layout_marginBottom="10dp"
        app:backgroundTint="@color/colorPrimary"
        android:text="@string/change_password"
        android:textColor="@color/white"/>

    <com.google.android.material.button.MaterialButton
        android:id="@+id/logout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        app:backgroundTint="#F44336"
        android:text="@string/logout"
        android:textColor="@color/white"/>

</RelativeLayout>
Home Screen 13. Open the HomeActivity.java and do below changes. Here we are just fetching the logged user information from SQLite and displaying it on the screen. The logout button will logout the user by clearing the session and deleting the user from SQLite table and Change Password button for changing current password.
HomeActivity.java
package org.snowcorp.login;

import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.textfield.TextInputLayout;

import org.json.JSONException;
import org.json.JSONObject;
import org.snowcorp.login.helper.DatabaseHandler;
import org.snowcorp.login.helper.Functions;
import org.snowcorp.login.helper.SessionManager;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Akshay Raj on 6/16/2016.
 * akshay@snowcorp.org
 * www.snowcorp.org
 */
public class HomeActivity extends AppCompatActivity {
    private static final String TAG = HomeActivity.class.getSimpleName();

    private TextView txtName, txtEmail;
    private MaterialButton btnChangePass, btnLogout;
    private SessionManager session;
    private DatabaseHandler db;

    private ProgressDialog pDialog;

    private HashMap user = new HashMap<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);

        txtName = findViewById(R.id.name);
        txtEmail = findViewById(R.id.email);
        btnChangePass = findViewById(R.id.change_password);
        btnLogout = findViewById(R.id.logout);

        // Progress dialog
        pDialog = new ProgressDialog(this);
        pDialog.setCancelable(false);

        db = new DatabaseHandler(getApplicationContext());
        user = db.getUserDetails();

        // session manager
        session = new SessionManager(getApplicationContext());

        if (!session.isLoggedIn()) {
            logoutUser();
        }

        // Fetching user details from database
        String name = user.get("name");
        String email = user.get("email");

        // Displaying the user details on the screen
        txtName.setText(name);
        txtEmail.setText(email);

        // Hide Keyboard
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        init();
    }

    private void init() {
        btnLogout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                logoutUser();
            }
        });

        btnChangePass.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(HomeActivity.this);
                LayoutInflater inflater = getLayoutInflater();
                View dialogView = inflater.inflate(R.layout.change_password, null);

                dialogBuilder.setView(dialogView);
                dialogBuilder.setTitle("Change Password");
                dialogBuilder.setCancelable(false);

                final TextInputLayout oldPassword = dialogView.findViewById(R.id.old_password);
                final TextInputLayout newPassword = dialogView.findViewById(R.id.new_password);

                dialogBuilder.setPositiveButton("Change",  new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // empty
                    }
                });

                dialogBuilder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });

                final AlertDialog alertDialog = dialogBuilder.create();

                TextWatcher textWatcher = new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    }

                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {
                        if(oldPassword.getEditText().getText().length() > 0 &&
                                newPassword.getEditText().getText().length() > 0){
                            alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
                        } else {
                            alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
                        }
                    }

                    @Override
                    public void afterTextChanged(Editable s) {
                    }
                };

                oldPassword.getEditText().addTextChangedListener(textWatcher);
                newPassword.getEditText().addTextChangedListener(textWatcher);

                alertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
                    @Override
                    public void onShow(final DialogInterface dialog) {
                        final Button b = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
                        b.setEnabled(false);

                        b.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                String email = user.get("email");
                                String old_pass = oldPassword.getEditText().getText().toString();
                                String new_pass = newPassword.getEditText().getText().toString();

                                if (!old_pass.isEmpty() && !new_pass.isEmpty()) {
                                    changePassword(email, old_pass, new_pass);
                                    dialog.dismiss();
                                } else {
                                    Toast.makeText(getApplicationContext(), "Fill all values!", Toast.LENGTH_SHORT).show();
                                }

                            }
                        });
                    }
                });

                alertDialog.show();
            }
        });
    }

    private void logoutUser() {
        session.setLogin(false);
        // Launching the login activity
        Functions logout = new Functions();
        logout.logoutUser(getApplicationContext());
        Intent intent = new Intent(HomeActivity.this, LoginActivity.class);
        startActivity(intent);
        finish();
    }

    private void changePassword(final String email, final String old_pass, final String new_pass) {
        // Tag used to cancel the request
        String tag_string_req = "req_reset_pass";

        pDialog.setMessage("Please wait...");
        showDialog();

        StringRequest strReq = new StringRequest(Request.Method.POST,
                Functions.RESET_PASS_URL, new Response.Listener() {

            @Override
            public void onResponse(String response) {
                Log.d(TAG, "Reset Password Response: " + response);
                hideDialog();

                try {
                    JSONObject jObj = new JSONObject(response);
                    boolean error = jObj.getBoolean("error");

                    if (!error) {
                        Toast.makeText(getApplicationContext(), jObj.getString("message"), Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(getApplicationContext(), jObj.getString("message"), Toast.LENGTH_LONG).show();
                    }

                } catch (JSONException e) {
                    // JSON error
                    e.printStackTrace();
                    Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
                }

            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e(TAG, "Reset Password Error: " + error.getMessage());
                Toast.makeText(getApplicationContext(), error.getMessage(), Toast.LENGTH_LONG).show();
                hideDialog();
            }
        }) {

            @Override
            protected Map getParams() {
                // Posting parameters to login url
                Map params = new HashMap<>();

                params.put("tag", "change_pass");
                params.put("email", email);
                params.put("old_password", old_pass);
                params.put("password", new_pass);

                return params;
            }

            @Override
            public Map getHeaders() throws AuthFailureError {
                Map params = new HashMap<>();
                params.put("Content-Type", "application/x-www-form-urlencoded");
                return params;
            }

        };

        // Adding request to volley request queue
        strReq.setRetryPolicy(new DefaultRetryPolicy(5 * DefaultRetryPolicy.DEFAULT_TIMEOUT_MS, 0, 0));
        strReq.setRetryPolicy(new DefaultRetryPolicy(0, 0, 0));
        MyApplication.getInstance().addToRequestQueue(strReq, tag_string_req);
    }

    private void showDialog() {
        if (!pDialog.isShowing())
            pDialog.show();
    }

    private void hideDialog() {
        if (pDialog.isShowing())
            pDialog.dismiss();
    }

}

4.5 Some Important Functions

1. Email Address Validation
public static boolean isValidEmailAddress(String email) {
    String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$";
    java.util.regex.Pattern p = java.util.regex.Pattern.compile(ePattern);
    java.util.regex.Matcher m = p.matcher(email);
    return m.matches();
}
2. Hide Soft Keyboard
public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager =
            (InputMethodManager) activity.getSystemService(
                    Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(
            activity.getCurrentFocus().getWindowToken(), 0);
}

5. Testing the App

For a beginner it will be always difficult to run this project for the first time. But don’t worry, the following steps will helps you testing this app. (The ip address looks like 192.168.225.46) ⇒ Make sure that both devices (the device running the PHP project and the android device) are on the same wifi network. ⇒ Give correct username , password and database name of MySQL in config.php ⇒ Replace the URL ip address of MAIN_URL in AppConfig.java with your machine ip address. You can get the ip address by running ipconfig in cmd

6. Download Complete Project

You can download complete project at Github

Download Project

Enter your email to unlock the download.

Tags

#android#forgot password#login#mysql#otp#php#register#reset password#sqlite#verify password#volley

Comments

pramod•Mar 22, 2017
good
1 reply
Akshay Raj•Mar 22, 2017
Thank You :)
1 reply
musa•Jan 31, 2018
hi i can&#8217;t connect to the mail server n
2 replies
Akshay Raj•Jan 31, 2018
Use real server not local server
3 replies
musa•Jan 31, 2018
can please give me an example of how to do that am using this for my final year project thank you.
1 reply
Akshay Raj•Jan 31, 2018
Upload your project to any web hosting then try
musa•Jan 31, 2018
OK thanks very much let me try that ,i will get back to you if i run in any error.Is that ok?
1 reply
Akshay Raj•Jan 31, 2018
Ok..you can message me at my facebook (@akrajilwar )
musa•Jan 31, 2018
great :)
musa•Jan 31, 2018
this is the error :"Warning: mail(): Failed to connect to mailserver at &quot;localhost&quot; port 25, verify your &quot;SMTP&quot; and &quot;smtp_port&quot; setting in php.ini or use ini_set() in C:\xampp\htdocs\android_login\register.php on line 71n {"error":false,"message":"Register successful!"}"
1 reply
Akshay Raj•Jan 31, 2018
mail() function not work in local server (wamp server). Try with real server
alireza•Jul 23, 2017
where can i find your login.php file? you do not mention it
1 reply
Akshay Raj•Jul 24, 2017
Check my source code on GitHub with this link https://github.com/akrajilwar/Android-Login-And-Registration
Latha•Dec 18, 2017
Hey, im getting error..n“Json error: Value
1 reply
Akshay Raj•Dec 19, 2017
send me full log
edy•Dec 19, 2017
I have nothing in my email when asking verify code, whats wrong?
1 reply
Akshay Raj•Dec 19, 2017
did you try with online server?
edy•Dec 19, 2017
im using wampserver installed on my laptop and internet connected by wifi, for url i used ip address 192.168.1.2:8080 (refer to ipconfig). but when i try to RESEND CODE i got error message Json error:value
1 reply
Akshay Raj•Dec 19, 2017
If you want to test mail function then you need online server
edy•Dec 19, 2017
i mean i got error message "Json error:value "
1 reply
Akshay Raj•Dec 19, 2017
Add two slash (//) before mail() function for testing. You can get verification code from phpmyadmin and if you want to try mail function then add your project to online server and remove slash from mail function
2 replies
edy•Dec 20, 2017
Thanks a lot for your assist
Muibi Azeez Abolade•Jun 12, 2020
Where will I add that

Enjoyed this article?

Subscribe to our newsletter to get more articles like this delivered to your inbox.