Using Menus in Android

Hey everyone!

[This is a long overdue post]

The Android mobile user interface has been constantly evolving. Beginning with Android 3.0, devices no longer provide a dedicated Menu button. However, in order to provide a consistent user experience, developers need to use the Menu API’s to present common user actions on devices running Gingerbread (2.3.3) and below.

Android provides three different types of menus. The options menu is the primary collection of menu items for an activity. Users can open the options menu panel by pressing the Menu button. A context menu is a floating menu that appears when the user performs a long-click on an element. For example, long press an item of a ListView to obtain the corresponding menu. Finally, a popup menu displays a list of items in a vertical list that’s anchored to the view that invoked the menu.

Through this post, we will learn how to implement an options and a context menu in Android.

Pre-requisites: Eclipse IDE, Android SDK (Target SDK 2.3.3)

Step 1: Create options menu

In order to create an options menu, we need to first define it using XML as follows. Create a new XML file called menu_option.xml in the res/menu directory of any of your existing Android projects.

menu_option.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/menu_apple"
        android:title="Apple"/>
    <item
        android:id="@+id/menu_orange"
        android:title="Orange"/>
    <item
        android:id="@+id/menu_mango"
        android:title="Mango"/>
    <item
        android:id="@+id/menu_image"
        android:icon="@drawable/ic_launcher"
        android:title="Image"/>

</menu>

Step 2: Now let’s create an Activity class called MyMenuActivity and add the following code!

MyMenuActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

public class MyMenuActivity extends Activity{

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

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		MenuInflater menuInflater = getMenuInflater();
		menuInflater.inflate(R.menu.menu_option, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()){
		case R.id.menu_apple:
			Toast.makeText(MyMenuActivity.this, "You selected apple", Toast.LENGTH_SHORT).show();
			return true;

		case R.id.menu_orange:
			Toast.makeText(MyMenuActivity.this, "You selected orange", Toast.LENGTH_SHORT).show();
			return true;

		case R.id.menu_mango:
			Toast.makeText(MyMenuActivity.this, "You selected mango", Toast.LENGTH_SHORT).show();
			return true;

		case R.id.menu_image:
			Toast.makeText(MyMenuActivity.this, "You selected an image", Toast.LENGTH_SHORT).show();
			return true;

		default:
			return super.onOptionsItemSelected(item);
		}
	}
}

activity_menu_option.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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_centerInParent="true"
        android:text="@string/hello_world"
        android:layout_height="wrap_content" />

</RelativeLayout>

Step 3: Create context menu

In order to implement a context menu, we need to create a ListView as follows!

activity_menu_context.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">  
  
    <ListView  
        android:id="@+id/listView1"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:layout_alignParentLeft="true"  
        android:layout_alignParentTop="true">  
    </ListView>  
  
</RelativeLayout>  

We then need to modify our MyMenuActivity class to now display a context menu instead of an option menu.

MyMenuActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MyMenuActivity extends Activity{

	private ListView m_listView;
	private String countries[]={"India","Spain","Portugal","Germany","France"};  

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

		m_listView=(ListView)findViewById(R.id.listView1);  

		ArrayAdapter<String> adapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,countries);  
		m_listView.setAdapter(adapter);  

		registerForContextMenu(m_listView);  

	}


	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
		// TODO Auto-generated method stub
		super.onCreateContextMenu(menu, v, menuInfo);  
		menu.setHeaderTitle("Select the option");    
		menu.add(0, v.getId(), 0, "Population");  
		menu.add(0, v.getId(), 0, "States");   
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		if(item.getTitle()=="Population"){  
			Toast.makeText(getApplicationContext(),"this will fetch the population",Toast.LENGTH_LONG).show();  
		}    
		else if(item.getTitle()=="States"){  
			Toast.makeText(getApplicationContext(),"this will fetch the number of states",Toast.LENGTH_LONG).show();  
		}else{  
			return false;  
		}    
		return true;    
	}  

}

Finally, save all changes. Make sure no errors are present. Run the application on an Android device/emulator and you should see the respective menus in Android.

option_menu_1

option_menu_2

context_menu_1

context_menu_2

context_menu_3

Reference: Android Menus

Tutorial #87: Implement ContentProvider in Android

Hey everyone!

As developers, we often need to create applications that can share data with other applications residing on the Android device. A content provider is similar to a database where one can query it, edit its content, as well as add or delete content using insert, update, delete, and query methods.

