Display contacts from address book in Android

In my last post, I had explained how to add new contacts using the Contacts Provider component in Android. Moving on, we will now learn how to display existing phone book contacts using the concept of Cursors. The Cursor interface provides random read-write access to the result set returned by a database query.

As mentioned on the developer’s page, cursor implementations are not required to be synchronized so code using a Cursor from multiple threads should perform its own synchronization when using the Cursor.

Through this post, we will learn how to display existing phone book and Skype contacts using Cursors.

Pre-requisites: Eclipse IDE, Android SDK (Target API level: 19)

Open the Eclipse IDE and create a new Activity class called DisplayContactListActivity in any of your existing Android projects and add the following code!

DisplayContactListActivity.java

package com.example;

import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Data;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class DisplayContactListActivity extends Activity {

	private Button m_objBtnSkypeContact;
	private Button m_objBtnPhoneContact;
	private TextView m_objDisplayContact;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_display_contact);

		m_objBtnSkypeContact = (Button)findViewById(R.id.btnSkypeContact);
		m_objBtnPhoneContact = (Button)findViewById(R.id.btnPhoneContact);
		m_objDisplayContact = (TextView)findViewById(R.id.txtDisplayContact);

		//skype phone contact button event
		m_objBtnSkypeContact.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				try{
					m_objDisplayContact.setText("");
					getSkypeContactsList();
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		});


		//phone contact button event
		m_objBtnPhoneContact.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				try{
					m_objDisplayContact.setText("");
					getPhoneContactsList();
				}catch(Exception ex){
					ex.printStackTrace();
				}
			}
		});
	}

	/**
	 * 
	 * This function is used to display the list of Skype contacts
	 */
	private void getSkypeContactsList() {
		StringBuffer strSkypeContactBuffer = new StringBuffer();
		Cursor objCursor = getContentResolver().query(
				Data.CONTENT_URI,
				new String[] { Data.CONTACT_ID, Data.DATA1 },
				Data.MIMETYPE + "= ?", 
				new String[] { "vnd.android.cursor.item/com.skype.android.skypecall.action" },
				null);

		while (objCursor != null && objCursor.moveToNext()) {
			long contact = objCursor.getLong(0);
			String skype = objCursor.getString(1);

			Log.i("ContactsApp" , " " + "contact " + contact + " has skype username: " + skype);
			strSkypeContactBuffer.append("Contact " + contact + " has skype username: " + skype + "\n");

		}

		//display contact details
		m_objDisplayContact.setText(strSkypeContactBuffer.toString());
	}

	/**
	 * 
	 * 
	 * This function is used to display the existing phone contacts
	 */
	private void getPhoneContactsList() {
		StringBuffer strPhoneContactBuffer = new StringBuffer();
		ContentResolver objContentResolver = getContentResolver();
		Cursor objCursor = objContentResolver.query(ContactsContract.Contacts.CONTENT_URI,
				null, null, null, null);
		if (objCursor.getCount() > 0) {
			while (objCursor.moveToNext()) {
				String id = objCursor.getString(objCursor.getColumnIndex(ContactsContract.Contacts._ID));
				String name = objCursor.getString(objCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
				if (Integer.parseInt(objCursor.getString(
						objCursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
					Cursor objContactCursor = objContentResolver.query(
							ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
							null,
							ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = ?",
							new String[]{id}, null);
					while (objContactCursor.moveToNext()) {
						String phoneNo = objContactCursor.getString(objContactCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
						Log.i("ContactsApp", "Name: " + name + ", Phone No: " + phoneNo);
						strPhoneContactBuffer.append("Name: " + name + ", Phone No: " + phoneNo + "\n");
						
					}
					objContactCursor.close();
				}
			}
		}

		//display contact details
		m_objDisplayContact.setText(strPhoneContactBuffer.toString());
	}
}

activity_display_contact.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/btnPhoneContact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="@string/lbl_phone_contact" />

    <Button
        android:id="@+id/btnSkypeContact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnPhoneContact"
        android:layout_centerInParent="true"
        android:text="@string/lbl_skype_contact" />

    <TextView
        android:id="@+id/txtDisplayContact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnSkypeContact"
        android:layout_centerInParent="true" />

</RelativeLayout>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- Display contact demo -->
    <string name="lbl_phone_contact">Show Phone contacts</string>
    <string name="lbl_skype_contact">Show Skype contacts</string>
</resources>

No changed are to be made to the AndroidManifest.xml file. Run the application on an Android device and you should be able to see the following output!

Screenshot_2015-11-09-09-04-47

Now, click on any of the buttons to retrieve the contact list.

That’s it then for this Android tip. Stay tuned for more! πŸ™‚

Display loading indicator using AngularJS

AngularJS allows developers to extend HTML with new attributes called Directives. In simple terms, an AngularJS directive is essentially a function that executes when the Angular compiler finds it in the DOM (Document Object Model). Directives are extended HTML attributes with the prefix ng-. For instance, the ng-model directive binds the value of HTML controls (input, select, textarea) to application data.

On the other hand, Services are substitutable objects that are wired together using dependency injection (DI). Developers can use services to organize and share code across your app. To use an Angular service, you add it as a dependency for the component (controller, service, filter or directive).

Through this post, we will learn how to display a simple loading indicator using AngularJS directives and services. The loading indicator thus implemented can be displayed while executing AJAX requests to remote web services.

Pre-requisites: Eclipse IDE for Java EE developers, Apache Tomcat 7.0

Step 1: Launch the Eclipse IDE and create a new Dynamic Web Project called AngularSpinnerDemo with target server runtime as Apache Tomcat 7.

create_dynamic_web_project

Now, let’s create our own directive that will display the spinner when the DOM is loaded.

Step 2: Create directive for Spinner

Create a new JavaScript file called spinner_directive.js that will include our custom directive. As the DOM (Document Object Model) is compiled by AngularJS, the directive controllers and link functions execute at different parts of the compile life-cycle.

spinner_directive.js

app.directive('spinner', function () {
    return {
        restrict: 'E',
        template: [
          '<span>',
          '  <img ng-show="showSpinner" ng-src="{{url}}" style="padding-right: 7px; width: {{ spinnerSize }}; vertical-align: middle" />',
          '  <span ng-show="loadingText && showSpinner">{{ loadingText }}</span>',
          '  <span ng-show="doneText && !showSpinner">{{ doneText }}</span>',
          '</span>'
        ].join(''),
        replace: true,
        scope: {
            id: '@',
            group: '@?',
            showSpinner: '@?',
            loadingText: '@?',
            doneText: '@?',
            onRegisterComplete: '&?',
            url: '@'
        },
        controller: function ($scope, $attrs, spinnerService) {
            // Register the spinner with the spinner service.
            spinnerService._register($scope);
            // Invoke the onRegisterComplete expression, if any.
            // Expose the spinner service for easy access.
            $scope.onRegisterComplete({ $spinnerService: spinnerService });
        },
        link: function (scope, elem, attrs) {
            // Check for pre-defined size aliases and set pixel width accordingly.
            if (attrs.hasOwnProperty('size')) {
                attrs.size = attrs.size.toLowerCase();
            }
            switch (attrs.size) {
                case 'tiny':
                    scope.spinnerSize = '15px';
                    break;
                case 'small':
                    scope.spinnerSize = '25px';
                    break;
                case 'medium':
                    scope.spinnerSize = '35px';
                    break;
                case 'large':
                    scope.spinnerSize = '75px';
                    break;
                default:
                    scope.spinnerSize = '50px';
                    break;
            }
        }
    };
});

Step 3: Create service for Spinner

Create a new JavaScript file called spinner_service.js that will include the definition of our spinner service as follows!

spinner_service.js

app.factory('spinnerService', function () {
    var cache = {};
    return {

        // A private function intended for spinner directives to register themselves with the service.
        _register: function (spinnerScope) {
            // If no id is passed in, throw an exception.
            if (!spinnerScope.id) {
                throw new Error("A spinner must have an ID to register with the spinner service.");
            }

            // Add our spinner directive's scope to the cache.
            cache[spinnerScope.id] = spinnerScope;
        },

        // A private function exposed just in case the user really needs to manually unregister a spinner.
        _unregister: function (spinnerId) {
            delete cache[spinnerId];
        },

        // A private function that will remove an entire spinner group if needed.
        _unregisterGroup: function (group) {
            for (var spinnerId in cache) {
                if (cache.hasOwnProperty(spinnerId)) {
                    if (cache[spinnerId].group === group) {
                        delete cache[spinnerId];
                    }
                }
            }
        },

        // A private function that will clear out all spinners from the cache.
        _unregisterAll: function () {
            for (var spinnerId in cache) {
                if (cache.hasOwnProperty(pinnerId)) {
                    delete cache[spinnerId];
                }
            }
        },

        // Show the specified spinner.
        // If loadingText is specified, replace the loadingText specified on the directive as we show the spinner.
        show: function (spinnerId, loadingText) {

            $("body").find("#loading").addClass("mydiv");
            if (cache.hasOwnProperty(spinnerId)) {
                var spinnerScope = cache[spinnerId];
                spinnerScope.showSpinner = true;
                if (loadingText !== undefined) {
                    spinnerScope.loadingText = loadingText;
                }

            }
        },

        // Hide the specified spinner.
        // If doneText is specified, replace the doneText specified on the directive as we hide the spinner.
        hide: function (spinnerId, doneText) {

            if (cache.hasOwnProperty(spinnerId)) {
                var spinnerScope = cache[spinnerId];
                $("body").find("#loading").removeClass("mydiv");
                spinnerScope.showSpinner = false;

                if (doneText !== undefined) {
                    spinnerScope.doneText = doneText;
                }

            }
        }

    };
});

Step 4: Create controller

spinnercntrl.js

app.controller("spinnercntrl", function ($scope,spinnerService) {

	//initially hide the spinner
	spinnerService.hide('mySpinner');

	/*method called on click of show spinner button*/
	$scope.showSpinner = function(){
		
		spinnerService.show('mySpinner');
		
		//hide the spinner after 3 seconds
		setTimeout(function(){ 
			spinnerService.hide('mySpinner');
		}, 3000);

	};

});

Finally, run the application on the Tomcat server. If no errors occur, then you should see the loading indicator on click of the Show spinner button.

output_1

output_2

Source code for this tutorial can be found over here.

Reference: AngularJS Developer Guide

Adding contacts in Android

Hi everyone!

The Android SDK allows developers to add new contacts using the Contacts Provider component. As mentioned on the developer’s page, the Contacts Provider is the source of data you see in the device’s contacts application, and you can also access its data in your own application and transfer data between the device and online services. The provider accommodates a wide range of data sources and tries to manage as much data as possible for each person, with the result that its organization is complex.

Developers can access the Contacts Provider information directly by calling ContentResolver methods or by sending intents to a pre-installed contacts application. Through this post, we will learn how to add new contacts to our existing phone address book.

Pre-requisites: Eclipse IDE, Android SDK (Target API level: 19)

In any of your existing Android projects, create a new Activity class called AddContactActivity and add the following code!

AddContactActivity.java

package com.example;

import java.util.ArrayList;
import android.app.Activity;
import android.content.ContentProviderOperation;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class AddContactActivity extends Activity {

	private Button m_objBtnAddContact;
	private EditText m_objInputContactName, m_objInputContactEmail, m_objInputContactMobNo;
	public static final String LOG_TAG = "AddContactDemo";
	public static final String ACCOUNT_TYPE = "REPLACE_YOUR_GMAIL_ACCOUNT_ADDRESS";

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_add_contact);

		m_objBtnAddContact = (Button)findViewById(R.id.btnAddContact);
		m_objInputContactName = (EditText)findViewById(R.id.inputContactName);
		m_objInputContactEmail = (EditText)findViewById(R.id.inputContactEmail);
		m_objInputContactMobNo = (EditText)findViewById(R.id.inputContactMobNo);

		//add new contact button event
		m_objBtnAddContact.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				try{
					
					String strContactName = m_objInputContactName.getEditableText().toString();
					String strContactEmail = m_objInputContactEmail.getEditableText().toString();
					String strContactMobNumber = m_objInputContactMobNo.getEditableText().toString();

					if(!isNullOrBlank(strContactName) && !isNullOrBlank(strContactEmail) && !isNullOrBlank(strContactMobNumber)){
						if(!contactExists(AddContactActivity.this, strContactMobNumber)){
							Contact objContact = new Contact(strContactName, strContactMobNumber, strContactEmail);
							addContactsToAddressBook(objContact);
						}else{
							Toast.makeText(getApplicationContext(), "Contacts already exists", Toast.LENGTH_LONG).show();
						}
					}
				}catch(Exception e){
					e.printStackTrace();
				}
			}
		});
	}


	/**
	 * This method is used to determine if a particular contact already exists
	 * @param Activity instance
	 * @param mobile number
	 * @return
	 */
	public boolean contactExists(Activity p_objActivity, String p_strMobileNumber) {
		if (p_strMobileNumber != null) {
			Uri objLookupUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(p_strMobileNumber));
			String[] objPhoneNumberProjection = { PhoneLookup._ID, PhoneLookup.NUMBER, PhoneLookup.DISPLAY_NAME };
			Cursor objCursor = p_objActivity.getContentResolver().query(objLookupUri, objPhoneNumberProjection, null, null, null);
			try {
				if (objCursor.moveToFirst()) {
					return true;
				}
			} finally {
				if (objCursor != null)
					objCursor.close();
			}
			return false;
		} else {
			return false;
		}
	}

	/**
	 * This function is used to check if a string is null or empty
	 * @param p_strInput
	 * @return true if string is null or empty
	 */
	public static boolean isNullOrBlank(String p_strInput){
		return (null== p_strInput || p_strInput.trim().equals(""));
	}

	/**
	 * This function is used to add a new contact to address book
	 * 
	 * @param contact
	 */
	public void addContactsToAddressBook(Contact contact){
		ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
		ops.add(ContentProviderOperation.newInsert(
				ContactsContract.RawContacts.CONTENT_URI)
				.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
				.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, "com.google")
				.build()
				);

		if(contact != null){
			//add contact name
			ops.add(ContentProviderOperation.newInsert(
					ContactsContract.Data.CONTENT_URI)              
					.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
					.withValue(ContactsContract.Data.MIMETYPE,
							ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
							.withValue(
									ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,     
									contact.getName()).build()
					);

			//add  contact email
			ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
					.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
					.withValue(ContactsContract.Data.MIMETYPE,
							ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
							.withValue(ContactsContract.CommonDataKinds.Email.DATA, contact.getEmailId())
							.withValue(ContactsContract.CommonDataKinds.Email.TYPE, ContactsContract.CommonDataKinds.Email.TYPE_WORK)
							.build());

			//add contact mobile no
			ops.add(ContentProviderOperation.
					newInsert(ContactsContract.Data.CONTENT_URI)
					.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
					.withValue(ContactsContract.Data.MIMETYPE,
							ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
							.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, contact.getMobileNo())
							.withValue(ContactsContract.CommonDataKinds.Phone.TYPE, 
									ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE)
									.build()
					);

			// Asking the Contact provider to create a new contact                  
			try {
				getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
			} 
			catch (Exception e) {               
				e.printStackTrace();
				Toast.makeText(getApplicationContext(), "Unable to add contact!", Toast.LENGTH_LONG).show();
			}
		}

		Toast.makeText(getApplicationContext(), "Contact added!", Toast.LENGTH_LONG).show();
	}


}

