Tutorial #101: Getting started with Flurry Analytics in Android

Hello everyone!

Now-a-days, developers keep track of user activity and generate useful statistics about an application. Hence, analytics plays an important role in mobile applications. There are plenty of analytics solutions that exists in the market today. For example, ACRA is a library enabling Android Application to automatically post their crash reports to a GoogleDoc form. It is targetted to Android application developers to help them get data from their applications when they crash or behave erroneously.

Through this post, we will learn how to integrate the get started with the Flurry Analytics SDK in Android. The Flurry Analytics SDK provides you with the tools and resources you need to gain a deep level of understanding about your user’s behavior in your apps. Set up advanced analysis of complex events, with metrics, segments and funnels to better track your user’s habits and performance.

Pre-requisites: Eclipse IDE, Android SDK, Flurry Developer Account

Step 1: Sign up for Flurry developer account

First, you need to create a developer account by signing up over here. Once the account is created, download the required SDK. Now, login into your account and create a new application that will display all the analytical information.

Step 2: Create Android application project

Launch Eclipse IDE and a create a new Android application project called AndroidFlurryAnalyticsDemo with package name com.app.flurry.android. Copy the FlurryAnalytics.jar file inside the libs folder of your Android project.

Step 3: Initialize Flurry and simulate a crash

Create a new class called FlurryApplication that extends the Application class in Android. This class will initialize Flurry on application launch.

FlurryApplication.java

package com.app.flurry.application;

import android.app.Application;
import com.app.flurry.utils.AppConstants;
import com.flurry.android.FlurryAgent;

public class FlurryApplication extends Application {
	@Override
	public void onCreate() {
	super.onCreate();

        //set log enabled
        FlurryAgent.setLogEnabled(true);

        //set log events
        FlurryAgent.setLogEvents(true);
        
        // initialize Flurry
        FlurryAgent.init(this, AppConstants.FLURRY_API_KEY);
    }
}

Next, let us simulate a crash event in our Activity class as follows!

MainActivity.java

package com.app.flurry.main;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.app.flurry.android.R;
import com.app.flurry.utils.AppConstants;
import com.flurry.android.FlurryAgent;

public class MainActivity extends Activity {

	private Button m_objBtnPrint;
	private String m_strName = null;

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

		m_objBtnPrint = (Button)findViewById(R.id.btnPrint);
		m_objBtnPrint.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				FlurryAgent.onEvent("click button");	
				simulateCrashEvent();
			}
		});
	}

	public void simulateCrashEvent(){
		try{
			m_strName.concat("This will result in null pointer exception");
		}catch(Exception ex){
			ex.printStackTrace();
			FlurryAgent.onError("error", "Error occurred on click of button", ex); 		
		}
		FlurryAgent.logEvent("print button clicked");	
	}

	@Override
	protected void onStart(){
		super.onStart();
		FlurryAgent.onStartSession(this, AppConstants.FLURRY_API_KEY);
	}

	@Override
	protected void onStop(){
		super.onStop();		
		FlurryAgent.onEndSession(this);
	}
}

activity_main.xml

<RelativeLayout 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"
    tools:context="${relativePackage}.${activityClass}" >

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

    <Button
        android:id="@+id/btnPrint"
        android:layout_below="@+id/txt1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/print" />

</RelativeLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.app.flurry.android"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />

    <!-- required permission -->
    <uses-permission android:name="android.permission.INTERNET" />
    <!-- optional permission - highly recommended -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- optional permission -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:name="com.app.flurry.application.FlurryApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name="com.app.flurry.main.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
    </application>

</manifest>

Save all changes and run the application on an Android device. If no errors occur, then you should see the following output from the dashboard page of the Flurry application.

crashes_page

events_page

users_page

Source code for this tutorial can be found over here

Reference: Flurry SDK Developer’s page

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! 🙂

Long time no see!

Hello everyone!

It has been more than a year now since I last posted an article over here. 2015 has been a very busy year. However, the entire experience of learning something new has helped me develop both personally and professionally; even as things continue to change drastically in the world of technology and every day there is some new gadget or some new SDK that is being launched by software companies around the globe.