As mentioned on the developer’s page, Content providers manage access to a structured set of data. They encapsulate the data, and provide mechanisms for defining data security. In this tutorial, we will learn how to implement a Content provider in Android.

Pre-requisites: Eclipse IDE, Android SDK

Step 1: Create Android project

Launch Eclipse IDE and create a new Android application project called AndroidContentProviderExample with package name com.app.myprovider and choose the target SDK as Android 4.4

Step 2: Create ContentProvider class

Let’s write our own ContentProvider that will enable users to add a particular name in the Student table of the College database. Create a new class called MyProvider and write the following code!

MyProvider.java

package com.app.myprovider;

import java.util.HashMap;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

public class MyProvider extends ContentProvider {

	public static final String PROVIDER_NAME = "com.app.provider.Names";
	public static final String URL = "content://" + PROVIDER_NAME + "/names";
	public static final Uri CONTENT_URI = Uri.parse(URL);
	public static final String NAME = "name";
	public static final String ID = "id";
	private static HashMap<String, String> namesMap;

	//database variables
	DBHelper dbHelper;
	private SQLiteDatabase database;
	static final String DATABASE_NAME = "College";
	static final String TABLE_NAME = "Student";
	static final int DATABASE_VERSION = 1;
	static final String CREATE_TABLE = 
			" CREATE TABLE " + TABLE_NAME +
			" (id INTEGER PRIMARY KEY AUTOINCREMENT, " + 
			" name TEXT NOT NULL);";

	// integer values used in content URI
	static final int NAMES = 1;
	static final int NAMES_ID = 2;
	static final UriMatcher uriMatcher;
	static{
		uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
		uriMatcher.addURI(PROVIDER_NAME, "names", NAMES);
		uriMatcher.addURI(PROVIDER_NAME, "names/#", NAMES_ID);
	}

	@Override
	public boolean onCreate() {
		// TODO Auto-generated method stub
		Context context = getContext();
		dbHelper = new DBHelper(context);
		// permissions to be writable
		database = dbHelper.getWritableDatabase();

		if(database == null)
			return false;
		else
			return true;	
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// TODO Auto-generated method stub
		SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
		queryBuilder.setTables(TABLE_NAME);

		switch (uriMatcher.match(uri)) {
		// maps all database column names
		case NAMES:
			queryBuilder.setProjectionMap(namesMap);
			break;
		case NAMES_ID:
			queryBuilder.appendWhere( ID + "=" + uri.getLastPathSegment());
			break;
		default:
			throw new IllegalArgumentException("Unknown URI " + uri);
		}
		if (sortOrder == null || sortOrder == ""){
			sortOrder = NAME;
		}
		Cursor cursor = queryBuilder.query(database, projection, selection, 
				selectionArgs, null, null, sortOrder);
		cursor.setNotificationUri(getContext().getContentResolver(), uri);

		return cursor;
	}

	@Override
	public String getType(Uri uri) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		long row = database.insert(TABLE_NAME, "", values);

		// If record is added successfully
		if(row > 0) {
			Uri newUri = ContentUris.withAppendedId(CONTENT_URI, row);
			getContext().getContentResolver().notifyChange(newUri, null);
			return newUri;
		}
		throw new SQLException("Fail to add a new record into " + uri);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// TODO Auto-generated method stub
		int count = 0;

		switch (uriMatcher.match(uri)){
		case NAMES:
			// delete all the records of the table
			count = database.delete(TABLE_NAME, selection, selectionArgs);
			break;
		case NAMES_ID:
			//gets the id
			String id = uri.getLastPathSegment();		
			count = database.delete( TABLE_NAME, ID +  " = " + id + 
					(!TextUtils.isEmpty(selection) ? " AND (" + 
							selection + ')' : ""), selectionArgs);
			break;
		default: 
			throw new IllegalArgumentException("Unsupported URI " + uri);
		}

		getContext().getContentResolver().notifyChange(uri, null);
		return count;
	}

	@Override
	public int update(Uri uri, ContentValues values, String selection,
			String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}


	private static class DBHelper extends SQLiteOpenHelper {

		public DBHelper(Context context) {
			super(context, DATABASE_NAME, null, DATABASE_VERSION);
			// TODO Auto-generated constructor stub
		}

		@Override
		public void onCreate(SQLiteDatabase db) {
			// TODO Auto-generated method stub
			db.execSQL(CREATE_TABLE);
		}

		@Override
		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
			// TODO Auto-generated method stub
			Log.w(DBHelper.class.getName(),
					"Upgrading database");
			db.execSQL("DROP TABLE IF EXISTS " +  TABLE_NAME);
			onCreate(db);
		}

	}


}

