Android Login and Registration are very common scenarios. You will find registration and login operation in all the apps where we want user information. In this tutorial, we’ll set up a local web server and MySQL database. We will develop android login and registration application. We will use PHP script to connect to the MySQL database.
The first step is to create the backend web server. I am working on Mac OS X and XAMPP can be used to set up a local Apache web server and MySQL database quickly.
XAMPP(or WAMP) is a one-click installer software that creates an environment for developing a PHP, MySQL web application (that we’ll be connecting with our android application). Download and install XAMPP from here. Launch the XAMPP app after installation and you will be greeted with below screen. You can test your server by opening https://localhost
. The following screen should appear. Also, you can check phpMyAdmin by opening https://localhost/phpmyadmin
. Let’s see what it shows! OOPS! You might end up with a screen like this. Seems like the MySQL server isn’t properly running. Go To the Manage Servers tab in the XAMPP application and click restart all. The servers should be running properly as seen in the image below. Now test phpMyAdmin in the localhost and you’ll end up with a screen similar to this. Now let’s test a sample php script. Create a new test.php
file and add the following lines into it.
<?php
echo "Hello, World";
?>
In the above code:
Note: Knowing PHP is not mandatory for this tutorial. if you’re using a MAC then goto Applications->Xampp->htdocs. Create a new folder here lets say test_android and copy paste the test.php that was created before. Now open the url https://localhost/test_android/test.php
You’ll end up with a screen like this:
Open the phpMyAdmin by visiting https://localhost/phpmyadmin
. Now select the Databases Tab that’s present in the top left of the headers row. Give a random name and create it. The newly created empty database would be visible in the left sidebar. Let’s create a users table in the newly created Database. Run the following query in the console
CREATE TABLE `firstDB`.`users` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 20 ) NOT NULL ,
`password` VARCHAR( 20 ) NOT NULL
)
If the table is successfully created, you’ll end up with a screen similar to this:
To connect a PHP script to MySQL database three input values are required. Following are the inputs and there default values for a XAMPP server
Let’s create a test-connect.php script and add it in the htdocs->test-android folder.
<?php
$host="localhost";
$user="root";
$password="";
$con=mysql_connect($host,$user,$password);
if($con) {
echo '<h1>Connected to MySQL</h1>';
} else {
echo '<h1>MySQL Server is not connected</h1>';
}
?>
mysql_connect() is a PHP’s inbuilt function to connect to MySQL database with the parameters listed above. Try running https://localhost/test_android/test-connect.php
and see the output. If it’s not connected, then try restarting the XAMPP servers.
Now that we’ve discussed the basic setup of PHP and MySQL, let’s get into the android login application part. We’ll be developing a sign-in/register application. To keep it short and simple we’ll be checking if the username and email are unique during registration. Before we jump onto the app logic let’s work on the PHP scripts and MySQL Database. First, let’s DROP the Table users and create a fresh one in the context of the above application.
CREATE TABLE IF NOT EXISTS `firstDB`.`users` (
`id` int(20) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`username` varchar(70) NOT NULL,
`password` varchar(40) NOT NULL,
`email` varchar(50) NOT NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime DEFAULT NULL
)
Following are the PHP scripts that you can copy paste in the htdocs->test_android folder. config.php
<?php
define("DB_HOST", "localhost");
define("DB_USER", "root");
define("DB_PASSWORD", "");
define("DB_NAME", "firstDB");
?>
The script for Database connection is given below. db-connect.php
<?php
include_once 'config.php';
class DbConnect{
private $connect;
public function __construct(){
$this->connect = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if (mysqli_connect_errno($this->connect)){
echo "Unable to connect to MySQL Database: " . mysqli_connect_error();
}
}
public function getDb(){
return $this->connect;
}
}
?>
The following script contains all the core functions of the application. user.php
<?php
include_once 'db-connect.php';
class User{
private $db;
private $db_table = "users";
public function __construct(){
$this->db = new DbConnect();
}
public function isLoginExist($username, $password){
$query = "select * from ".$this->db_table." where username = '$username' AND password = '$password' Limit 1";
$result = mysqli_query($this->db->getDb(), $query);
if(mysqli_num_rows($result) > 0){
mysqli_close($this->db->getDb());
return true;
}
mysqli_close($this->db->getDb());
return false;
}
public function isEmailUsernameExist($username, $email){
$query = "select * from ".$this->db_table." where username = '$username' AND email = '$email'";
$result = mysqli_query($this->db->getDb(), $query);
if(mysqli_num_rows($result) > 0){
mysqli_close($this->db->getDb());
return true;
}
return false;
}
public function isValidEmail($email){
return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}
public function createNewRegisterUser($username, $password, $email){
$isExisting = $this->isEmailUsernameExist($username, $email);
if($isExisting){
$json['success'] = 0;
$json['message'] = "Error in registering. Probably the username/email already exists";
}
else{
$isValid = $this->isValidEmail($email);
if($isValid)
{
$query = "insert into ".$this->db_table." (username, password, email, created_at, updated_at) values ('$username', '$password', '$email', NOW(), NOW())";
$inserted = mysqli_query($this->db->getDb(), $query);
if($inserted == 1){
$json['success'] = 1;
$json['message'] = "Successfully registered the user";
}else{
$json['success'] = 0;
$json['message'] = "Error in registering. Probably the username/email already exists";
}
mysqli_close($this->db->getDb());
}
else{
$json['success'] = 0;
$json['message'] = "Error in registering. Email Address is not valid";
}
}
return $json;
}
public function loginUsers($username, $password){
$json = array();
$canUserLogin = $this->isLoginExist($username, $password);
if($canUserLogin){
$json['success'] = 1;
$json['message'] = "Successfully logged in";
}else{
$json['success'] = 0;
$json['message'] = "Incorrect details";
}
return $json;
}
}
?>
In the above code, the $json contains the JSONObjects returned. The following PHP script is the one that is called upon first from the application. index.php
<?php
require_once 'user.php';
$username = "";
$password = "";
$email = "";
if(isset($_POST['username'])){
$username = $_POST['username'];
}
if(isset($_POST['password'])){
$password = $_POST['password'];
}
if(isset($_POST['email'])){
$email = $_POST['email'];
}
$userObject = new User();
// Registration
if(!empty($username) && !empty($password) && !empty($email)){
$hashed_password = md5($password);
$json_registration = $userObject->createNewRegisterUser($username, $hashed_password, $email);
echo json_encode($json_registration);
}
// Login
if(!empty($username) && !empty($password) && empty($email)){
$hashed_password = md5($password);
$json_array = $userObject->loginUsers($username, $hashed_password);
echo json_encode($json_array);
}
?>
In the above code, we check whether the email field is empty or not. If it is, we’ll call the login function in the PHP script, else we’ll go to the registration function. The JSON response returns two params : success(0 or 1) and the message.
md5()
function uses the RSA Data Security, Inc. MD5 Message-Digest Algorithm to create a hash string of the password.isValidEmail()
method. FILTER_VALIDATE_EMAIL works on PHP versions 5.2.0+In this project, we’ve used three libs for implementing the HTTP Calls in our application. The JSONParser class is used for doing the POST and GET HTTP Calls to the localhost and returning the response in the form of a JSONObject.
The activity_main.xml
layout is defined below.
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="https://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:paddingLeft="24dp"
android:paddingRight="24dp"
android:id="@+id/linearLayout">
<EditText android:id="@+id/editName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username"
android:textColor="#FF192133"
android:textColorHint="#A0192133"
android:fontFamily="sans-serif-light"
android:focusable="true"
android:focusableInTouchMode="true" />
<EditText android:id="@+id/editPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:textColor="#FF192133"
android:textColorHint="#A0192133"
android:fontFamily="sans-serif-light"
android:hint="Password"
android:focusable="true"
android:focusableInTouchMode="true" />
<EditText android:id="@+id/editEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:textColor="#FF192133"
android:visibility="gone"
android:textColorHint="#A0192133"
android:fontFamily="sans-serif-light"
android:hint="Email"
android:focusable="true"
android:focusableInTouchMode="true" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnSignIn"
android:text="SIGN IN"
android:textStyle="bold"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnRegister"
android:text="REGISTER"
android:textStyle="bold"
/>
</LinearLayout>
</RelativeLayout>
</ScrollView>
The MainActivity.java is given below.
package com.journaldev.loginphpmysql;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
EditText editEmail, editPassword, editName;
Button btnSignIn, btnRegister;
String URL= "https://10.0.3.2/test_android/index.php";
JSONParser jsonParser=new JSONParser();
int i=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editEmail=(EditText)findViewById(R.id.editEmail);
editName=(EditText)findViewById(R.id.editName);
editPassword=(EditText)findViewById(R.id.editPassword);
btnSignIn=(Button)findViewById(R.id.btnSignIn);
btnRegister=(Button)findViewById(R.id.btnRegister);
btnSignIn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
AttemptLogin attemptLogin= new AttemptLogin();
attemptLogin.execute(editName.getText().toString(),editPassword.getText().toString(),"");
}
});
btnRegister.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(i==0)
{
i=1;
editEmail.setVisibility(View.VISIBLE);
btnSignIn.setVisibility(View.GONE);
btnRegister.setText("CREATE ACCOUNT");
}
else{
btnRegister.setText("REGISTER");
editEmail.setVisibility(View.GONE);
btnSignIn.setVisibility(View.VISIBLE);
i=0;
AttemptLogin attemptLogin= new AttemptLogin();
attemptLogin.execute(editName.getText().toString(),editPassword.getText().toString(),editEmail.getText().toString());
}
}
});
}
private class AttemptLogin extends AsyncTask<String, String, JSONObject> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected JSONObject doInBackground(String... args) {
String email = args[2];
String password = args[1];
String name= args[0];
ArrayList params = new ArrayList();
params.add(new BasicNameValuePair("username", name));
params.add(new BasicNameValuePair("password", password));
if(email.length()>0)
params.add(new BasicNameValuePair("email",email));
JSONObject json = jsonParser.makeHttpRequest(URL, "POST", params);
return json;
}
protected void onPostExecute(JSONObject result) {
// dismiss the dialog once product deleted
//Toast.makeText(getApplicationContext(),result,Toast.LENGTH_LONG).show();
try {
if (result != null) {
Toast.makeText(getApplicationContext(),result.getString("message"),Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Unable to retrieve any data from server", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
That’s a pretty big code! Let’s draw the important inferences from the above code.
The JSONParser.java
class is given below.
package com.journaldev.loginphpmysql;
import android.util.Log;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
/**
* Created by anupamchugh on 29/08/16.
*/
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static JSONArray jArr = null;
static String json = "";
static String error = "";
// constructor
public JSONParser() {
}
// function get json from url
// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String url, String method,
ArrayList params) {
// Making HTTP request
try {
// check for request method
if(method.equals("POST")){
// request method is POST
// defaultHttpClient
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
try {
Log.e("API123", " " +convertStreamToString(httpPost.getEntity().getContent()));
Log.e("API123",httpPost.getURI().toString());
} catch (Exception e) {
e.printStackTrace();
}
HttpResponse httpResponse = httpClient.execute(httpPost);
Log.e("API123",""+httpResponse.getStatusLine().getStatusCode());
error= String.valueOf(httpResponse.getStatusLine().getStatusCode());
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else if(method.equals("GET")){
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
Log.d("API123",json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try to parse the string to a JSON object
try {
jObj = new JSONObject(json);
jObj.put("error_code",error);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
private String convertStreamToString(InputStream is) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
is.close();
return sb.toString();
}
}
In the above code, we’re calling the respective classes HTTPPost or HTTPGet depending on the the second parameter that’s passed in the makeHttpRequest function.
jObj.put("error_code",error);
Above, we are appending the response status code returned from the server in the final JSONObject that’s returned to the MainActivity class. Note: Don’t forget to add the following permission in your AndroidManifest.xml file.
<uses-permission android:name="android.permission.INTERNET"/>
Many Users have posted their comments at the bottom of this tutorial, stating they’re getting “Unable to retrieve data” Toast. Please note that since Android 6.0 and above you need to add the following attribute in your application tag in the Manifest.xml file: android:usesCleartextTraffic="true"
Why so? In order to allow the network security of the emulator/device to do http calls. Please check the output with the latest screengrabs from Android Q emulator below. Latest source code with the changes in the AndroidManifest.xml file is updated in the link and our Github Repository.
The output of the application in action is given below.
In the below screengrab we register a new user and it gets added in the Database. We then login using the credentials we entered during registration.
This brings an end to the Android Login with PHP MySQL Tutorial. You can download the project from the link below. It contains the test_android folder too that holds the PHP files. Copy it into the xampp->htdocs folder! Good Luck.
Download Android Login Registration PHP MySQL Project
You can also access the full source code from our Github Repository below:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Cannot resolve method ‘makeHttpRequest’ in ‘JsonParser’
- rihamu
I get the error unable to retrive data from any server. I check every thing mentioned but I steel have this can this problem cause by using mamp server instead of xampp
- amir hossin haghy
More than one file was found with OS independent path ‘META-INF/DEPENDENCIES’. how to solve this error
- divya
Hi there. Looks great. Anyone got this working for application/json or {key:value} parameters? Any suggestions how to go about it? Thanks.
- Bullehs
Great bro! Very usefull for my new project :D Keep going!!
- Agustin
Many Thanks for this toturial. Can you help me on my project? I want to show data of a user after login and show the user name! Sorry for my bad english. Many thanks.
- Hélder Constantino
IF your app is working on an emulator but not working on a real device, make sure that you should turn off the firewall.
- Ali Raza
Hello Everyone, I will pay $25.00 via Paypal if you can get this to connect to an online database (MYSQL) for registration and login, and to post something in the forum which would be a single category always in the forum. The form after login would be Title: Paragraph: Post: Let me know if anyone is interested.
- Steve
For my emulator its working but on real device it is not working at all not. Any suggestion??
- Gunjan Bansal
Hey Anupam, while clicking on the create Account button my program crashes …can you help me out
- Vinit