Thursday 30 June 2016

Genymotion: Set a location in Running Emulator

Hae there, this is probably one of the simplest things i get to do while running a project that requires location.
By default, a running genymotion virtual device location is disabled and it's usually preset at latitude =65.9667 and longitude = -18.5333

How to enable the location service and adding a custom location.

1. Open Genymotion,






2. Run a virtual device - i like using Google nexus 6 - API 22



3. On the side menu of the emulator, click on the GPS, and a GPS window will popup.



4. Turn the GPS on notice the default latitude and longitude values, those are the onces we are going to change




5. Get the co-ordinate of a place 

- Click here, then scroll down the page, Enter the name of the place you want e.g Technical University of Kenya and press Get GPS Coordinates.
latitude will be = -1.292001
and longitude is= 36.824594



- Copy the latitude and longitude and paste it to the virtual device GPS respectively, leave the rest to default.



- Close the GPS popup window, then you'll be good to go,

*** In case you want the emulator to virtualize your location as if your moving, just get other coordinates and enter them, you'll notice the location changing on the map in real time***

See Also:

* Show User's Current Location

Saturday 25 June 2016

Android Google Maps: Show current Location

Today im gonna show you how to create an android app that shows your current location on the map

Project Structure:



Procedure:
1. To start with, Create an new android project,
Go to start 'start a new project' from the welcome screen > Name it 'CurrentLocation' > Choose 'Google maps activity' *This is the main point* and finish to create the project.

2. After gradle has synced successfully, android studio will open google_maps_api.xml by default. in this xml file, we are required to get our api key from google console and replace it where there is this
phrase "YOUR_KEY_HERE"


 


* Android studio makes it very easy to get the api key because after creating the project, the hash signature is already written in the google_maps_api.xml file.

- Copy the url from the file and paste it to your browser, e.g in my case it's on line 7 in my editor,

https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=
8F:D7:78:DF:61:AB:F8:5B:53:E9:48:39:56:D4:3B:1F:05:E3:4E:05%3Bcom.androidmastermind.currentlocation

> Rememeber to use your projects url, else it won't work.

- The link takes you straight to google api console which will prompt you to enable the maps api by creating a project

- After the page loads, just click on continue...,  A project will be created as 'My Project' ,(will change this later)



-  Another page will load after some few seconds, click on 'Go to credentials'



- A page will load with the package name of your app and the sha-1 certificate fingerprint, You can rename the key the way you want, for my case ill leave it to default and press create.



- A popup window will appear with your api key, just copy it and click ok. At this point we are done with the console,



-  Go back to our android project, in the google_maps_api.xml, paste the api key

<resources>
    <!--    TODO: Before you run your application, you need a Google Maps API key.

    To get one, follow this link, follow the directions and press "Create" at the end:
    https://console.developers.google.com/flows/enableapi?
apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=
8F:D7:78:DF:61:AB:F8:5B:53:E9:48:39:56:D4:3B:1F:05:E3:4E:05%
3Bcom.androidmastermind.currentlocation
    You can also add your credentials to an existing key, using this line:
    8F:D7:78:DF:61:AB:F8:5B:53:E9:48:39:56:D4:3B:1F:05:E3:4E:05;com.androidmastermind.currentlocation
    Alternatively, follow the directions here:
    https://developers.google.com/maps/documentation/android/start#get-key
    Once you have your key (it starts with "AIza"), replace the "google_maps_key"    string in this file.    -->
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">
AIzaSyBIfHPW-nb4JdNK1TlWuV3XiVIWhmuDvqwN</string>
</resources>

- You can now test your app and see if it displays a map, by default, your supposed to see a map with a marker, if you click it it will popup with 'marker in sydney'
- For this, just fire up genymotion, or plug your device in debug mode.




- Now lets go back to our MainActivity.java and make some changes,
- first thing we will implement LocationListener, this will be monitoring the location in case you move from the current location.
* Be careful to import <<import android.location.LocationListener;>> for the locationlistner, else you may meet some errors later.


- Will also create a method, getCurrentLocation(), that will be fethching the current location, and check if google play services are available before displaying the location.

package com.androidmastermind.currentlocation;