AngularJS has now become popular among web developers. I got an opportunity to work on a live web application project that involved the use of this so called superheroic framework, and the end result was quite satisfying!

Augmented Reality has been around for many years now and it was a high time for me to get the hang of it. Using Metaio’s augmented reality SDK for Android, I learnt how to create and interact with 2D and 3D artifacts in realtime. Some of the key learnings in this space would include image recognition, detecting 3D models without using markers and understanding the concept of location based augmented reality. The sheer joy of applying the concept of Augmented Reality in applications on wearable devices was just like an icing on the cake.

The Wowza live streaming media server still continues to be my prime source of R&D. Two way live video streaming is what I am currently working on using the Wowza Media Server API’s and I hope it bears fruit soon. After having worked on the conventional and enterprise driven Oracle database, I have slowly started moving towards NoSQL databases including MongoDB and Firebase.

Finally, thanks to my parents for their constant support and encouragement. Special thanks to my colleagues at work who have helped me whenever required. From here on, I will try and get back to blogging and share as much information as I can with all you tech-hungry folks! 🙂

Tutorial #100: The Switch from KitKat to Lollipop!

Hey everyone!

The new Android version release has brought few changes in the way developers used certain widgets to create layouts. For instance, starting from Lollipop, Android introduces a new Toolbar widget. As mentioned by Chris Banes in this post, the Toolbar widget is a generalization of the Action Bar pattern that gives developers much more control and flexibility. Similarly, Android has made a “switch” in the way the current Switch widget is implemented.

As mentioned on the developer’s page, a Switch is a two-state toggle switch widget that can select between two options. The user may drag the “thumb” back and forth to choose the selected option, or simply tap to toggle as if it were a checkbox. Through this tutorial, we will learn how to implement the Switch widget in Android.

Pre-requisites: Eclipse IDE, Android SDK

Step 1: Create a new Activity class called TestSwitchActivity in any of your existing Android projects and write the following code,

TestSwitchActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Switch;
import android.widget.TextView;

public class TestSwitchActivity extends Activity {

	private TextView m_tvSwitchStatus;
	private Switch m_objSwitch;

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

		m_tvSwitchStatus = (TextView) findViewById(R.id.switchStatus);
		m_objSwitch = (Switch) findViewById(R.id.sampleSwitch);

		//set the switch to ON 
		m_objSwitch.setChecked(true);
		//attach a listener to check for changes in state
		m_objSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(CompoundButton buttonView,
					boolean isChecked) {

				if(isChecked){
					m_tvSwitchStatus.setText("Switch is currently ON");
				}else{
					m_tvSwitchStatus.setText("Switch is currently OFF");
				}

			}
		});

		if(m_objSwitch.isChecked()){
			m_tvSwitchStatus.setText("Switch is currently ON");
		}
		else {
			m_tvSwitchStatus.setText("Switch is currently OFF");
		}
	}
}

Step 2: Create Switch widget

In previous versions of Android, we would implement a Switch widget in our layout as follows,

activity_switch.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:padding="5dp">

    <Switch
        android:id="@+id/sampleSwitch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="20dp"
        android:text="@string/action" />

    <TextView
        android:id="@+id/switchStatus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/sampleSwitch"
        android:layout_marginTop="22dp"
        android:text="@string/status"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

According to recent changes, the Switch widget can now be implemented using SwitchCompat. The difference is that it does not make any attempt to use the platform provided widget on those devices which it is available normally.

activity_switch.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="5dp" >

    <android.support.v7.widget.SwitchCompat
        android:id="@+id/sampleSwitch"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop="20dp"
        android:text="@string/action"
        android:thumb="@drawable/thumb_pressed"
        android:track="@drawable/bg"/>

    <TextView
        android:id="@+id/switchStatus"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/sampleSwitch"
        android:layout_marginTop="22dp"
        android:text="@string/status"
        android:textAppearance="?android:attr/textAppearanceMedium" />

</RelativeLayout>