Step 3: Create Activity class

Next, let’s create our Activity class called MainActivity that will allow user to add, delete or show the respective values.

MainActivity.java

package com.app.myprovider;

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

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

        //delete all the records and the table of the database provider
	public void deleteAllNames(View view) {
		String URL = "content://com.app.provider.Names/names";
		Uri friends = Uri.parse(URL);
		int count = getContentResolver().delete(
				friends, null, null);
		String countNum = "App: "+ count +" records are deleted.";
		Toast.makeText(getBaseContext(), 
				countNum, Toast.LENGTH_LONG).show();

	}

        //add a new name
	public void addName(View view) {
		ContentValues values = new ContentValues();

		values.put(MyProvider.NAME, 
				((EditText)findViewById(R.id.name)).getText().toString());

		Uri uri = getContentResolver().insert(
				MyProvider.CONTENT_URI, values);

		Toast.makeText(getBaseContext(), 
				"App:" + uri.toString() + " inserted!", Toast.LENGTH_LONG).show();
	}

        //display all names
	public void showAllNames(View view) {
		String URL = "content://com.app.provider.Names/names";
		Uri friends = Uri.parse(URL);
		Cursor c = getContentResolver().query(friends, null, null, null, "name");
		String result = "App Results:";

		if (!c.moveToFirst()) {
			Toast.makeText(this, result+" no content yet!", Toast.LENGTH_LONG).show();
		}else{
			do{
				result = result + "\n" + c.getString(c.getColumnIndex(MyProvider.NAME)); 
			} while (c.moveToNext());
			Toast.makeText(this, result, Toast.LENGTH_LONG).show();
		}

	}

}

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}" >

    <EditText
        android:id="@+id/name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="@string/name" />

    <Button
        android:id="@+id/btnAdd"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/name"
        android:layout_marginTop="30dp"
        android:onClick="addName"
        android:text="@string/add" />

    <Button
        android:id="@+id/btnShow"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/btnAdd"
        android:layout_below="@+id/btnAdd"
        android:layout_marginTop="20dp"
        android:onClick="showAllNames"
        android:text="@string/show" />

    <Button
        android:id="@+id/btnDelete"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/btnShow"
        android:layout_below="@+id/btnShow"
        android:layout_marginTop="20dp"
        android:onClick="deleteAllNames"
        android:text="@string/delete" />

</RelativeLayout>

strings.xml

    <string name="name">Name</string>
    <string name="add">Add a new name</string>
    <string name="show">Show all names</string>
    <string name="delete">Delete all names</string>

Step 4: Register Provider in Manifest file

Further, for Android to use our provider it is important to register the same in the AndroidManifest.xml as follows!

AndroidManifest.xml

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

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".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>

        <provider
            android:name=".MyProvider"
            android:authorities="com.app.provider.Names" >
        </provider>

    </application>
</manifest>

Finally, make sure no errors are present. Run the application on an Android device and you should be able to insert, delete and display the list of names as follows! πŸ™‚

output_1

output_2

output_3

output_4

Reference: Android Content Providers

Display incoming SMS messages in Android

Hi guys,

In the past, we have seen how a Broadcast Receiver can be used to listen to certain events and in turn notify the user when the particular event occurs. In general, a broadcast originates from the system as well as applications.

It is important to register a broadcast receiver for a particular action. One of the ways of registering the same is by using the receiver tag in the AndroidManifest.xml file. Through this post, we will learn how to listen to incoming SMS text messages in Android using a broadcast receiver.

Pre-requisites: Eclipse IDE, Android SDK

Launch Eclipse IDE and in any of your existing Android application projects create a new class called MySMSApp and add the following code.

MySMSApp.java

package com.example;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;

public class MySMSApp extends BroadcastReceiver {