import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback,LocationListener {

    private static final String TAG = "CurrentLocation";
    private GoogleMap mMap;
    protected LocationManager locationManager;
    private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;


    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!isGooglePlayServicesAvailable()) {
            return;
        }
        setContentView(R.layout.activity_maps);

        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }


    /**     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        displayCurrentLocation(mMap);
    }

    private void displayCurrentLocation(GoogleMap mMap) {
        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) 
!= PackageManager.PERMISSION_GRANTED
 && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION)
 != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        mMap.setMyLocationEnabled(true);
        mMap.getUiSettings().setCompassEnabled(true);
        mMap.getUiSettings().setZoomControlsEnabled(true);

        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        Criteria criteria = new Criteria();
        String bestProvider = locationManager.getBestProvider(criteria, true);
        Location location = locationManager.getLastKnownLocation(bestProvider);

        if (location != null) {
            onLocationChanged(location);

        }

        locationManager.requestLocationUpdates(bestProvider, 20000, 0, this);

    }

    private boolean isGooglePlayServicesAvailable() {
        GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
        if (resultCode != ConnectionResult.SUCCESS) {
            if (apiAvailability.isUserResolvableError(resultCode)) {
                apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST).show();
            } else {
                Log.i(TAG, "This device is not supported.");
                finish();
            }
            return false;
        }
        return true;
    }

    @Override    public void onLocationChanged(Location location) {
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();

        LatLng currentLocation = new LatLng(latitude, longitude);
        mMap.addMarker(new MarkerOptions().position(currentLocation).title("My Location"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(currentLocation));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
    }

    @Override
    public void onStatusChanged(String s, int i, Bundle bundle) {

    }

    @Override
    public void onProviderEnabled(String s) {

    }

    @Override
    public void onProviderDisabled(String s) {

    }
}

* That's it, you've successfully created an app that monitors your current location.




> My current location was at Technical University of Kenya
* Run it on a real device to see how it behaves when you move around and change location

See Also:
* Show Nearby Places From a User's Location



Thursday 23 June 2016

Android login: using volley, php, mysql, pdo

Today you gonna learn how to create a login activity that uses volley for request. Click here If you want more information about volley library.
To begin with, will first create a back-end using PHP and my SQL. I'm using wamp server to host the php scripts.

1. Backend - PHP, MYSQL, PDO

Project Structure:




i) fire up the server (wampserver for my case), open browser and go to localhost/phpmyadmin

ii) create a database androidmastermind,

iii) create a table login,

CREATE TABLE IF NOT EXISTS `login` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(30) NOT NULL,
  `password` varchar(50) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
)

INSERT INTO `login` (`id`, `username`, `password`, `created_at`)
 VALUES(1, 'admin@gmail.com', 'admin', '2016-06-22 09:34:13');

iv) Create constants.php file, this will hold all the variables that we will need to reuse.

<?php

define("USERNAME","username");
define("PASSWORD","password");

v) Create DbConnection.php file, this will handle the database connection and disconnection when needed.
* Remember to change the username and password*

<?php

    private static $dbName = 'androidmastermind';
    private static $dbHost = 'localhost';
    private static $dbUsername = 'kevynashinski';
    private static $dbUserPassword = 'elegant';
    private static $cont = null;
    public function __construct(){
    }

    public static function connect(){
        // One connection through whole application
        if (null == self::$cont) {
            try {
                self::$cont = new PDO("mysql:host=" . self::$dbHost . ";"
                 . "dbname=" . self::$dbName, self::$dbUsername, self::$dbUserPassword);
                self::$cont->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            } catch (PDOException $e) {
                die($e->getMessage());            }
        }
        return self::$cont;    }

    public static function disconnect(){
        self::$cont = null;    }
}

vi) Finally create login.php file, this will authenticate the user, by receiving thus username and password through POST.

<?php
include 'DbConnection.php';
include 'constants.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST') {

    $username = $_REQUEST[USERNAME];
    $password = $_REQUEST[PASSWORD];
//    open connection
    $conn = DatabaseConnection::connect();
    $sql = "select * from login WHERE username='$username' AND password='$password'";
//    check if a row exists with the credentials
    if ($conn->query($sql)->rowCount() > 0) {
//        shows there's a record
        echo 1;
    } else {
//        shows there's no such record
        echo 0;
    }
} else{
//    shows that nothing was posted
    echo 2;
}

* The index.php serves the purpose of testing our database connection.

<?php
include 'DbConnection.php';
$conn=DatabaseConnection::connect();
if($conn){
    echo "Ready to Roll!!!";
}else{
    echo "connection Error".$conn->errorInfo();
}

2. Frontend - Android

Project Structure:



i) Create a new android project, name it AndroidLogin

ii) Import volley library to your build.gradle (app:module)

compile group: 'com.mcxiaoke.volley', name: 'library', version: '1.0.19'

ii) Create App.java in the package, this class extends Application, it holds the initialization of the app configurations, in our case volley initialization.

package com.androidmatermind.androidlogin;

import android.app.Application;
import android.text.TextUtils;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

/** * Created by Kevynashinski on 6/23/2016. */
public class App extends Application{
    public static final String TAG = "androidlogin";