In this case, our Activity file would be as follows,

TestSwitchActivity.java

package com.app.lollipop.test;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.SwitchCompat;
import android.util.Log;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;

public class TestSwitchActivity extends Activity {

	private TextView m_tvSwitchStatus;
	private SwitchCompat m_objSwitch;

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

		try {

			m_tvSwitchStatus = (TextView) findViewById(R.id.switchStatus);
			m_objSwitch = (SwitchCompat)findViewById(R.id.sampleSwitch);
			m_objSwitch.setThumbResource(R.drawable.apptheme_switch_thumb_holo_light);
			m_objSwitch.setTrackResource(R.drawable.apptheme_switch_track_holo_light);
			m_objSwitch.setTextOn("ON");
			m_objSwitch.setTextOff("OFF");
			
			//set the switch to ON 
			m_objSwitch.setChecked(true);
			//attach a listener to check for changes in state
			m_objSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {

				@Override
				public void onCheckedChanged(CompoundButton buttonView,
						boolean isChecked) {

					if(isChecked){
						m_tvSwitchStatus.setText("Switch is currently ON");
					}else{
						m_tvSwitchStatus.setText("Switch is currently OFF");
					}

				}
			});

			if(m_objSwitch.isChecked()){
				m_tvSwitchStatus.setText("Switch is currently ON");
			}
			else {
				m_tvSwitchStatus.setText("Switch is currently OFF");
			}
		}catch(Exception e){
			e.printStackTrace();
			Log.i("App", "Error occurred due to" +e.getMessage());
		}
	}
}

Finally, save all changes and run the Android application project on an emulator or a real device. If no errors occur then you should see the following output!

Android Switch on Pre Lollipop versions

Android Switch on Pre Lollipop versions

Android Switch on Lollipop

Android Switch on Lollipop

From here on, we will learn more about the recent changes in Android 5.0. We will also try to implement the same in the upcoming tutorials.

Reference: Android Switch

Tutorial #99: Send e-mail using JavaMail in JSP

Hi everyone!

JavaMail is a well known Java API used to send and receive email via SMTP, POP3 and IMAP. It mainly provides a platform-independent and protocol-independent framework to build mail and messaging applications. In addition, the JavaMail API package is also included in the Java EE platform.

JavaMail facilitates the sending of an e-mail via Gmail SMTP server, using both TLS and SSL connection. Through this tutorial, we will learn how to send an e-mail using JavaMail in a sample JSP page.

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

Step 1: Create new Dynamic web project

Launch Eclipse IDE and create a new Dynamic web project called SendEmailUsingJSP with target runtime as Apache Tomcat 7.

Step 2: Add external jar files

In order to implement the sending of an e-mail, developers need to download and use the latest version of the JavaMail API in their web projects. For this tutorial, I will be using the mail-1.4.7.jar version of the JavaMail API. Make sure you add the .jar file in the WEB-INF/lib folder of your web project.

Step 3: Create JSP page

Create a new index.jsp page inside the WebContent folder of your web project and write the following code.

index.jsp

<%@ pageimport="javax.servlet.http.*,javax.servlet.*" %>
<%@ page import="javax.mail.internet.*,javax.activation.*"%>
<%@ page import="java.io.*,java.util.*,javax.mail.*"%>
<%

    //username for abc@gmail.com will be "abc"
	String username = "sender_username";
	String password = "sender_password";
	String result = null;

	try {
		
        Properties props = System.getProperties();
		props.setProperty("mail.transport.protocol", "smtp");
		props.setProperty("mail.host", "smtp.gmail.com");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.port", "465");
		props.put("mail.debug", "true");
		props.put("mail.smtp.socketFactory.port", "465");
		props.put("mail.smtp.socketFactory.class",
				"javax.net.ssl.SSLSocketFactory");
		props.put("mail.smtp.socketFactory.fallback", "false");

		Session emailSession = Session.getInstance(props,
				new javax.mail.Authenticator() {
					protected PasswordAuthentication getPasswordAuthentication() {
					return new PasswordAuthentication("sender_username","sender_password");
				}
		});

		emailSession.setDebug(true);
		Message message = new MimeMessage(emailSession);
		message.setFrom(new InternetAddress(
				"sender_username@gmail.com"));
		message.setRecipients(Message.RecipientType.TO,
				InternetAddress.parse("xyz@hotmail.com"));
		message.setSubject("Test mail from Java");
		message.setText("Hello. this is a test");

		Transport transport = emailSession.getTransport("smtps");
		transport.connect("smtp.gmail.com", username, password);
		transport.sendMessage(message, message.getAllRecipients());

		result = "Successfully sent email";

	   } catch (MessagingException e) {
		result = "Unable to send email";
	}