activity_add_contact.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/txtContactName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/lbl_contact_name" >
    </TextView>

    <EditText
        android:id="@+id/inputContactName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="@string/lbl_contact_name"
        android:inputType="text" >
    </EditText>

    <TextView
        android:id="@+id/txtContactEmail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/lbl_contact_emailid" >
    </TextView>

    <EditText
        android:id="@+id/inputContactEmail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="@string/lbl_contact_emailid"
        android:inputType="textEmailAddress" >
    </EditText>

    <TextView
        android:id="@+id/txtContactMobNo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/lbl_contact_mobnumber" >
    </TextView>

    <EditText
        android:id="@+id/inputContactMobNo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="@string/lbl_contact_mobnumber"
        android:inputType="number" >
    </EditText>

    <Button
        android:id="@+id/btnAddContact"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:hint="@string/lbl_add_contact" >
    </Button>

</LinearLayout>

strings.xml

 <string name="lbl_contact_name">Enter contact name</string>
    <string name="lbl_contact_emailid">Enter contact email ID</string>
    <string name="lbl_contact_mobnumber">Enter contact mobile number</string>
    <string name="lbl_add_contact">Add contact
</string>

Before running the application on a physical device, one needs to add the below permissions in the AndroidManifest.xml file

AndroidManifest.xml

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />

Finally, if no errors occur you should be able to see the below output on running the application.

Main screen

Main screen

Adding new contact

Adding new contact

Contact already exists

Contact already exists

In the next post, we will see how to fetch and display the list of contacts! πŸ™‚

A date with Java 8!

[This is a long overdue post…]

Hello everyone!

Java is a pure object oriented programming language. Over the years, there have been many enhancements including some of the features like Annotations, Generics etc. Prior to Java 8, it was difficult to pass plain methods as arguments. Java 8 helps overcome this limitation by introducing a new feature called Lambda expressions. This addition to the language brings Java in line with other functional JVM-based languages such as Scala and Clojure.

Java 8 has introduced a lot more features including parallel operations, new date/time API’s, internationalization, concurrency etc. Through this post, we will learn how to implement two of the new features in Java 8 with the help of sample programs.

Pre-requisites: Java SE Development Kit 8, Notepad

1. Lambda expressions

Lambda Expressions, a new language feature, has been introduced in this release. They enable you to treat functionality as a method argument, or code as data. Lambda expressions let you express instances of single-method interfaces (referred to as functional interfaces) more compactly.

Create a new Java file called JavaEightTest and write the following code!

JavaEightTest.java

import java.io.*;
import java.lang.*;
import java.util.*;

public class JavaEightTest{

