User registration in Android, Java, PHP, and MySQL

User registration is used in almost every android app today.

We will create a registration form in an android application using Java. And when the form is submitted, we will send an HTTP request from android to the PHP server that will save the user’s data in the MySQL database.

MySQL table structure

Following will be the table structure for users table:

--
-- Table structure for table `users`
--

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `name` text NOT NULL,
  `username` text NOT NULL,
  `password` text NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Indexes for table `users`
--
ALTER TABLE `users`
  ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

Users table will have a unique ID that will be used to uniquely identify the user in the whole users table. We are adding a “primary key” index to the ID field. And also an “AUTO_INCREMENT” that will automatically generate the next ID number. For example, if there are 4 users already registered and a new user tries to register, then the MySQL database will automatically assign his ID to 5.

User registration in android – Layout

Now come to the android part. First, we will be creating a layout for the registration form. To keep the things simple, we are using name, username, and password in the registration form:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_login"
    android:paddingLeft="36dp"
    android:paddingTop="15dp"
    android:paddingRight="36dp">

    <ImageView
        android:id="@+id/logo"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerHorizontal="true"
        android:src="@drawable/logo" />

    <TextView
        android:id="@+id/tv_Signup"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/logo"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:text="Create an account"
        android:textColor="#ffffff"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tv_Signup"
        android:backgroundTint="@android:color/white"
        android:hint="Full Name"
        android:inputType="text|textCapWords"
        android:maxLines="1"
        android:textColor="#ffffff"
        android:textColorHint="#ffffff" />

    <EditText
        android:id="@+id/username"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/name"
        android:backgroundTint="@android:color/white"
        android:digits="qwertyuiopasdfghjklzxcvbnm1234567890"
        android:hint="Username"
        android:inputType="text"
        android:maxLines="1"
        android:textColor="#ffffff"
        android:textColorHint="#ffffff" />

    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/password"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/username"
        android:backgroundTint="@android:color/white"
        android:drawablePadding="5dp"
        android:hint="Password"
        android:inputType="textPassword"
        android:maxLines="1"
        android:textColor="#ffffff"
        android:textColorHint="#ffffff"
        android:textCursorDrawable="@null" />

    <Button
        android:id="@+id/btn_register"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_below="@+id/password"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:text="Register" />

    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btn_login"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp" />
</RelativeLayout>

In android, dp – Density-independent Pixels – is an abstract unit that is based on the physical density of the screen. These units are relative to a 160 dpi screen, so one dp is one pixel on a 160 dpi screen. The ratio of dp-to-pixel will change with the screen density, but not necessarily in direct proportion.

  1. <RelativeLayout> it will have full width and height to the screen, has an image as background (as in the screenshot). Will have padding from left (36dp), right (36dp), and top (15dp).
  2. <ImageView> to display the logo of the app or company. It has 100dp widths and 100dp height
  3. <TextView> to display the heading of the page.
  4. <EditText> is the input field for name. It will be below the heading. Its text will be in white color. Each word will be capitalized.
  5. Second <EditText> is for username. It will be below the name field. You can only write a-z and 0-9 digits, no special characters will be allowed.
  6. <android.support.v7.widget.AppCompatEditText> this field is for password. User cannot see the text entered in this field.
  7. <Button> which when clicked will submit the form and send an HTTP request to PHP server to store that data in MySQL database.
  8. Finally a <ProgressBar> to display a loading circle when the request is sent to the server. And will be hidden when the response is received from the server.

Call HTTP request – Volley

In your app/build.gradle, make sure to add Volley dependency:

dependencies {
    ....

    implementation 'com.android.volley:volley:1.1.1'
}

Now in your register activity’s onCreate method paste the following code. We will explain that line-by-line:

ProgressBar progressBar = findViewById(R.id.progressBar);
progressBar.setVisibility(View.GONE);