	public static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		if (intent.getAction().equals(ACTION)){ 
			Bundle bundle = intent.getExtras();
			if (bundle != null){
				Object[] pdus = (Object[]) bundle.get("pdus");
				SmsMessage[] messages = new SmsMessage[pdus.length];
				for (int i = 0; i < pdus.length; i++){
					messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
				}
				for (SmsMessage message : messages){
					
					String strMessageFrom = message.getDisplayOriginatingAddress();
					String strMessageBody = message.getDisplayMessageBody();

					Toast.makeText(context, "SMS Message received from:" +strMessageFrom, Toast.LENGTH_LONG).show();
					Toast.makeText(context, "SMS Message content" +strMessageBody, Toast.LENGTH_LONG).show();

				}
			}    
		} 
	}

}

Once we have implemented our receiver class, it is important to register the same in the AndroidManifest.xml file as follows.

AndroidManifest.xml

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

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

    <application
        android:allowBackup="true"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.SomeDummyActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- Receiver for SMS -->
        <receiver android:name=".MySMSApp">
            <intent-filter>
                <action android:name="android.provider.Telephony.SMS_RECEIVED" />
            </intent-filter>
        </receiver>

    </application>

</manifest>

Save all changes. Make sure no errors are present. Run the application on an Android device. The next time you get an SMS message, you should see the following output!

output

That’s it for this Android tip. Still lots more to come…! πŸ™‚

Implement DialogFragment in Android

Hello everyone!

Users often need to make certain choices while using an application. A dialog resembles a small window that helps the user to make a decision or enter any additional information. If an application consists of a number of dialogs, one would possibly go ahead and create multiple “Yes/No” dialogs. However, if fragments are used within your Activity, then you need to use DialogFragment in order to present a fragment as a dialog (window). A simple Dialog won’t help in this case as it has nothing to do with the fragment’s life-cycle.

DialogFragments and Fragments are made available in the support library which makes the class usable in all currently used versions of Android. On the whole, a DialogFragment is pretty similar to a Dialog. It’s just wrapped inside a fragment. Through this post, we will learn how to implement a DialogFragment in Android.

Pre-requisites: Eclipse IDE, Android SDK

In any of your existing Android projects, creating a new Activity class called TestDialogFragmentActivity with package name com.example and add the following code.

TestDialogFragmentActivity.java

package com.example;

import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class TestDialogFragmentActivity extends FragmentActivity {

	private Button btnOpenFragment;
	FragmentManager fm = getSupportFragmentManager();

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_fragment);

		btnOpenFragment = (Button) findViewById(R.id.btnfragment);
		btnOpenFragment.setOnClickListener(new OnClickListener() {
			public void onClick(View arg0) {
			      MyDialogFragment dialogFragment = new MyDialogFragment();
			      dialogFragment.show(fm, "Dialog Fragment");
			}
		});

	}
}

Now, let’s implement the DialogFragment class for the same. Create a new class called MyDialogFragment and add the following code.

MyDialogFragment.java

import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyDialogFragment extends DialogFragment {


	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		
		View rootView = inflater.inflate(R.layout.dialog_fragment, container,false);
        getDialog().setTitle("DialogFragment Example");        
       
        return rootView;
	}	
}

The layout files would be as follows,

activity_fragment.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" >
 
    <Button
        android:id="@+id/btnfragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="@string/dialogFragment" />

</RelativeLayout>

dialog_fragment.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" >
 
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:padding="10dp"
        android:text="@string/txtFragment" />

</RelativeLayout>

strings.xml

    <string name="txtFragment">Hi. This is a dialog fragment</string>
    <string name="dialogFragment">Open DialogFragment</string>

Finally, make sure no errors are present. Save all changes. Run the application on an Android device and you should see the following output!

output_1

output_2

Reference: Android DialogFragment

Getting started with Android Wear!

Hello everyone!

Android wear is a platform developed by Google for wearable devices. It was launched in the month of March 2014 as a developer preview along with partner companies such as Motorola, Samsung, LG etc. Android Wear is basically an operating system designed primarily for smartwatches and other wearables. It integrates Google Now functionality and mobile notifications into the screen of a wearable device.

Through this post, we will learn how to get started with using Android Wear. We would be creating a sample program to display wearable style notifications!

Pre-requisites: Eclipse IDE, Android SDK (Target SDK: Android 4.4W)

Step 1: Download Android Wear SDK

In order to start creating wearable applications, one needs to download and install the Wearable SDK. Launch the SDK Manager application and download the latest version of the SDK.

sdk_manager

Step 2: Create new Android Wear project

Create a new Android application project called AndroidWearHelloWorld with package name com.app.hellowear. Choose the target SDK as Android 4.4W.

