Adding Long Click functionality in List View – Context Menus Clicks

Now that we are familiar with long clicks and Context Menus that are triggered by them, we must understand that Context Menus are but a kind of menu and just like any other type of menu, their items too are clickable. In fact, if there were no such options the whole purpose of displaying a menu is defeated.

In this post I will show you how to handle clicks on the Context Menu which is a rather simple task. All we need to do is add another method. Complete Source Code is at the bottom.

  • Create the layout of the activity and insert a ListView into it.
  • Switch over to the java file and declare the List View. Create the string array to populate the list.
  • Declare and assign the ArrayAdapter to the ListView.
  • Register the List View for Context Menu and create the method onCreateContextMenu(). Add the two menu items Edit and Delete.
  • Now just after the onCreateContextMenu() method we define another method on:
    [java]
    public boolean onContextItemSelected(MenuItem item){
    if(item.getTitle()=="Edit")Toast.makeText(getApplicationContext(), "Edit Clicked", Toast.LENGTH_LONG).show();
    if(item.getTitle()=="Delete")Toast.makeText(getApplicationContext(), "Delete Clicked", Toast.LENGTH_LONG).show();
    return true;
    }
    [/java]
  • Save your work and execute it on the device or the emulator.
  • I am just displaying a Toast on the click of the Context Menu item. You can choose to do whatever you want.

LongClick1  LongClick2

COMPLETE SOURCE CODE

activity_main.xml

MainActivity.java

[java]
package com.nero.myfirstapp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String values[]=new String[]{"Vergil", "Dante", "Sparda", "Nero", "Arkham", "Agni", "Rudra", "Beowulf", "Nevan"};
ListView lv = getListView();
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1,values);
lv.setAdapter(adapter);
registerForContextMenu(lv);

lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
String item = ((TextView)view).getText().toString();
Toast.makeText(getApplicationContext(), "Clicked: "+item, Toast.LENGTH_LONG).show();
}
});
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){
menu.add(0, v.getId(), 0, "Edit");
menu.add(0, v.getId(), 0, "Delete");
}

public boolean onContextItemSelected(MenuItem item){
if(item.getTitle()=="Edit")Toast.makeText(getApplicationContext(), "Edit Clicked", Toast.LENGTH_LONG).show();
if(item.getTitle()=="Delete")Toast.makeText(getApplicationContext(), "Delete Clicked", Toast.LENGTH_LONG).show();
return true;
}
}
[/java]

Adding Long Click functionality in List View – Context Menus

As we saw in the last post, we can easily handle clicks on the list items. However, often times in our applications we would like to have separate genres of options on the click of the the list items if possible. This is where long clicks come into play. Android provides facilities to handle both regular and long clicks by identifying them separately.

Here, I will show you how to use this facility of Android and separately handle clicks. I am creating a menu here on detecting long clicks. You can do a lot more things as and what you feel like. So start off an activity and follow along. Complete Source Code is at the bottom.

  • Create the layout of the activity and insert a ListView into it.
  • Switch over to the java file and declare the List View. Create the string array to populate the list.
  • Declare and assign the ArrayAdapter to the ListView.
  • Just after this assignment we need to register our ListView for Context Menu. Write the below line:
    [java]
    registerForContextMenu(lv);
    [/java]
  • Close the onCreate() method and create a new method:
    [java]
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){
    menu.add(0, v.getId(), 0, "Edit");
    menu.add(0, v.getId(), 0, "Delete");
    }
    [/java]
  • Here we are going to provide the user with a couple of options of Edit and Delete the entry. Of course, we are not going to perform these actions here. This is just for demonstration purposes.
  • Save your work and execute it on an emulator or device.

LongClick

Understanding the Code:

  • The menu.add() method we are using here has a constructor add(int groupId, int itemId, int order, CharSequence title).
  • We are providing a value of 0 for both groupId and order. We however are giving each item an itemId which we derive easily from the view argument to the method.

COMPLETE SOURCE CODE

activity_main.xml

MainActivity.java

[java]
package com.nero.myfirstapp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String values[]=new String[]{"Vergil", "Dante", "Sparda", "Nero", "Arkham", "Agni", "Rudra", "Beowulf", "Nevan"};
ListView lv = getListView();
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1,values);
lv.setAdapter(adapter);
registerForContextMenu(lv);

lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
String item = ((TextView)view).getText().toString();
Toast.makeText(getApplicationContext(), "Clicked: "+item, Toast.LENGTH_LONG).show();
}
});
}
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){
menu.add(0, v.getId(), 0, "Edit");
menu.add(0, v.getId(), 0, "Delete");
}
}
[/java]

Adding Click functionality in List View – onItemClickListener()

In the previous posts we saw how we can, in a number of ways populate out List Views. However, most of the times just populating and displaying List Views aren’t enough. You must have seen that in most of the applications, we can click the items of the List View and that brings up an array of options that the programmer has programmed. We are going to learn how to add the click functionality to our List View.

Remember that the functionality described here will work in exactly in the same manner irrespective of whether it is a long click or a regular click. I will show you how to add the Long Click functionality in the list item in a separate post.
So start up an activity and follow along. Complete Source Code is at the bottom.

  • We are going to be working with ArrayAdapters just as we have been doing in the previous posts. The process of adding the click functionality remain the same even if you choose to use a different kind of adapter.
  • In the XML file of the activity, add the list view and switch to the MainActivity.java file. The source code at the bottom extends the MainActivity from ListActivity, but you can extend Activity just as I had shown you in the first post on List Views.
  • Set up the ArrayAdapter and assign it to the ListView.
  • Just after that, add the following code:
    [java]
    lv.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position, long id){
    String item = ((TextView)view).getText().toString();
    Toast.makeText(getApplicationContext(), "Clicked: "+item, Toast.LENGTH_LONG).show();
    }
    });
    [/java]
  • Save your work and execute it on an emulator or a device.

Click1    Click2

Understanding the Code

  • A careful examination of code shows that it itself is comprehensive enough.
  • AdapterView<?> parent is the parent Adapter view i.e. it refers to the complete section where the Adapter is used.
  • View view is the specific view which we are clicking at the moment, in this case the element we are clicking.
  • int position gives the position of the view under consideration, in this case the element clicked.
  • long id gives the id of the clicked element.
  • Here, I’ve shown you a very basic example of how to handle clicks by using Toast. You can create dialogs, alert boxes or switch to entire new activities if you want to. Refer to my previous posts and apply the concept discussed here.

COMPLETE SOURCE CODE

activity_main.xml

MainActivity.java

[java]
package com.nero.myfirstapp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String values[]=new String[]{"Vergil", "Dante", "Sparda", "Nero", "Arkham", "Agni", "Rudra", "Beowulf", "Nevan"};
ListView lv = getListView();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1,values);
lv.setAdapter(adapter);

lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id){
String item = ((TextView)view).getText().toString();
Toast.makeText(getApplicationContext(), "Clicked: "+item, Toast.LENGTH_LONG).show();
}
});
}
}
[/java]

List View using Array Adapters – Part III : Using Custom Row Layouts

Till now we have been using Android’s default row layout for populating the ListView. It might sometimes become necessary to use one that satisfies our needs, thereby creating a custom row layout. As I had said in my earlier posts that there are a number of ways f implementing List views, we are going to use one here that allows use of custom layout for every single row of the list view.

Since this is just another way of implementing, I will just provide a few points of difference worth noting from earlier implementations and the complete source code

  • We will be extending the ListActivity class here
  • We will not be using the setContentView() method here. This tells Android that we need only a List view in our activity spanning across the entire size.
  • We will also not be declaring the ListView here for the same reason.
  • We will assign the adapter to the ListView with the use of this keyword. See below for implementation

Array_Adapter3

COMPLETE SOURCE CODE

row_item.xml

MainActivity.java

[java]
package com.nero.myfirstapp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String values[]=new String[]{"Vergil", "Dante", "Sparda", "Nero", "Arkham", "Agni", "Rudra", "Beowulf", "Nevan"};
this.setListAdapter(new ArrayAdapter(this, R.layout.row_item, R.id.textView1,values));
}
}
[/java]

Doubly Linked Lists

A doubly linked list is a linked linear data structure,each node of which has one or more data fields but only two link fields known as left link (LLINK) and right link (RLINK).The LLINK field of a given node points to the node on its left and RLINK field of a given node points to the node on its right.