   public static void main(String args[]){
       
      //the old way 
      List<String> names = Arrays.asList("orange", "apples", "grapes", "bananas");
      Collections.sort(names, new Comparator<String>() {
              @Override
              public int compare(String a, String b) {
               return b.compareTo(a);
              }
      });

      //the new way
      Collections.sort(names, (String a, String b) -> b.compareTo(a));

      new Thread(
            () -> System.out.println("Hello from thread")
      ).start();

    }
}

2. Date/Time API’s

The Date-Time APIs, introduced in JDK 8, are a set of packages that model the most important aspects of date and time. The core classes in the java.time package use the calendar system defined in ISO-8601 (based on the Gregorian calendar system) as the default calendar. Other non-ISO calendar systems can be represented using the java.time.chrono package.

Create a new Java file called JavaEightDate and write the following code!

JavaEightDate.java

import java.time.LocalDate;
import java.time.Month;
import java.time.ZoneId;
 
public class JavaEightDate {
 
    public static void main(String[] args) {
         
        //show the current date
        LocalDate today = LocalDate.now();
        System.out.println("Current Date is="+today);
         
        //create LocalDate 
        LocalDate firstDay_2014 = LocalDate.of(2014, Month.JANUARY, 1);
        System.out.println("Specific Date="+firstDay_2014);
                  
        //current date in a specific zone, say "Asia/Kolkata"
        LocalDate todayKolkata = LocalDate.now(ZoneId.of("Asia/Kolkata"));
        System.out.println("Current Date in IST="+todayKolkata);
     
        //getting date from the base date i.e 01/01/1970
        LocalDate dateFromBase = LocalDate.ofEpochDay(365);
        System.out.println("365th day from base date= "+dateFromBase);
       
    }
}