%>
<html>
<head>
<title>Send Email using JSP</title>
</head>
<body>
	<center>
		<h1>Send Email using JSP</h1>
	</center>
	<p align="center">
		<%
			out.println("Result: " + result + "\n");
		%>
	</p>
</body>
</html>

Finally, save all changes and run the application on the Tomcat server. If no errors occur then you should see the following output!

output

Reference: JavaMail API

Tutorial #98: Calling web services using PL/SQL in Oracle

Web services are widely used to as a means of communication between two multiple devices. Oracle also allows developers to consume web services using certain built-in packages. Moreover, one can extend a relational database’s storage, indexing, and searching capabilities to include web services. Through this tutorial, we will learn how to call a simple web service using PL/SQL in Oracle. We would using a public testing platform for services utilizing JavaScript Object Notation (JSON).

Pre-requisites: Oracle 11gR2 database with *SQLPlus, Windows 7 (64 bit)

Step 1: Writing the PL/SQL query

Open the SQL Plus command prompt and login using your database credentials. Once logged in successfully execute the following command in order to enable DBMS_OUTPUT statements.

set serveroutput on

In order to call web services, Oracle provides the UTL_HTTP package. It helps make hyper-text transfer protocol (HTTP) callouts from PL/SQL and SQL. One can use it to access data on the Internet or to call Oracle Web Server cartridges. We would be creating a stored procedure to use the same. Our PL/SQL procedure would be as follows,

create or replace procedure call_webservice as
  t_http_req  utl_http.req;
  t_http_resp  utl_http.resp; 
  t_response_text VARCHAR2 (2000);

begin
 
  t_http_req:= utl_http.begin_request('http://date.jsontest.com/','GET','HTTP/1.1');
  t_http_resp:= utl_http.get_response(t_http_req);
  UTL_HTTP.read_text(t_http_resp, t_response_text);
  DBMS_OUTPUT.put_line('Response> status_code: "' || t_http_resp.status_code || '"');
  DBMS_OUTPUT.put_line('Response> reason_phrase: "' ||t_http_resp.reason_phrase || '"');    
  DBMS_OUTPUT.put_line('Response> data:' ||t_response_text); 
  utl_http.end_response(t_http_resp);
 
end;

create_procedure

Step 2: Executing the PL/SQL query

Now, execute the above PL/SQL procedure using the below command,

exec call_webservice

Once the procedure has executed successfully you will see the following output,

execute_procedure

Reference: UTL_HTTP in Oracle

Tutorial #97: Generate multi-language PDF using iText in Java

Hi everyone,

iText is a PDF software that can be used to create PDF documents dynamically using Java, .NET, Android etc. Based on the comments I received of late, iText can be used to generate multi-language PDF documents for Java, web and other applications.

iTextG is a special version of iText built for Android and Google App Engine.

Differences between the iText core library and the Android/GAE port are as follows,

1. iTextG uses SpongyCastle instead of Bouncy Castle. Make sure to download and include the right jars namely scprov-jdk15on and scpkix-jdk15on.

2. References to any of the classes not on the Google App Engine whitelist have been removed.

Through this tutorial, we will learn how to generate a multi-language PDF using the iText library in Java.

Pre-requisites: Eclipse IDE, Windows 7 (64 bit), iText software ( itext-2.1.7.jar)