Advantages-

1.The availability of two links LLINK and RLINK permit forward and backward movement during the processing of the list.
2.The deletion of a node X from the list requires only the value of X.
3.Efficiency of operations like insertion,deletion,etc increases.

Disadvantage-

1.Each node needs two links which can be considered expensive storage-wise when compared to singly linked lists.

Operations-

Insertion-

To insert node X to the right of node Y in a headed circular doubly linked list P-

[cpp]

INSERT (X,Y)

LLINK(X)=Y;
RLINK(X)=RLINK(Y);
LLINK(RLINK(Y))=X;
RLINK(Y)=X;

END
[/cpp]

insertion

Deletion-

To delete node X from a headed circular doubly linked list P-

[cpp]

DELETE (P,X)

RLINK(LLINK(X))=RLINK(X);
LLINK(RLINK(X))=LLINK(X);

END

[/cpp]

deletion

Linked Lists

Linked list is one of the fundamental,simplest and most common data structures in C programming language.A linked list is a data structure consisting of a group of nodes which together represent a sequence.Each node comprises of data and a link to the next node in the sequence.

Advantages of Linked List over an array-

1.Linked list is a dynamic data structure whose length can be increased or decreased at run time.An array is a static data structure that is length of array cannot be altered at run time.

2.In an array, all the elements are kept at consecutive memory locations while in a linked list the elements (or nodes) may be kept at any location but still connected to each other through pointers.The list elements can easily be inserted or removed without reallocation or reorganization of the entire structure because the data items need not be stored contiguously in memory or on disk.

3.Linked lists are preferred mostly when we don’t know the volume of data to be stored.

Creating a Linked List-

A block in a linked list is represented through a structure-

typedef struct node_type
{

int data;
struct node_type *link;

} node;

The value ‘data’ can be any value while the pointer ‘link’ contains the address of next block of this linked list.
The ‘next’ pointer of the last node would contain a NULL.

A node is created by allocating memory to a structure in the following way-

struct node_type *ptr = (struct node_type*)malloc(sizeof(struct node_type));

The pointer ‘ptr’ now contains address of a newly created node.

To assign a value to the node-

ptr->val = data;

To assign its next pointer,the address of next node-

ptr->next = NULL;

The first node of the list is known as head node.

Algorithm-

//initialization

head->data=X;
head->next=NULL;

PROCEDURE-

//let the new node be temp
//inserted at the beginning

temp->data=X;
temp->next=head;

head=temp;

REPEAT PROCEDURE

Code-

[cpp]

//Insertion at the beginning of the list

typedef struct node_type
{

int data;
struct node_type *link;

} node;

typedef node *list;

list head;

//value to be entered in the list is dat which is the input

scanf("%d",&dat);

//creating the first node

head=(list)malloc(sizeof(node));

head->data = dat;
head->link=NULL;

list temp;

//dat!=99 denotes stopping condition

while(dat!=99)
{
scanf("%d",&dat);

//creating node
temp=(list)malloc(sizeof(node));

temp->data=dat;
temp->link=head;

//since inserted at the beginning
// the new node will become the head

head=temp;

}

//Printing the list

temp=head; //initialization

while(temp!=NULL)
{
printf("%d ",temp->data);

//going to next node
temp=temp->next;
}

[/cpp]

All Permutations

Given a string,the task is to print all the permutations of the string.
A permutation is a rearrangement of the elements of an ordered list S.A string of length N has N! permutations.

Example-

Let the string be S=”abc”.

Length of the string=3

Number of permutations=3!=6

Permutations-

abc
acb
bac
bca
cab
cba

Algorithm-

Basic idea-

All permutations of a string X is the same thing as all permutations of each possible character in X, combined with all permutations of the string X without that letter in it.

All permutations of “abcd” are-

“a” concatenated with all permutations of “bcd”.
“b” concatenated with all permutations of “acd”.
“c” concatenated with all permutations of “bad”.
“d” concatenated with all permutations of “bca”.

Recursive solution-

The first character is kept constant and permutations are generated with the rest.Then,the first two characters are kept constant and permutations are generated with the rest until we are out of characters.