Finally, save all changes. Compile the above Java class using the javac command. If no errors occur then you should see the following output!

output

Reference: What’s New in JDK 8?

AngularJS: Routing

In any web application, navigation is crucial. If users can’t navigate through your application easily, you will quickly lose them. AngularJS provides an out of the box service provider called $routeProvider. Through AngularJS, developers can use routes to create different URLs for different content in an application.

As mentioned in the documentation, the routing functionality in Angular is due to the ngRoute module, which is distributed separately from the core Angular framework. The application’s module needs to declare this dependency in order to use the features provided by the ngRoute module. Through this post, we will learn how to implement routing using AngularJS.

Pre-requisites: Eclipse IDE (for Java EE developers), Apache Tomcat

Step 1: Launch Eclipse IDE and create a new Dynamic Web Project called AngularRouting. Choose the target runtime as Apache Tomcat 7.0

Step 2: Create HTML page

Create a new HTML page called index.html and place it inside the WebContent folder of your web project. In order to implement routing, the first thing to do is add the extra JavaScript inside the head section as follows!

index.html

....
  <head>
    <title>AngularJS Routing tutorial </title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular-route.min.js"></script>
  </head>
....

Next, let’s implement our $routeProvider. The $routeProvider is configured in the module’s config() function via calls to the when() and otherwise() functions.

index.html

....
var app = angular.module("demo",['ngRoute']);
app.config(['$routeProvider',
		  function($routeProvider) {
			$routeProvider.
				when('/ShowResult/:id', {
					templateUrl: 'templates/show_result.html',
					controller: 'ShowResultController'
				}).
				otherwise({
					redirectTo: '/'
				});
		}]);
....

We also need to register the ShowResultController and hence navigate to the new page depending upon the request parameter (in this case id). Here’s how our HTML page finally looks,

index.html

<!DOCTYPE html>
<html ng-app="demo">
  <head>
    <title>AngularJS Routing tutorial </title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular-route.min.js"></script>
  </head>
  <body>
	
	<div ng-controller="TableController">

	    <h2>Student data</h2>
		
		<table>
		    <tr>
			  <th> Id </th>
			  <th> Name </th>
			  <th> Age </th>
			  <th> Email </th>
			  <th> City </th>
			  <th> Action </th>
			</tr>
		   <tr ng-repeat="student in students">
		      <td>{{ student.id }} </td>
		      <td>{{ student.name | uppercase}} </td>
			  <td>{{ student.age }} </td>
			  <td>{{ student.email | lowercase }} </td>
		      <td>{{ student.city | uppercase}} </td>
			  <td> <a href="#ShowResult/{{student.id}}">Show Result</a></td>
		  </tr>	   
		</table>
	 	
		<div ng-view></div>

		
	</div>

	<script type="text/javascript">
		
		var app = angular.module("demo",['ngRoute']);
		app.controller("TableController", function($scope){
		    $scope.students = [
				{ id:"101", name: 'Hari', city: 'Mumbai', email:'hari@gmail.com',age:'16'},
				{ id:"102", name: 'Alexander', city: 'Paris', email:'alex@gmail.com',age:'18'}
			];
		});
		
		app.config(['$routeProvider',
		  function($routeProvider) {
			$routeProvider.
				when('/ShowResult/:id', {
					templateUrl: 'templates/show_result.html',
					controller: 'ShowResultController'
				}).
				otherwise({
					redirectTo: '/'
				});
		}]);
		
		app.controller('ShowResultController', function($scope, $routeParams) {
		    $scope.id = $routeParams.id;
		    
		    if($scope.id == 101){
		    	$scope.message = 'The result for student is passed';
		    }else{
		    	$scope.message = 'The result for student is failed';
		    }
		});
	
	</script>
	
  </body>