Next, add the following code in your Activity class.

MainActivity.java


import android.app.Activity;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.WearableExtender;
import android.support.v4.app.NotificationManagerCompat;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);	
        NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(this);


        // Create a big text style for the notification
        NotificationCompat.BigTextStyle notificationPageStyle = new NotificationCompat.BigTextStyle();
        secondPageStyle.setBigContentTitle("Test Message!")
        .bigText("This is a really long message...");

        PendingIntent actionPendingIntent =
                PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class),
                        PendingIntent.FLAG_CANCEL_CURRENT);

        // Create the action
        NotificationCompat.Action action =
                new NotificationCompat.Action.Builder(R.drawable.ic_launcher,
                        getString(R.string.test), actionPendingIntent)
                        .build();

        // Build the notification and add the action via WearableExtender
        Notification wearableNotification =
                new NotificationCompat.Builder(this)
                        .setSmallIcon(R.drawable.ic_launcher)
                        .setStyle(notificationPageStyle)
                        .extend(new WearableExtender().addAction(action))
                        .build();
        
        notificationManagerCompat.notify(2, wearableNotification);

	}
 }

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">

    <TextView
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

</RelativeLayout>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">AndroidWearHelloWorld</string>
    <string name="hello_world">Go to notification screen</string>
    <string name="test">You have a new message!</string>   
</resources>

Finally, save all changes and run the application on an Android Wear compatible virtual device. If no errors occur then you should see the following output!

output_1

output_2

Lot’s more on Android Wear in my upcoming posts. Stay tuned! πŸ™‚

Reference: Android Wear Notifications

Tutorial #86: Implement face detection in Android

Hey friends!

Face Detection is one of the most common image processing applications. Prior to Android 4.0 (Ice Cream Sandwich) developers would use third party libraries in order to implement the face detection functionality. Today, one can easiliy identify different faces with the help of certain pre-defined functions.

The Camera class in Android now provides the startFaceDetection method to initiate face detection on an Android phone. As mentioned on the developer’s page, once the method has been called the camera will notify Camera.FaceDetectionListener of the detected faces in the preview frame. Moreover, the startFaceDetection method is supported only if getMaxNumDetectedFaces() returns a number larger than zero.

Through this tutorial, we will learn how to implement face detection in Android. We would be displaying the number of faces detected by using a sample image.

Pre-requisites: Eclipse IDE, Android SDK (Target SDK: Android 4.0 and above)

Step 1: Create new Android project

Launch Eclipse IDE and create a new Android application project called AndroidFaceDetectionDemo with package name com.app.facedetection.

Step 2: Create new Activity class

In order to implement face detection, we need to basically access the device camera. Let’s create an Activity class called FaceDetectionActivity that implements the same.

FaceDetectionActivity.java

package com.app.facedetection;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.Face;
import android.hardware.Camera.FaceDetectionListener;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