This algorithm is performed on the input string itself.Thus,no additional memeory is required.The “backtracking” undoes the changes to the string, leaving it in its original state.

Code-

[cpp]

char a[1000];//string

//to swap characters at position i and j

void swap (int i, int j)
{
char temp;
temp = a[i];
a[i] = a[j];
a[j] = temp;
}

//i is the starting index
//n is the ending index
//initially,permute(0,n-1) is called

void permute(int i, int n)
{
int j;

if (i == n)
printf("%s\n", a);

else
{
for (j = i; j <= n; j++)
{
swap(i,j);
//increasing the number of fixed characters
permute(i+1, n);
swap(i,j); //backtrack
}
}
}

[/cpp]

Note-

It has a time complexity of O(N*N!) and is an example of Backtracking.

List View using Array Adapters – Part II : Using ListActivity

In the previous post, I showed you how to create a ListView and populate it with elements of a String array. If you can recall, we used a regular activity in the process. By regular activity I mean that our Java class extended Android.App.Activity class.

It is worth knowing that Android has a special class names Android.App.ListActivity that is meant specifically for a ListView purpose. In this post I am going to show you how to use ListActivity class for creating a ListView. Remember that even though it is meant specifically for a ListView, it does support other elements of an Android layout. Complete Source Code is at the bottom.

  • Start off an activity. Switch to the XML layout file and insert a ListView from the palette on the left.
  • Spread it all the way across the length and breadth of the activity.
  • Switch over to the MainActivity.java file and declare the ListView. Unlike what we did in the last post, we are going to use a different declaration here.
    [java]
    ListView lv = getListView();
    [/java]
  • Obviously, since we are using a dedicated class, getListView() method makes perfect sense. Remember that this cannot be used in a regular activity.
  • Remember that a ListActivity requires your ListView to be identified as android.R.id.list. In order to do that, you need to edit your XML file to set the android:id attribute of the ListView to @+id/list. In some systems, this needs to be set to @+id/android:list.
  • Create a string array containing elements that you want in the list. Try and put enough values so that you can also experience the scrolling feature of ListView provided by default in the ListView element.
  • We are now going to populate the ListView with elements from the string array with the help of an Array Adapter.
  • Now declare the Array Adapter and assign it to the ListView.
  • Save your work and run it on an emulator or device.

Array_Adapter1  Array_Adapter2

COMPLETE SOURCE CODE

activity_main.xml

MainActivity.java

[java]
package com.nero.myfirstapp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String values[]=new String[]{"Vergil", "Dante", "Sparda", "Nero", "Arkham", "Agni", "Rudra", "Beowulf", "Nevan"};
ListView lv = getListView();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1,values);
lv.setAdapter(adapter);
}
}

[/java]

List View using Array Adapters – Part I

Often times in your application when you want to list down a bunch of data you’re going to use a List View. It provides a predefined layout that helps create a list from a specific set of data. Now, inserting a list view in you activity’s layout is but trivial. Here we are going to see how to populate the list view.

It is to be remembered that a List can be implemented inside an activity in a number of ways. I will try and discuss all such ways in separate posts. Also remember that the classes we are going to use have overloaded constructors and we will be using any one of them. However, all of them are equally important in various situations, so I suggest you use the eclipse code-hinting feature to have a look at all those. Complete Source Code is at the bottom.

  • Start off an activity. Switch to the XML layout file and insert a ListView from the palette on the left.
  • Spread it all the way across the length and breadth of the activity.
  • Switch over to the MainActivity.java file and declare the ListView. 
  • Create a string array containing elements that you want in the list. Try and put enough values so that you can also experience the scrolling feature of ListView provided by default in the ListView element.
  • We are now going to populate the ListView with elements from the string array with the help of an Array Adapter.
  • In order to declare the ArrayAdapter write the below lines:
    [java]
    ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1,values);
    [/java]
  • We can also declare the ArrayAdapter using the below declaration:
    [java]
    ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, values);
    [/java]
  • As I said earlier, we can use one of many constructors of the ArrayAdapter class depending on our needs and the situation
  • values is the name of the string array containing the elements to be displayed.
  • Now, we have the ArrayAdapter ready and in order to populate the list we need to assign this adapter to the ListView:
    [java]
    lv.setAdapter(adapter);
    [/java]
  • lv is the name of the ListView of my activity.
  • Save your work and run it on an emulator or device.