    private ImageLoader mImageLoader;

    private RequestQueue mRequestQueue;
    private static App mInstance;

    @Override    public void onCreate() {
        super.onCreate();
        mInstance = this;
    }


    public static synchronized App getInstance() {
        return mInstance;
    }

    public RequestQueue getRequestQueue() {
        if (mRequestQueue == null) {
            mRequestQueue = Volley.newRequestQueue(getBaseContext());
        }

        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> req, String tag) {
        // set the default tag if tag is empty
        req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
        getRequestQueue().add(req);
    }

    public <T> void addToRequestQueue(Request<T> req) {
        req.setTag(TAG);
        getRequestQueue().add(req);
    }

    public void cancelPendingRequests(Object tag) {
        if (mRequestQueue != null) {
            mRequestQueue.cancelAll(tag);
        }
    }
}

iii) Create another file, AppConfig.java, this holds the server link

package com.androidmatermind.androidlogin;

/** * Created by muus on 6/23/2016. */
public final class AppConfig {

    public static final String SERVER_URL="http://192.168.56.1/androidlogin/";
    public static final String URL_LOGIN=SERVER_URL+"login.php";
}

iv) InternetConnection.java class, will help us check if internet is available before login begins

package com.androidmatermind.androidlogin;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

/** * Created by kevynashinski on 11/9/2015. */
public class InternetConnection {

    Context context;

    public InternetConnection(Context context) {
        this.context = context;
    }

    public boolean isInternetAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager)
 context.getSystemService(Context.CONNECTIVITY_SERVICE);

//        boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
        NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
        return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    }
}

v) Under the MainActivity.java, will when a user click sign in button, will first check if internet is available, then carry out the login operation. The email and password will also be validated

package com.androidmatermind.androidlogin;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.CursorLoader;
import android.content.Loader;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static android.Manifest.permission.READ_CONTACTS;

/** * A login screen that offers login via email/password. */
public class MainActivity extends AppCompatActivity implements LoaderCallbacks<Cursor> {

    private static final int REQUEST_READ_CONTACTS = 0;

    // UI references.    private AutoCompleteTextView mEmailView;
    private EditText mPasswordView;
    private View mProgressView;
    private View mLoginFormView;

    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Set up the login form.
        mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
        populateAutoComplete();

        mPasswordView = (EditText) findViewById(R.id.password);