EditText username = findViewById(R.id.username);
EditText password = findViewById(R.id.password);
EditText name = findViewById(R.id.name);

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

        String usernameText = username.getText().toString().trim();
        String passwordText = password.getText().toString().trim();
        String nameText = name.getText().toString().trim();

        if (!usernameText.isEmpty() && !passwordText.isEmpty() && !nameText.isEmpty()) {

            progressBar.setVisibility(View.VISIBLE);
            btn_register.setEnabled(false);

            String url = "http://localhost/tutorials/Http.php";
            // Instantiate the RequestQueue.
            RequestQueue queue = Volley.newRequestQueue(this);

            // Request a string response from the provided URL.
            StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
                    new Response.Listener<String>() {
                        @Override
                        public void onResponse(String response) {
                            try {
                                JSONObject responseJson = new JSONObject(response);
                                String status = responseJson.getString("status");
                                String message = responseJson.getString("message");

                                Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();

                                progressBar.setVisibility(View.GONE);
                                btn_register.setEnabled(true);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }, new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();
                    Toast.makeText(getApplicationContext(), error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                }
            }) {
                @Override
                protected Map<String, String> getParams() {
                    Map<String, String> params = new HashMap<>();
                    params.put("name", name.getText().toString().trim());
                    params.put("username", username.getText().toString().trim());
                    params.put("password", password.getText().toString().trim());
                    params.put("registration", "1");

                    return params;
                }

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

            // To prevent timeout error
            stringRequest.setRetryPolicy(new DefaultRetryPolicy(50000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));

            // Add the request to the RequestQueue.
            stringRequest.setShouldCache(false);
            queue.add(stringRequest);

        } else {
            Toast.makeText(getApplicationContext(), "Please fill all details", Toast.LENGTH_LONG).show();
        }
    }
});
  1. First, we are creating an instance of ProgressBar and hiding it by default. We will only display when the request is sent.
  2. Then we are getting the name, username, and password input fields objects.
  3. After that, we are checking if any of the fields are empty, then display an error in Toast.
  4. Now, we are displaying the progress bar and disabling register button, so the user cannot click multiple times.
  5. Then we are sending a request using Volley. The request method should be POST.
  6. getParams() will have all our parameters. We are sending a name, username, and password along with an additional value “registration” that will be used to tell the server to handle the request for registration.
  7. Response received from the server will be a JSON string, so we are converting that into JSONObject, and displaying server response message in a Toast.
  8. And finally, we are hiding the progress bar and enable the register button again. So if there is any error, then the user can click on the register button again.

Save user data in MySQL using PHP

Now come to the server-side. As you see we are sending the request to Http.php so we must have that file in our server. This file should have the following content, we will explain that line-by-line:

<?php

ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

$conn = mysqli_connect("localhost", "root", "root", "tutorials");

if (isset($_POST["registration"]))
{
    $username = $_POST["username"];
    $name = $_POST["name"];

    $sql = "SELECT * FROM `users` WHERE `username` = '" . $username . "'";
    $result = mysqli_query($conn, $sql);

    if (mysqli_num_rows($result) > 0)
    {
        echo json_encode(array(
            "status" => "error",
            "message" => "Username already exists"
        ));
        exit();
    }

    $password = password_hash($_POST["password"], PASSWORD_DEFAULT);

    $sql = "INSERT INTO `users`(`name`, `username`, `password`) VALUES ('" . $name . "', '" . $username . "', '" . $password . "')";
    mysqli_query($conn, $sql);

    echo json_encode(array(
        "status" => "success",
        "message" => "Account has been created",
        "user_id" => mysqli_insert_id($conn) . ""
    ));
    exit();
}
  1. First, we are enabling all PHP errors. So if there is any error it will be received in error response in the android app.
  2. Then we are connecting with the database using host: port, username, password, and database name respectively.
  3. After that, we are checking if the request received is for registration, then get the name, username, and password fields from a POST request.
  4. Now, check from the database if the user with the same username already exists in the user’s table, if yes, then send an error response and stop the script using exit() function.
  5. Then convert the plain text password into an encrypted hash, so even if your database got hacked, no one will know the actual password of your users.
  6. And finally, run an INSERT query to save the database in MySQL database and send the success response back to the android app.
  7. We are also sending the inserted ID in response. So if you want to use the newly inserted ID in the MySQL table, you can get it from mysqli_insert_id function and passing the connection as a parameter.

User registration has been done in your android project. You can also learn how to authenticate the user for login and save his data in android Shared Preferences.

AJAX file upload with progress bar – Javascript, PHP

In this tutorial, we are going to show you how you can upload file with AJAX. We will also be displaying a progress bar. We will be using PHP.

AJAX file upload with progress bar

There are 2 types of progress bars, one with infinite progress loop similar to this:

and one which shows the number of percentage completed like this:

We will be using the 2nd progress bar as it is more accurate than the first one.

Select file

We will be using an AJAX function to upload user selected file on the server and show the progress bar of how much the file has been uploaded. We will be creating just 2 files, 1 for client (index.php) and 1 for server (upload.php). So, start off by creating a simple HTML form in file index.php:

<form method="POST" enctype="multipart/form-data" onsubmit="return onSubmit();">
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" />
</form>
  • enctype=”multipart/form-data” and method=”POST” are important in <form> tag to upload file.

Prevent form from submitting

In order to upload file via AJAX, first we need to stop the default form action method. We can do this by return false from onsubmit attribute of <form> tag. All the code written in this tutorial is pure Javascript, there is no dependency of jQuery in this tutorial.