Array_Adapter1  Array_Adapter2

Understanding the Code:

  • Adapters may be seen as the bridge between the UI components and the data source that fill the data into the UI.
  • There are various types of Adapters – ArrayAdapters, SimpleCursorAdapters, SimpleAdapters etc. We can even make custom adapters that serves our purposes.
  • The declarations that I have shown here has the below constructor:
    [java]
    ArrayAdapter = new ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
    [/java]
  • Once we have setup the bridge i.e. ArrayAdapter we need to use it to populate the List. We do this by using the setAdapter() method.

COMPLETE SOURCE CODE

main_activity.xml

MainActivity.java

[java]
package com.nero.myfirstapp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String values[]=new String[]{"Vergil", "Dante", "Sparda", "Nero", "Arkham", "Agni", "Rudra", "Beowulf", "Nevan"};
ListView lv = (ListView) findViewById(R.id.list);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1,values);
lv.setAdapter(adapter);
}
}
[/java]

Content Providers in Android

One of the most striking features of Android is Content Providers. In a sentence, Content Providers consist of a centrally located database in Android that helps applications use the data from other applications or those provided by Android itself. A very comprehensive article is on the official Android Documentation here.
This post is aimed at shoeing you how to use Content Providers if you need certain data in your application and hence I will not go into the details of what Content Providers are. Nevertheless, the article linked above will familiarize you with it to a good extent.

Now, we are going to create an application that extracts the contacts from the device. It is obvious that there is no way you can access the contacts because it belongs to a different application that comes pre-installed with Android. This is where we are going to use Content Providers. Let us see how:

  • The first thing we are going to do is add a permission to the manifest file of our application. The permission is android.permission.READ_CONTACTS.
  • This tells Android that we are going to access the contacts list of the device. You don’t want your application to use the contact list of a device without letting the user know. This is hence done to protect user privacy.
  • We are going to extract the contacts and send it to Logcat so we can check if our application ran succesfully.
  • We are not going to have a layout for this activity as we do not need it.
  • Add the following lines below the super.onCreate(savedInstanceState)

    [java]
    Cursor c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
    while(c.moveToNext()){
    int nameidx = c.getColumnIndex(PhoneLookup.DISPLAY_NAME);
    String name = c.getString(nameidx);
    Log.d("CONTACTS", name);
    }
    [/java]
  • Save it and execute it on an emulator or a device.
  • Since there is no layout for this activity we are going to have to check out the DDMS for the Logs. Below is a snip of how it ran on my system. I have three contacs int my emulator- Nero, Vergil and Dante.

ContentP1

Understanding the Code:

  • Remember that the Content Providers are like a centrally located database.
  • A cursor can be considered analogous to a pointer in most programming languages. It points to the first of the rows retrieved from a query.
  • We access the Content Providers with the help of Content Resolvers class. Here, we make an inline query.
  • Each Content Provider is identified unquely by a URI i.e. Uniform Resource Identifier. The URI here is located with the help of ContactsContract class. The complete URI here is ContactsContract.Contacts.CONTENT_URI.
  • Since a cursor points to a complete row and we just need the name of the contact, we need to identify exactly which column will the contact name be in. For this we make use of the Column Index. We identify the Column Index by a particular constant string inside the PhoneLookup class i.e. PhoneLookup.DISPLAY_NAME. This name identifies uniquely the index of the column where the contact name is located.
  • Once we have the column index, we can easily extract the string from it and log it in the Logcat.
  • It must also be remembered that the Content Provider for this application is inbuilt in Android. If one wishes to share information between two standalone applications, one can create his own Content Provider. This would then enable all other applications to access the application’s data.

COMPLETE SOURCE CODE

MainActivity.java

[java]
package com.nero.myfirstapp;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

import android.media.MediaPlayer;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract;
import android.provider.ContactsContract.PhoneLookup;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class Main extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Cursor c = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while(c.moveToNext()){
int nameidx = c.getColumnIndex(PhoneLookup.DISPLAY_NAME);
String name = c.getString(nameidx);
Log.d("CONTACTS", name);
}
}
}

[/java]