</html>

Important: Notice the ngView directive in the above page. Inside the div with the ngView directive (can also be written ng-view) the HTML template specific to the given route will be displayed.

show_result.html

<h2>Show Result</h2>
 
{{ message }}

Finally, save all changes and make sure no errors are present. Run the application on the Tomcat server and you should see the following output!

output

Reference: Routing in AngularJS

Using multiple processes in Android

Hello everyone!

In Android, when an application’s first component starts, a new process for the application with a single thread of execution called main thread or UI Thread gets created. By default, all components of the same application usually run in the same process. A Service when invoked using the startService method from an Activity runs on the main application thread. However, if the Service performs an intensive task then it may cause your application to become unresponsive eventually resulting in an ANR (Application Not Responding) message.

Memory management plays an important role in applications involving multiple processes. As mentioned on the Android developer’s page, one can specify a separate process for each application component by declaring the android:process attribute for each component in the manifest file. For example, one can specify a service to run in a process separate from the application’s main process by declaring a new process named background as follows.

<service android:name= ".MyBackgroundService"
         android:process= ":background" />

Through this post, we will learn how to manage and use multiple processes in Android.

Pre-requisites: Eclipse IDE, Android SDK

Step 1: Create Service class

In any of your existing Android projects, create two new Service classes named FirstService and SecondService respectively.

FirstService.java

package com.example;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class FirstService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i("FirstService", "onStartCommand method is called");
		return Service.START_NOT_STICKY;
	}
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i("FirstService","onCreate Method is called");
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i("FirstService","OnDestroy Method is called");
		super.onDestroy();
	}

	@Override
	public boolean stopService(Intent name) {
		// TODO Auto-generated method stub
		Log.i("FirstService","stopService Method is called");
		return super.stopService(name);
	}

}

SecondService.java

package com.example;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class SecondService extends Service {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.i("SecondService", "onStartCommand method is called");
		return Service.START_NOT_STICKY;
	}
	
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		Log.i("SecondService","onCreate Method is called");
		super.onCreate();
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		Log.i("SecondService","OnDestroy Method is called");
		super.onDestroy();
	}

	@Override
	public boolean stopService(Intent name) {
		// TODO Auto-generated method stub
		Log.i("SecondService","stopService Method is called");
		return super.stopService(name);
	}

}

Note: Make sure you have registered the above Services in the AndroidManifest.xml file as follows!

AndroidManifest.xml

....
<application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.example.TestProcessActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
         <service
            android:name="com.example.FirstService"
            android:process=":firstservice">
        </service>
        <service
            android:name="com.example.SecondService"
            android:process=":secondservice">
        </service>
</application>
....

Step 2: Create Activity class

Create a new Activity class called TestProcessActivity that will include certain methods to call the respective Services.

TestProcessActivity.java

package com.example;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class TestProcessActivity extends Activity {

	private Intent m_objServiceIntent = null; 

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_process);
	}

	public void startFirstService(View view){
		m_objServiceIntent = new Intent(TestProcessActivity.this, FirstService.class);
		startService(m_objServiceIntent);
	}

	public void startSecondService(View view){
		m_objServiceIntent = new Intent(TestProcessActivity.this, SecondService.class);
		startService(m_objServiceIntent);
	}
}

activity_process.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="startFirstService"
        android:text="@string/call_first_service"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="startSecondService"
        android:text="@string/call_second_service"/>

</LinearLayout>

Finally, make sure no errors are present. Save all changes and run the application on an Android device. If no errors occur then you should be able to see the following output!

output_1

Next, you need to call each Service by clicking the respective button.

first_service

second_service

Now, try switching to the DDMS perspective in order to view the multiple processes running on the Android device.

ddms_output

Reference: Multiple Processes in Android

AngularJS: Custom directives

Hello everyone!