Launch Eclipse IDE and create a new Java console application project called JavaPDFGeneration with package name com.app.generate. Create a new Java class called GeneratePDF and add the following code!

GeneratePDF.java

package com.app.pdfgenerate;

import java.io.FileOutputStream;
import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.HeaderFooter;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

public class GeneratePDF {
	
    public static void main(String arg[]) throws Exception {
              
       try {
                       
            Document document = new Document();
			String encoding = "Identity-H";
			Font fontNormal = FontFactory.getFont(("F:/programs/pdf/fonts/Roboto-Black.ttf"), encoding,BaseFont.EMBEDDED, 8, Font.NORMAL);
			PdfWriter.getInstance(document, new FileOutputStream("F:/programs/pdf/test.pdf"));
			HeaderFooter header = new HeaderFooter(new Paragraph("Header", fontNormal), false);
			HeaderFooter footer = new HeaderFooter(new Paragraph("footer", fontNormal), false);
			document.setHeader(header);
			document.setFooter(footer);
			document.open();

			Chunk chunkEnglish = new Chunk("Hello World " + "\n", fontNormal);
			Chunk chunkBrazil = new Chunk("Olá Mundo " + "\n", fontNormal);

			PdfPTable table = new PdfPTable(2);
			table.addCell("Locale");
			table.addCell("Translated Text");

			PdfPCell cellEnglish = new PdfPCell(new Phrase(chunkEnglish));
			table.addCell(new PdfPCell(new Phrase(new Chunk("English",fontNormal))));
			table.addCell(cellEnglish);

			PdfPCell cellBrazil = new PdfPCell(new Phrase(chunkBrazil));
			table.addCell(new PdfPCell(new Phrase(new Chunk("Brazil",fontNormal))));
			table.addCell(cellBrazil);

			document.add(table);
			document.close();

			System.out.println("PDF generation complete....");
	
		  } catch (Exception e) {
			System.out.println("Error occurred while generating PDF" + e.getMessage());
			e.printStackTrace();
	      }
   }
}

Save all changes and run the application. If no errors occur then you should see the PDF file (test.pdf) created in the specified output directory.

output

Reference: iText library

Tutorial #96: Implement multi-language support in Android

Hey friends!

Today, Android has become one of the dominant mobile operating systems in the world. Android applications are now used by people living across the globe. It is important for developers to build applications that can support multiple languages. In order to reach maximum users, an application should handle text, audio files, numbers, currency, and graphics in ways appropriate to the locales where it will be used.

By default Android considers English as the primary language and loads the string resources from res/values/strings.xml file. In order to add support for another language, one needs to create a values folder by appending an hyphen and the ISO language code. For example if you want to add support for French, you should create a values folder named values-fr and keep a strings.xml file in it with all the strings translated into French language.

As mentioned on the developer’s page, it’s always a good practice to extract UI strings from your application code and keep them in an external file. Through this tutorial, we will learn how to implement multi-language support in Android.

Pre-requisites: Eclipse IDE, Android SDK

Step 1: Create Android project

Launch Eclipse IDE and create a new Android application project called AndroidMultiLanguageSupportDemo. Let’s keep the package name as com.app.multilanguage. Choose the target SDK as Android 4.4 (API level 19)

Step 2: Add multi-language support

As mentioned earlier, we need to create multiple values folder for the appropriate language depending on the language code as follows!

res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello_world">Hello world!</string>
</resources>

res/values-fr/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <string name="hello_world">bonjour le monde!</string>
</resources>

MainActivity.java

package com.app.multilanguage;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

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

res/layout/activity_main.xml

<RelativeLayout 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"
    tools:context="${relativePackage}.${activityClass}">

    <TextView
        android:id="@+id/txtView"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="24sp"
        android:textColor="#FE2E2E"
        android:text="@string/hello_world" />

</RelativeLayout>

Finally, save all changes. Make sure no errors are present. Run the application on an Android device and you should see the following output for the respective languages.

English

English

Japanese

Japanese

Hindi

Hindi

French

French

That’s it for this tutorial. Hope it helps! 🙂

Reference: Supporting different languages