In this tutorials, you will learn how to develop a complete Android Login Registration System with PHP, MySQL, and SQLite Databases.
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.
9. Create an activity class named LoginActivity.java.
11. Create an activity class named EmailVerify.java db.addUser() – Will insert the user in SQLite database once he is successfully verified his Email.
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.
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 format1. 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.
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>
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>
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>
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 HashMapuser = 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 Validationpublic 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 cmd6. Download Complete Project
You can download complete project at GithubDownload Project
Enter your email to unlock the download.