Directives play an important role in AngularJS applications allowing developers to interact and hence simplify DOM manipulation. One of the most important features of a web application is reusability. AngularJS helps us to build custom directives that can in turn modify or even create a totally new behavior in HTML. To call a directive from HTML, we can simple apply the directive in the DOM. At present, there are four different types of directives namely,

1. Element directives

An element directive is activated when AngularJS finds a matching HTML element in the HTML template. Angular normalizes an element’s tag and attribute name to determine which elements match which directives.

2. Attribute directives

In HTML, we mention attributes for a particular tag. This tag holds the code snippet. Attribute directives help to write specific code that such tags can simply include.

3. CSS class directives

4. Comment directives

Note: AngularJS recommends that you try to use element and attribute directives, and leave the CSS class and comment directives (unless absolutely necessary).

Through this tutorial, we will learn how to use the element directive in AngularJS.

Pre-requisites: Eclipse IDE (for Java EE developers), Apache Tomcat 7.0

Step 1: Launch Eclipse IDE and create a new Dynamic Web Project called AngularCustomDirectives with module version 3.0. Create the following index.html page in the WebContent folder.

index.html

<!DOCTYPE html>
<html ng-app="demo">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
  </head>
  <body>
	
	<div ng-controller="ListController">
		<customerinfo></customerinfo>
	</div>

	<script type="text/javascript">	
		var app = angular.module("demo",[]);
		app.directive('customerinfo', function() {
			
			var directive = {};
		    directive.restrict = 'E'; /* restrict this directive to elements */
			directive.templateUrl = "html-templates/customerinfo-template.html";
			
			return directive;
			
		});
		
		app.controller("ListController", function($scope){
		    $scope.customers = [
				{ name: 'Hari', city: 'Mumbai', email:'hari@gmail.com',age:'16'},
				{ name: 'Alexander', city: 'Paris', email:'alex@gmail.com',age:'18'}
			];
		});
		
	</script>
	
  </body>
</html>

The restrict field is used to set if the directive should be activated by a matching HTML element, or an element attribute. By setting restrict to E one can specify that only HTML elements named customerinfo should activate the directive.

Step 2: Create a new folder called html-templates under the WebContent folder and create the customerinfo-template.html file as follows.

customerinfo-template.html

	<h2>List of customers</h2>
	<ul>
		<li ng-repeat="customer in customers">
		    Name: {{ customer.name |uppercase}} 
		    Age: {{ customer.age }} 
		    Email: {{ customer.email |lowercase }} 
		    City: {{ customer.city | uppercase}}
		</li>
	</ul>

Save all changes. Make sure no errors are present. Run the project on the Tomcat server to launch the corresponding web page in a browser and you should see the following output!

output

Reference: AngularJS directives

Android Tools: Zipalign

Hello friends!

Android provides developers the zipalign tool to align your .apk file before distributing to end-users. The tool not only provides better optimization but also ensures that that all uncompressed data starts with a particular alignment relative to the start of the file. It is important to note that the zipalign must only be performed after the .apk file has been signed with your private key. If you perform zipalign before signing, then the signing procedure will undo the alignment.

Through this post, we will learn how to use the zipalign tool in Android.

Pre-requisites: Eclipse IDE, Android SDK

How to export signed apk?

Launch Eclipse IDE and switch to your Android project workspace. Choose any of your existing Android projects for which you need to zipalign the .apk. Before generating the signed apk for your Android project, it is necessary to follow the below steps as per the official documentation for signing an application.

1. Check the AndroidManifest.xml and verify that android:debuggable attribute is set to false. The attribute indicates whether or not the application can be debugged, even when running on a device in user mode.

2. Check the android:versionCode and android:versionName attributes. If it is a new version of an existing apk, make sure these values are larger than the previous apk file.

3. Finally, right click your application, go to Android Tools -> Export Signed Application Package and sign the application using a release key certificate (not debug) as mentioned over here.

Running zipalign

Once you have obtained the signed apk, you can use the zipalign tool for optimization. The following command converts the signed apk to a zipalign signed apk that can be uploaded on the Google Play Store.

zipalign -v 4 AndroidRandomExamples.apk AndroidRandomExamples_aligned.apk

Syntax

zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk

The output of the zipalign process is as follows!

Output

Output

Reference: Android ZipAlign

AngularJS: Form validation

Hello everyone!

In my previous post we learnt how to get started with AngularJS. In general, forms and controls provide validation services so that the end user can be notified of invalid input. As mentioned on the developer’s page, the ng-submit directive prevents the default action (which for form means sending the request to the server and reloading the current page). In Angular, one can submit a form either using a button element with an ng-click attribute or by using the ng-submit directive.

