Login Application For Android


Below is a simple android application for login. It accepts user name and password from the user and sends to remote server application for validation/authentication. Finally displays the result to the user.







Step 1: Create the layout for the application.

FirstApp/res/layout/activity_main.xml




<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="510dip"
    android:layout_marginTop="10dip"
    android:background="#DDDDDD">
    <TextView
        android:id="@+id/tv_un"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="10pt"
        android:textColor="#444444"
        android:layout_alignParentLeft="true"
        android:layout_marginRight="9dip"
        android:layout_marginTop="20dip"
        android:layout_marginLeft="10dip"
        android:text="User Name:"/>
    <EditText
        android:id="@+id/et_un"
        android:layout_width="150dip"
        android:layout_height="wrap_content"
        android:background="@android:drawable/editbox_background"
        android:layout_toRightOf="@id/tv_un"
        android:layout_alignTop="@id/tv_un"
        android:inputType="text"
        />
     <TextView
        android:id="@+id/tv_pw"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="10pt"
        android:textColor="#444444"
        android:layout_alignParentLeft="true"
        android:layout_below="@id/tv_un"
        android:layout_marginRight="9dip"
        android:layout_marginTop="15dip"
        android:layout_marginLeft="10dip"
        android:text="Password:"/>
    <EditText
        android:id="@+id/et_pw"
        android:layout_width="150dip"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dip"
        android:background="@android:drawable/editbox_background"
        android:layout_toRightOf="@id/tv_pw"
        android:layout_alignTop="@id/tv_pw"
        android:layout_below="@id/et_un"
        android:inputType="textPassword"/>"
    <Button
        android:id="@+id/btn_login"
        android:layout_width="100dip"
        android:layout_height="wrap_content"
        android:layout_below="@id/et_pw"
        android:layout_alignParentLeft="true"
        android:layout_marginTop="15dip"
        android:layout_marginLeft="160dip"
        android:text="Login" />
     <TextView
        android:id="@+id/tv_error"
        android:layout_width="400dip"
        android:layout_height="100dip"
        android:textSize="7pt"
        android:layout_alignParentLeft="true"
        android:layout_below="@id/btn_login"
        android:layout_marginRight="9dip"
        android:layout_marginTop="15dip"
        android:layout_marginLeft="120dip"
        android:textColor="#AA0000"
        android:text=""/>
</RelativeLayout>




Step 2: Create a java class to create UI threads.

com.example.firstapp.clientside.LoginLayout.java


/**
 * 
 */
package com.example.firstapp.clientside;

/**
 * @author Prabu
 *
 */
import java.util.ArrayList;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import com.example.firstapp.R;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

@SuppressLint("NewApi")
public class LoginLayout extends Activity {
 EditText un, pw;
 TextView error;
 Button ok;
 private String resp;
 private String errorMsg;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  un = (EditText) findViewById(R.id.et_un);
  pw = (EditText) findViewById(R.id.et_pw);
  ok = (Button) findViewById(R.id.btn_login);
  error = (TextView) findViewById(R.id.tv_error);

  ok.setOnClickListener(new View.OnClickListener() {

   @Override
   public void onClick(View v) {
    /** According with the new StrictGuard policy,  running long tasks on the Main UI thread is not possible
    So creating new thread to create and execute http operations */
    new Thread(new Runnable() {

     @Override
     public void run() {
      ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
      postParameters.add(new BasicNameValuePair("username",un.getText().toString()));
      postParameters.add(new BasicNameValuePair("password",pw.getText().toString()));

      String response = null;
      try {
       response = SimpleHttpClient.executeHttpPost("http://192.168.1.3:8084/LoginServer/login.do", postParameters);
       String res = response.toString();
       resp = res.replaceAll("\\s+", "");

      } catch (Exception e) {
       e.printStackTrace();
       errorMsg = e.getMessage();
      }
     }

    }).start();
    
    /** Inside the new thread we cannot update the main thread
    So updating the main thread outside the new thread */
    try {
     if (resp.equals("1")) {
      error.setText("Correct Username and Password");
     } else {
      error.setText("Sorry!! Incorrect Username or Password");
     }
     if (null != errorMsg && !errorMsg.isEmpty()) {
      error.setText(errorMsg);
     }
    } catch (Exception e) {
     error.setText(e.getMessage());
    }
   }
  });
 }
}



Note: Please use your IP address in below statement;

response = SimpleHttpClient.executeHttpPost("http://192.168.1.3:8084/LoginServer/login.do", postParameters);

http://192.168.1.3:8084/LoginServer/login.do is the url of my server application's servlet.




Step 3: Create a java class to post the username and password to a remote server.

 Normally the database and other resources like servlets will reside in separate computer and the Android application will communicate with that computer to authenticate the user. Thats why we are creating this java class.

com.example.firstapp.clientside.SimpleHttpClient.java





/**
 * 
 */
package com.example.firstapp.clientside;