@SuppressLint("InflateParams")
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class FaceDetectionActivity extends Activity implements SurfaceHolder.Callback{

	private Camera camera;
	private SurfaceView surfaceView;
	private SurfaceHolder surfaceHolder;
	boolean preview = false;
	private LayoutInflater layoutInflater = null;
	private Button btnTakePicture;
	private TextView txtFaceCount;
	private TextView txtImagePath;

	final int RESULT_SAVEIMAGE = 0;

	/** Called when the activity is first created. */
	@SuppressWarnings("deprecation")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_facedetection);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

		getWindow().setFormat(PixelFormat.UNKNOWN);
		surfaceView = (SurfaceView)findViewById(R.id.camPreview);
		surfaceHolder = surfaceView.getHolder();
		surfaceHolder.addCallback(this);
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

		txtFaceCount = (TextView)findViewById(R.id.tvFaceCount);
		txtImagePath = (TextView)findViewById(R.id.tvImagePath);
		
		layoutInflater = LayoutInflater.from(getBaseContext());
		View viewControl = layoutInflater.inflate(R.layout.picture_control, null);
		LayoutParams layoutParamsControl
		= new LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.FILL_PARENT);
		this.addContentView(viewControl, layoutParamsControl);

		btnTakePicture = (Button)findViewById(R.id.takepicture);
		btnTakePicture.setOnClickListener(new Button.OnClickListener(){

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				camera.takePicture(mShutterCallback,
						mRawPictureCallback, mJPGPictureCallback);
			}});

		LinearLayout layoutBackground = (LinearLayout)findViewById(R.id.linearLayout);
		layoutBackground.setOnClickListener(new LinearLayout.OnClickListener(){

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				btnTakePicture.setEnabled(false);
				camera.autoFocus(mAutoFocusCallback);
			}});


	}

	@SuppressLint("NewApi")
	FaceDetectionListener faceDetectionListener
	= new FaceDetectionListener(){

		@Override
		public void onFaceDetection(Face[] faces, Camera camera) {

			if (faces.length == 0){
				Toast.makeText(getApplicationContext(), "No face detected..!", Toast.LENGTH_SHORT).show();
			}else{

				txtFaceCount.setText("Number of Faces Detected:" + " " +String.valueOf(faces.length));
			}


		}};

	AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback(){

		@Override
		public void onAutoFocus(boolean arg0, Camera arg1) {
				// TODO Auto-generated method stub
				btnTakePicture.setEnabled(true);
		}};

		ShutterCallback mShutterCallback = new ShutterCallback(){
			@Override
			public void onShutter() {
					// TODO Auto-generated method stub

		}};

		PictureCallback mRawPictureCallback = new PictureCallback(){

		@Override
		public void onPictureTaken(byte[] arg0, Camera arg1) {
						// TODO Auto-generated method stub

		}};

		PictureCallback mJPGPictureCallback = new PictureCallback(){

		@Override
		public void onPictureTaken(byte[] arg0, Camera arg1) {
			// TODO Auto-generated method stub	
			
				try {
								
						int imageNum = 0;
		      
						Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
					    File imagesFolder = new File(Environment.getExternalStorageDirectory(), "FaceDetection");
					    if (!imagesFolder.exists()) {
					        imagesFolder.mkdirs();
					    }
				        
					    String fileName = "image_" + String.valueOf(imageNum) + ".jpg";
					    File output = new File(imagesFolder, fileName);
					        
						   while (output.exists()){
						       imageNum++;
						       fileName = "image_" + String.valueOf(imageNum) + ".jpg";
						       output = new File(imagesFolder, fileName);
						   }
				       
					    Uri uriSavedImage = Uri.fromFile(output);
					    imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
	
					    OutputStream imageFileOS;
					       
					    imageFileOS = getContentResolver().openOutputStream(uriSavedImage);
					    imageFileOS.write(arg0);
					    imageFileOS.flush();
					    imageFileOS.close();
	
						txtImagePath.setText("Image saved to:" + " " +uriSavedImage.toString());
					
					} catch (FileNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					camera.startPreview();
					camera.startFaceDetection();
			}};

			@Override
			public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
			  // TODO Auto-generated method stub
			 if(preview){
					camera.stopFaceDetection();
					camera.stopPreview();
					preview = false;
			  }

			if (camera != null){
					try {
					camera.setPreviewDisplay(surfaceHolder);
					camera.startPreview();	
					camera.startFaceDetection();
					preview = true;
					} catch (IOException e) {
						// TODO Auto-generated catch block
					   e.printStackTrace();
					}
				}
			}

			@Override
			public void surfaceCreated(SurfaceHolder holder) {
				// TODO Auto-generated method stub
				camera = Camera.open();
				camera.setFaceDetectionListener(faceDetectionListener);
			}

			@Override
			public void surfaceDestroyed(SurfaceHolder holder) {
				// TODO Auto-generated method stub
				camera.stopFaceDetection();
				camera.stopPreview();
				camera.release();
				camera = null;
				preview = false;
			}
}

picture_control.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linearLayout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="bottom"
    android:orientation="vertical" >

    <Button
        android:id="@+id/takepicture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:text="@string/click_picture" />

</LinearLayout>

activity_facedetection.xml

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

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:text="@string/app_name" />

    <TextView
        android:id="@+id/tvFaceCount"
        android:textSize="15sp"
        android:gravity="center_horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
    
    <TextView
        android:id="@+id/tvImagePath"
        android:textSize="15sp"
        android:gravity="center_horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <SurfaceView
        android:id="@+id/camPreview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">AndroidFaceDetection</string>
    <string name="click_picture">*Take Picture</string>
</resources>

Note: Make sure you add the below permissions in your project’s AndroidManifest.xml file.

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

Step 3: Run on device

Finally, save all changes and run the application on an Android device. If no errors occur then you should see the following output! πŸ™‚

output_1

output_2