Through this post we will learn how to implement form validation in AngularJS.

Pre-requisites: Windows 7, Notepad or any text editor

Launch Notepad or any text editor and create a new HTML page called form_validation.html as follows.

form_validation.html

<!DOCTYPE html>
<html ng-app="demo">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
	
	<style type="text/css">
	    
        .ng-invalid.ng-dirty{
		  border-color: #FA787E;
		}
		
		.ng-valid.ng-dirty{
		  border-color: #78FA89;
		}
	</style>
	
  </head>
  <body>
	
	<div ng-controller="ListController">

	    <h2>List of submissions </h2>  
		<ul>
		   <li ng-repeat="student in students">
		     Name: {{ student.name | uppercase}}
		     Email : {{ student.email | lowercase }}
		     City: {{ student.city | uppercase}}
		  </li>	   
		</ul>
	
		<h2>Please fill the below form</h2>
		
		<form ng-controller="FormController" name="myForm" ng-submit="myForm.$valid && addStudent(student)" novalidate>
		
    	  Name: <input type="text" ng-model="student.name" placeholder="Enter your name" required/> <br>
		  Email: <input type="email" ng-model="student.email" placeholder= "Enter your email addresss" required/> <br>
		  City: <input type="text" ng-model="student.city" placeholder="Enter your city"/> <br>
		  
		 <input type="submit" value="Submit"/>
	
		</form>
		 	
	</div>

	<script type="text/javascript">
		
		var app = angular.module("demo",[]);
		app.controller("ListController", function($scope){
		    $scope.students = [
				{ name: 'Hari', city: 'Mumbai', email:'hari@gmail.com'},
				{ name: 'Alexander', city: 'Paris', email:'alex@gmail.com'}
			];
		});
		
		app.controller("FormController", function($scope){
			$scope.addStudent = function(student){
				$scope.students.push(student);
			};
		});
		
	</script>
	
  </body>
</html>

Open the above page in a web browser. If no errors occur then you should see the following output before and after the form submission!

output_1

output_2

That’s it for this AngularJS tip. Stay tuned for more! πŸ™‚

Getting started with AngularJS!

The web is constantly evolving. Earlier, when a browser sent a request to the web server, the server would respond with the corresponding webpage & assets required to load the page. However, when a user clicked a link on the page, the browser would download the same files again. AngularJS is an open source web application framework designed to overcome such limitations. It is maintained by Google and the community at large.

AngularJS is by far one of the most popular technologies for developing MVC based web applications. It supports rapid front end development including features such as two way data binding, dependency injection, custom directives etc with the goal of improving testability and performance. Through this post, we will learn how to get started with AngularJS.

Pre-requisites: Windows 7, Notepad or any text editor, JavaScript

Modules

Modules are used to define applications. A module acts as a container for the different parts of an app, including directives, controllers, services etc. All application controllers should belong to a module. For example,

<div ng-app="demo">
 {{ Hello, Angular!}}
</div>

A reference has been made to the demo module using the ng-app directive.

Directives

AngularJS directives are basically extended HTML attributes with the prefix ng-. As mentioned on the developer’s page, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS’s HTML compiler ($compile) to attach a specified behavior to that DOM element or even transform the DOM element and its children.

Controllers

In Angular, a Controller is a JavaScript constructor function that is used to augment the Angular Scope. A Controller is attached to the DOM via the ng-controller directive.

Now, it’s time to implement the above concepts using an example. Let’s create an HTML page called test.html and write the following code.

test.html

<!DOCTYPE html>
<html ng-app="demo">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
  </head>
  <body>
	<div>
      <input type="text" ng-model="userName" placeholder="Enter a name here">
        Hello, {{ userName}}!
    </div>
	
	<h2>List of students</h2>
	<div ng-controller="ListController">
		<ul>
		   <li ng-repeat="student in students">{{ student.studentName | uppercase}}</li>	   
		</ul>
	</div>

	<script type="text/javascript">
		
		var app = angular.module("demo",[]);
		app.controller('ListController', function($scope) {
			$scope.students = [
				{ studentName: 'Hari', city: 'Mumbai'},
				{ studentName: 'Alexander', city: 'Paris'},
				{ studentName: 'Zen', city: 'Tokyo'},
				{ studentName: 'Benjamin', city: 'New York'}
			];
		});   
	</script>
	
  </body>
</html>

The above example demonstrates the use of the ng-app and the ng-controller directive. It also explains data binding using AngularJS. If you open the page in a web browser you should see the following output.

output

In the upcoming tutorials we will learn how to use some more features of Angular JS. Till then happy coding! πŸ™‚

Reference: Angular JS Developer Guide