        Button signInButton = (Button) findViewById(R.id.sign_in_button);
        assert signInButton != null;
        signInButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                if(new InternetConnection(getBaseContext()).isInternetAvailable())
                attemptLogin();
                else {
                    Toast.makeText(getBaseContext(),"Check your internet connection",
Toast.LENGTH_LONG).show();
                }
            }
        });

        mLoginFormView = findViewById(R.id.login_form);
        mProgressView = findViewById(R.id.login_progress);
    }

    private void populateAutoComplete() {
        if (!mayRequestContacts()) {
            return;
        }

        getLoaderManager().initLoader(0, null, this);
    }

    private boolean mayRequestContacts() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return true;
        }
        if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
            Snackbar.make(mEmailView, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
                    .setAction(android.R.string.ok, new View.OnClickListener() {
                        @Override
                        @TargetApi(Build.VERSION_CODES.M)
                        public void onClick(View v) {
                            requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
                        }
                    });
        } else {
            requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
        }
        return false;
    }

    /**     * Callback received when a permissions request has been completed.     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        if (requestCode == REQUEST_READ_CONTACTS) {
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                populateAutoComplete();
            }
        }
    }


    /**     * Attempts to sign in or register the account specified by the login form.
     * If there are form errors (invalid email, missing fields, etc.), the     
     * errors are presented and no actual login attempt is made.
     */
    private void attemptLogin() {
        // Reset errors.
        mEmailView.setError(null);
        mPasswordView.setError(null);

        // Store values at the time of the login attempt.
        String email = mEmailView.getText().toString();
        String password = mPasswordView.getText().toString();

        boolean cancel = false;
        View focusView = null;

        // Check for a valid password, if the user entered one.
        if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
            mPasswordView.setError(getString(R.string.error_invalid_password));
            focusView = mPasswordView;
            cancel = true;
        }

        // Check for a valid email address.
        if (TextUtils.isEmpty(email)) {
            mEmailView.setError(getString(R.string.error_field_required));
            focusView = mEmailView;
            cancel = true;
        } else if (!isEmailValid(email)) {
            mEmailView.setError(getString(R.string.error_invalid_email));
            focusView = mEmailView;
            cancel = true;
        }

        if (cancel) {
            // There was an error; don't attempt login and focus the first
            // form field with an error.
            focusView.requestFocus();
        } else {
            // Show a progress spinner, and kick off a background task to
            // perform the user login attempt.
            showProgress(true);
            login(email,password);
        }
    }

    private void login(final String email, final String password) {
        StringRequest strReq = new StringRequest(Request.Method.POST,
                AppConfig.URL_LOGIN, new Response.Listener<String>() {

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

                showProgress(false);

                if(response.equalsIgnoreCase("1")){
                    Toast.makeText(getBaseContext(),"Login Success!!!",Toast.LENGTH_LONG).show();
                }else if(response.equalsIgnoreCase("0")){
                    Toast.makeText(getBaseContext(),"Invalid username or password",
Toast.LENGTH_LONG).show();
                }else if(response.equalsIgnoreCase("2")){
                    Toast.makeText(getBaseContext(),"Server Error!",Toast.LENGTH_LONG).show();
                }
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {

                showProgress(false);

                Log.e(App.TAG, "Login Error: " + error.getMessage());
            }
        }) {

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

                return params;
            }
        };

        // Adding request to request queue
        App.getInstance().addToRequestQueue(strReq);
    }

    private boolean isEmailValid(String email) {
        //TODO: Replace this with your own logic
        return Patterns.EMAIL_ADDRESS.matcher(email).matches();
    }

    private boolean isPasswordValid(String password) {
        //TODO: Replace this with your own logic
        return password.length() > 4;
    }

    /**     * Shows the progress UI and hides the login form.
     */    
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
    private void showProgress(final boolean show) {
        // On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
        // for very easy animations. If available, use these APIs to fade-in
        // the progress spinner.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
            int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);

            mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
            mLoginFormView.animate().setDuration(shortAnimTime).alpha(
                    show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
                }
            });

            mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
            mProgressView.animate().setDuration(shortAnimTime).alpha(
                    show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
                }
            });
        } else {
            // The ViewPropertyAnimator APIs are not available, so simply show
            // and hide the relevant UI components.
            mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
            mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
        }
    }

    @Override
    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        return new CursorLoader(this,
                // Retrieve data rows for the device user's 'profile' contact.
                Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,
                        ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION,

                // Select only email addresses.
                ContactsContract.Contacts.Data.MIMETYPE +
                        " = ?", new String[]{ContactsContract.CommonDataKinds.Email
                .CONTENT_ITEM_TYPE},

                // Show primary email addresses first. Note that there won't be
                // a primary email address if the user hasn't specified one.
                ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
    }

    @Override
    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
        List<String> emails = new ArrayList<>();
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            emails.add(cursor.getString(ProfileQuery.ADDRESS));
            cursor.moveToNext();
        }

        addEmailsToAutoComplete(emails);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> cursorLoader) {

    }

    private void addEmailsToAutoComplete(List<String> emailAddressCollection) {
        //Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
        ArrayAdapter<String> adapter =
                new ArrayAdapter<>(MainActivity.this,
                        android.R.layout.simple_dropdown_item_1line, emailAddressCollection);

        mEmailView.setAdapter(adapter);
    }


    private interface ProfileQuery {
        String[] PROJECTION = {
                ContactsContract.CommonDataKinds.Email.ADDRESS,
                ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
        };

        int ADDRESS = 0;
        int IS_PRIMARY = 1;
    }

}

vi) Add the following codes to the activity_main.xml

<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center_horizontal"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <!-- Login progress -->
    <ProgressBar
        android:id="@+id/login_progress"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:visibility="gone" />

    <ScrollView
        android:id="@+id/login_form"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/email_login_form"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <AutoCompleteTextView
                    android:id="@+id/email"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="Email Address"
                    android:inputType="textEmailAddress"
                    android:maxLines="1"
                    android:singleLine="true" />

            </android.support.design.widget.TextInputLayout>

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <EditText
                    android:id="@+id/password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="password"
                    android:inputType="textPassword"
                    android:maxLines="1"
                    android:singleLine="true" />

            </android.support.design.widget.TextInputLayout>

            <Button
                android:id="@+id/sign_in_button"
                style="?android:textAppearanceSmall"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:text="Sign in"
                android:textStyle="bold" />

        </LinearLayout>
    </ScrollView>
</LinearLayout>

vii) Run the project,
a) When login success.



b) When login failure.



Thats all, your good to go!!!