Reference: Android Camera

Using command line shell for SQLite in Android

Hello everyone!

The SQLite library is a crucial part of the Android environment. It is a light weight database that allows storage of user and application data. Moreover, SQLite is ACID-compliant and implements most of the SQL standard, using a dynamically and weakly typed SQL syntax.

The SQLite project provides a simple command-line utility named sqlite3 (or sqlite3.exe on windows) that allows a user to manually enter and execute SQL statements against an SQLite database. Through this post, we will learn how to use the sqlite3 program to create a new database.

Pre-requisites: Android SDK, Windows 7 (64 bit)

Open an instance of the command prompt and navigate to the platform-tools folder present within the Android SDK bundle.

Step 1: Create a new database

create_database

In order to create a new SQLite database, we need to execute the following command.

sqlite3 Employee.db

Step 2: Create new table and insert records

We can use the standard CREATE TABLE SQL statement in order to create a new table as follows!

create table Employee(EmpId int primary key, EmpName varchar(50));

Now, let’s insert a few records in the above table.

insert into Employee values('101','ashish');
insert into Employee values('102','ajay');

create_table_insert_rows

Step 3: Dump/Print contents of table

As mentioned on the Android developer’s page, the sqlite3 tool includes many useful commands, such as .dump to print out the contents of a table and .schema to print the SQL CREATE statement for an existing table.

Finally, let’s look at the .dump command that will generate a .sql file as follows!

sqlite3 Employee.db .dump > Employee.sql

Employee.sql

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE Employee(EmpId int primary key, EmpName varchar(50));
INSERT INTO "Employee" VALUES(101,'ashish');
INSERT INTO "Employee" VALUES(102,'ajay');
COMMIT;

That’s it for this Android tip. Hope it helps! πŸ™‚

Reference: Command Line Shell for SQLite

Implement spell checker in Android

Hi everyone!

Spell check is of the most common programs used to identify words in a document that may not be spelled correctly. Today, one need not carry a dictionary to self spell check. The age of mobile technology has given rise to a number of applications that incorporate the spell checking functionality.

Android offers developers a spelling checker framework. In order to implement the spell checking feature, developers need to make use of the SpellCheckerSessionListener interface. The interface provides callbacks for getting results from text services. Through this post, we will learn how to implement a spell checker application in Android.

Pre-requisites: Android SDK, Eclipse IDE

Create a new Activity class called TestSpellCheckerActivity in any of your existing Android projects and add the following code!

TestSpellCheckerActivity.java

package com.app.test;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SpellCheckerSession;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
import android.view.textservice.TextServicesManager;
import android.widget.EditText;
import android.widget.TextView;

public class TestSpellCheckerActivity extends Activity implements SpellCheckerSessionListener {
	
	private TextView txtSpellCheck;
	private SpellCheckerSession btnChecker;
	private EditText etWord;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_spellcheck);
		txtSpellCheck = (TextView)findViewById(R.id.txtLabel);
		etWord = (EditText)findViewById(R.id.etWord);
	}

	@Override
	public void onResume() {
		super.onResume();
		final TextServicesManager tsm = (TextServicesManager) getSystemService(
				Context.TEXT_SERVICES_MANAGER_SERVICE);
		btnChecker = tsm.newSpellCheckerSession(null, null, this, true);         
	}

	@Override
	public void onPause() {
		super.onPause();
		if (btnChecker != null) {
			btnChecker.close();
		}
	}

	@SuppressWarnings("deprecation")
	public void getSuggestions(View view){
		btnChecker.getSuggestions(new TextInfo(etWord.getText().toString()), 3);
	}
	
	@Override
	public void onGetSuggestions(final SuggestionsInfo[] arg0) {
		final StringBuilder sb = new StringBuilder();

		for (int i = 0; i < arg0.length; ++i) {
			
			final int len = arg0[i].getSuggestionsCount();
			sb.append('\n');
			for (int j = 0; j < len; ++j) {
				sb.append("," + arg0[i].getSuggestionAt(j));
			}
			
		}
		runOnUiThread(new Runnable() {

			public void run() {
				txtSpellCheck.append(sb.toString());
			}
		});

	}
	
	@Override
	public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] arg0) {
		// TODO Auto-generated method stub

	}
}