<script>
    function onSubmit() {
        return false;
    }
</script>

Get input type file in Javascript

Now, you have to get the user selected file and save it in a variable called file. document.getElementById(“file”) helps in getting the input type file object and it has an array of user selected files in a variable called files.

function onSubmit() {
    var file = document.getElementById("file").files[0];
    return false;
}

Call AJAX to upload file

To call an AJAX to upload the file, first create an built-in XMLHttpRequest object and save in variable ajax. This object is supported in all browsers and it is native Javascript object, no jQuery is required.

var ajax = new XMLHttpRequest();

Now call open(method, url, async) function from ajax object.

  • First parameter is the method of request GET or POST.
  • Second is the name of PHP file which will upload the file. In this case upload.php which will be created in next step.
  • Third is a boolean, whether the request is asynchronous or not. true for asynchronous. Asynchronous requests does not hang up the browser. Syncronized requests may block the browser if the script at upload.php is very time-taking.
ajax.open("POST", "upload.php", true);

Sending file via AJAX required an FormData object to be appended in the AJAX request. We can create a FormData object simply by the following line:

var formData = new FormData();
formData.append("file", file);
  • formData.append 1st parameter is the string which will used in upload.php file to upload the file and 2nd parameter is the user selected file. In this case, it is stored in variable file

Call the send() function from ajax object to actually call an AJAX request. It accepts 1 parameter that is of FormData object.

ajax.send(formData);

When response is received from server

ajax object has multiple functions that are called once the status of request is changed. For example, when server receives the request, if server does not exists, if server failed to respond etc. All these callbacks are received in a function called onreadystatechange.

ajax.onreadystatechange = function() {
    //
};

Now we have to respond only if the request is successful. In this onreadystatechange function, we have 3 variables readyState, status and responseText.

  • readyState will have value 4 when the request is done/completed.
  • status will have value 200 when everything goes right.
ajax.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
    	console.log(this.responseText);
    }
};

Save file on server – PHP

Now create a new file named upload.php and open it in code editor. In this file, we will just be storing the file in a server. Paste the following code in upload.php file:

<?php
    move_uploaded_file($_FILES["file"]["tmp_name"], $_FILES["file"]["name"]);
    echo "Done";
?>

At this point if you run the index.php file, you will be able to select a file and save it in your server and your index.php will look like this:

<form method="POST" enctype="multipart/form-data" onsubmit="return onSubmit();">
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" />
</form>

<script>
    function onSubmit() {
        var file = document.getElementById("file").files[0];

        var formData = new FormData();
        formData.append("file", file);
        
        var ajax = new XMLHttpRequest();
        ajax.open("POST", "upload.php", true);
        ajax.send(formData);

        ajax.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                console.log(this.responseText);
            }
        };

        return false;
    }
</script>

And your upload.php should look like this:

<?php
    move_uploaded_file($_FILES["file"]["tmp_name"], $_FILES["file"]["name"]);
    echo "Done";
?>

Show progress bar

Now, in order to view the progress bar you can simply create an <progress> tag anywhere in your index.php where you want to see the progress. Provide it a unique id and set it’s initial value to 0:

<progress id="progress" value="0"></progress>

Get progress bar object in javascript, right above return false; line in the function onSubmit(), like this:

function onSubmit() {
    ..........

    ajax.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 200) {
            console.log(this.responseText);
        }
    };

    var progress = document.getElementById("progress");
    return false;
}

While uploading files, ajax object also has an event called onprogress that will tell the current uploaded file percentage:

ajax.upload.onprogress = function (event) {
    //
};
  • event variable will tell the current status of uploaded file.

First you have to set the maximum value of progress object to that required by an AJAX request to upload the file:

progress.max = event.total;

Now simply set the progress value attribute to uploaded value from event object:

progress.value = event.loaded;

Now, you will be able to view the progress of an uploaded file via AJAX.

Complete code

Here is a complete code of your index.php file:

<form method="POST" enctype="multipart/form-data" onsubmit="return onSubmit();">
    <input type="file" name="file" id="file" />
    <input type="submit" name="submit" />
</form>

<progress id="progress" value="0"></progress>

<script>
    function onSubmit() {
        var file = document.getElementById("file").files[0];

        var formData = new FormData();
        formData.append("file", file);
        
        var ajax = new XMLHttpRequest();
        ajax.open("POST", "upload.php", true);
        ajax.send(formData);

        ajax.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                console.log(this.responseText);
            }
        };

        var progress = document.getElementById("progress");
        ajax.upload.onprogress = function (event) {
            progress.max = event.total;
            progress.value = event.loaded;
        };

        return false;
    }
</script>

Show progress of download with remaining time – Javascript

[wpdm_package id=’104′]