/**
 * @author Prabu
 *
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
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.conn.params.ConnManagerParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

public class SimpleHttpClient {
 /** The time it takes for our client to timeout */
    public static final int HTTP_TIMEOUT = 30 * 1000; // milliseconds

    /** Single instance of our HttpClient */
    private static HttpClient mHttpClient;

    /**
     * Get our single instance of our HttpClient object.
     *
     * @return an HttpClient object with connection parameters set
     */
    private static HttpClient getHttpClient() {
        if (mHttpClient == null) {
            mHttpClient = new DefaultHttpClient();
            final HttpParams params = mHttpClient.getParams();
            HttpConnectionParams.setConnectionTimeout(params, HTTP_TIMEOUT);
            HttpConnectionParams.setSoTimeout(params, HTTP_TIMEOUT);
            ConnManagerParams.setTimeout(params, HTTP_TIMEOUT);
        }
        return mHttpClient;
    }

    /**
     * Performs an HTTP Post request to the specified url with the
     * specified parameters.
     *
     * @param url The web address to post the request to
     * @param postParameters The parameters to send via the request
     * @return The result of the request
     * @throws Exception
     */
    public static String executeHttpPost(String url, ArrayList<NameValuePair> postParameters) throws Exception {
        BufferedReader in = null;
        try {
            HttpClient client = getHttpClient();
            HttpPost request = new HttpPost(url);
            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
            request.setEntity(formEntity);
            HttpResponse response = client.execute(request);
            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

            StringBuffer sb = new StringBuffer("");
            String line = "";
            String NL = System.getProperty("line.separator");
            while ((line = in.readLine()) != null) {
                sb.append(line + NL);
            }
            in.close();

            String result = sb.toString();
            return result;
        }
        finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * Performs an HTTP GET request to the specified url.
     *
     * @param url The web address to post the request to
     * @return The result of the request
     * @throws Exception
     */
    public static String executeHttpGet(String url) throws Exception {
        BufferedReader in = null;
        try {
            HttpClient client = getHttpClient();
            HttpGet request = new HttpGet();
            request.setURI(new URI(url));
            HttpResponse response = client.execute(request);
            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));

            StringBuffer sb = new StringBuffer("");
            String line = "";
            String NL = System.getProperty("line.separator");
            while ((line = in.readLine()) != null) {
                sb.append(line + NL);
            }
            in.close();

            String result = sb.toString();
            return result;
        }
        finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}






Step 4: Add permissions to access internet

To be able to access the internet from the application (To send the user name and the password to the remote machine) we need to add permissions using following line to the AndroidManifest.xml file

<uses-permission android:name="android.permission.INTERNET"/>


So your final AndroidManifest.xml file will look like;






<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.firstapp"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk android:minSdkVersion="8"
        android:targetSdkVersion="16" />
 <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.firstapp.clientside.LoginLayout"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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





Step 5: Create the login server application

We are done at the android application side. Now we need the server application to check the user name and the password. Here I have used a simple web application with a servlet. This application runs in a Tomcat server. You can have your own logic to validate the username and the password in the servlet. You can do database operations etc. But here I am just doing static validation of the username and password.



LoginServlet.java



/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package serverside;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *
 * @author Vienna
 */
public class LoginServlet extends HttpServlet {

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
        String un,pw;
        un=request.getParameter("username");
        pw=request.getParameter("password");
        if(un.equalsIgnoreCase("hello") && pw.equals("world"))
            out.print(1);
        else
            out.print(0);
        } finally {            
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}






Step 6: We are done and ready to run the application.









This example has been upgraded with SSL support and AsynTaskSupport here. Have a look..



Please dont forget to share your views !!



8 comments:

  1. Code is simple and easy to understand. thanks

    ReplyDelete
  2. When i press the login button i get import android.os.NetworkOnMainThreadException; in username box. how to fix it

    ReplyDelete
    Replies
    1. According with the new StrictGuard policy, running long tasks on the Main UI thread is not possible. So I have created a new thread and given my network logic in the new thread.
      new Thread(new Runnable() {
      //Network/long running task goes here
      }
      Please refer step2. I have clearly mentioned. This will resolve your issue.
      It is recommended to use AsyncTask for such long running/networking tasks to avoid lagging of your application.
      To know how to use AsyncTask please refer AsyncTask tutorial

      Delete
  3. I always get incorrect username or password error.

    ReplyDelete
    Replies
    1. Hi,
      please post the error stack trace so that we can narrow down the issue.

      Delete
  4. Hey.. the application looks good but I did not understand the URL used to call the server application. I am trying to execute this with a local host. So I do not know which URL to give. How is it that the login.do file is generated?

    ReplyDelete
    Replies
    1. Hi Navtej singh,
      Looks like you have missed the step5.

      login.do is the separate servlet running in tomcat server. I have created a web project in netbeans with this servlet and that runs in tomcat server.
      The android application communicates with this server app.

      You have to give the url of this server application.

      Delete