activity_spellcheck.xml

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

    <EditText
        android:id="@+id/etWord"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/instruction">
        <requestFocus />
    </EditText>

    <Button
        android:id="@+id/btnSuggest"
        android:layout_width="150dip"
        android:layout_height="50dip"
        android:onClick="getSuggestions"
        android:text="@string/spell_check"/>

    <TextView
        android:id="@+id/txtLabel"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/suggestions"/>

</LinearLayout>

strings.xml

 <string name="spell_check">Spell Check</string>
 <string name="suggestions">Suggestions</string>
 <string name="instruction">Enter any text</string>

Save all changes. Make sure no errors are present. Run the application on an Android device and you should see the following output!

output_1

output_2

Reference: Android SuggestionsInfo

The way of life!

Sometimes when you feel you are at your best; everything is falling right into place, life hits you hard and puts you back in the race! πŸ™‚

At 24, I might be the best person for the job, the most loving son or the most helpful person but when I encounter reality, the feeling just nullifies. As a person, I always want to excel, success is what I crave for, passion is what drives me; even then I could never learn the way of life.

Back then, personal hygiene is something I never paid attention too. You often hear your parents tell you to wipe your body clean after a shower, cut your nails on time, wash your hands before a meal, tighten your shoelaces and so on. Trust me these small things have a big impact on life. Cooking is something I could never learn but criticizing the cook brought a smile to my face. Household chores? Who does that anyway? The fact is that I never learnt things – the hard way.

Was there anything that could have brought about a change in me? Perhaps yes and one such incident indeed did. I was travelling home via the CST-bound local, glued to my headphones seated near the window. It was pouring heavily and in order to avoid water from entering the compartment, people would normally shut the windows by pulling down the glass case. Suddenly, an old man, who sat in front of me asked me to pull down the window. As usual, I responded late and when I tried pulling it down, I couldn’t. I just didn’t know how to do it. At the end, the old man had to get up and pull the window down himself. Till the time I reached home my eyes were filled with tears. Something had hit me hard – mentally. Life had just taught me the best lesson. Today, even after several years the old man’s words echo in my mind. I remember he said, “Look at this guy wearing headphones. He doesn’t even know how to close a window!!”

Times have changed. For a person who never knew how to use a pen to a person who is on the verge of completing his second book, life has always challenged every move of mine. All I do is try and live up to those. Remember, no matter who you are, rich or poor, near or far, never neglect the basic things of life. Learn to respect life and it will respect you!

Hello World using OpenCV and Qt

Hello everyone!

Qt is one of the popular cross-platform application and UI frameworks allowing developers to incorporate both GUI and Non-GUI based features within their applications. The Qt SDK also helps in developing cross-platform OpenCV applications. The Qt Creator IDE is a tool that can be used to write, debug and execute programs. On the other hand, OpenCV as you might be aware is a well known image processing library. The combination of Qt and OpenCV is something that has attracted the attention of developers worldwide.

Through this post, we will learn how to write a simple Hello World application using OpenCV and Qt.

Pre-requisites: Windows 7 (64 bit), Qt Creator based on Qt 5.2.0, OpenCV

Step 1: Configure Qt for using OpenCV

In case you have not configured Qt for using OpenCV, I would recommend reading this presentation for setting up your Qt environment. Once you have configured your environment, you can proceed to the next step.

Step 2: Create a new Qt Project

Launch the Qt Creator IDE and create a new Qt console Application with the name OpenCV_HelloWorld. Choose the compiler (MinGW or Visual Studio) of your choice and proceed. Now, write the following code in your main.cpp file.

main.cpp

#include "opencv2/opencv.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;

int main(int argc, char** argv){

    namedWindow("output",1);
    Mat output = Mat::zeros(120,350,CV_8UC3);
    putText(output,"Hello world :)", cvPoint(15,70), FONT_HERSHEY_PLAIN,3,cvScalar(0,255,0),4);
    imshow("Output",output);
    waitKey(0);
    return 0;

}

Step 3: Add path to OpenCV libraries

In order for Qt to make use of OpenCV, we need to include the path to the libraries in the Qt project (.pro) file as follows.

QT       += core

QT       -= gui

TARGET = OpenCV_HelloWorld
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app

SOURCES += main.cpp
INCLUDEPATH += F://softwares//opencv//opencv//sources//release//install//include

Finally, run qmake and build the project. Make sure no errors occur. If everything runs fine then you should see the following output!

qt_opencv_helloworld

So that’s it for this Qt tip. A lot more still to come! πŸ™‚