Creating a Contacts Application

Making a contacts application is a bit redundant for a phone like android but it's a good way to get your feet wet on the basics of android databases (SQLite). I have used and simplified the Notepad tutorial that google had created for android. I recommend you to check it out after this.

Android Database
Android uses the SQLite Databases for saving its files. SQLite is an open source embeddable database engine written in C by D. Richard Hipp. It is entirely self-contained with no external dependencies and is suitable for mobile devices and applications alike. Google exposes the SQLite functionality using the android.database.sqlite package. The recommended way (and arguably more efficient method) to use it within an application is to use Cursor to point to return the findings of the queries and using ContentValues to save data values to the databases.

Contacts Application Objective
We want to demonstrate using the database functionality in the android stack by making a contacts application. Although in real life, such an application might not be used for saving contacts in the phone itself, it can be used to replace the default contacts application if extended properly with the databases exposed using the ContentProvider class. However, the objective here is to use the application to interface with the SQLite database in the phone and save contacts information in them.

Starting out
First of all, we start out with a new eclipse project which can be created from File>New>Project and select Android Project from the dialog. Set the following attributes in the dialog


 * Project name: Contacts
 * Package name: org.hfoss.contacts
 * Activity name: ContactsApp
 * Application name: HFOSS contacts

Making the resources file
We want to add a few strings to the applications, so that we are not hard coding strings and values in our applications. So, open up your res/values/strings.xml file and add these in between the tags.

Making the interfaces
Applications in android are designed using the xml files at res/layout. So, create a new file from File>New>file and name the file contact_list.xml and put the following content in it:

Understanding xml file
This xml file is special for ListActivity activity it assigns a ListView if the content is available else it just prints an unavailable entry. You don't need to make a new id anywhere for this to work, android:list and android:empty are built in to android.

We also need an editing activity if we want to allow our users to enter contact information. Follow the instructions as above and create a new file contact_edit.xml with the following content. Remember to download the file (Right Click>Save Link as in firefox) because some browsers try to parse the file and copying that might not give desirable results.

Understanding the xml file
The xml file here uses the RelativeLayout for laying out the buttons and EditText views for editing the content.

You need to create another xml file to put the content from the Database to the screen on the list. We want to create a new file contact_row.xml for that with two columns, one for name and other for the phone number.

Making DBHelper
We can make a DBHelper class to keep the SQL codes away from the application and avoiding hardcoding everything in the application. We need the following fields in our table, so we make strings that will help us access the values later from our application.
 * Create a new class DBHelper in src>org.hfoss.ContactsApp (In package view in eclipse)

Initialization
Do a Ctrl+Shift+O to update the import files

Creating and Deleting rows
To save the data to android database that we have created, we need to use the ContentValues to save the key-value pairs which can then be used to insert the row into the table. To delete, we are just checking for the specific rowId and deleting that entry. Updating the row is the same as creating the row but with rowId supplied because we want to update a specific rowId supplied from the ContactEdit activity. Do a Ctrl+Shift+O to update the import files

Listing Contacts
We need to list the contacts from the database in the ContactApp activity. Since we want to display the contacts as a list,we want our ContactApp to be an extension of ListActivity and not Activity. So we change to

Here, the line 3 gets the layout contact_list.xml and sets it as the view for the Activity when it loads. We want the application to load the data from the database when it loads using the fillData function. So we create it.

The code here first gets all the Rows in the cursor c and then gets a adapter based on the contact_row layout file we created earlier. It uses the name and mobile number to fill the name and phonenumber columns. It's displayed when the adapter is set as the ListAdapter for the ListActivity. We can see the Adapter design pattern here as ListAdapter adapts(so to say) our cursor for the ListActivity to display. We supply the display Resource Ids, the column names that we want to get  , the cursor c and the layout's Resource Id on which to lay them onto (we created it before in res/layout/contact_row). This mapping is automatically done with the Adapter class here.

Getting Contacts
As you might have seen when you pasted the above code, eclipse showed an error for the fetchAllRows method. So, we make it. Well, there's a much deeper reason for it. Our code just wont make any sense if we don't get any data into it. So, we want to fetch rows to display. The second function fetchAllRows gets everything from the database. It is good enough for our purposes to get all the columns and rows for displaying in the Activity. The first one looks a bit complicated but it isn't. It just gets the value from the database where rowId is equal to the given row Id.

The concept here to remember is that query function just creates a SQL query for us.

Creating Menus
We want to add options to insert a new contact to the database or delete it. We provide a menu to do so in Android. We add these lines to the method in the ContactApp.java file What this code does is that it adds the items Insert and Delete Contacts to the menu of the Activity. It assigns the menu-group (0 since we want it to be at the top level, the id- Menu.FIRST and Menu.FIRST+1 since we want the delete menu item to follow the insert menu item.

Menu Options
With these menu options, we want to detect the insert menu item and open up an editing screen(ContactEdit.java) to enter the credentials of a new contact and just delete and refresh the list if the delete menu item is selected.

Creating Contact
We want to open up a new Activity whenever the user wants to create a new contact. We open the ContactEdit Activity whenever the user wants to create a new contact. We assign the CONTACT_CREATE when spawning the sub-Activity for two reasons because for one, anything below 0 is passd to startSubActivity it creates a new Activity and not the sub-Activity that we wanted to do. So the back button won't work.

Detecting clicks
We want to open the contact page for the person to view and edit the details everytime the user clicks a list item. What we need to do is, we need to get all the details of the database's current cursor position and send it to the contact editing interface. We use intents to do so. When we spawn an activity, we pass an intent that we want to run the activity with certain characteristics. Why not send some data with it? Here the Bundles come into picture because now we can pass data in the form of key value pairs in the bundle that is passed to an activity.

Editing Contact
First, we want to get all the views including the TextViews and the submit button. Now we want to check if we have anything passed to us in the extras Bundle. The code here checks if the intent passed to the Activity has any Extra information in it. It is useful for passing values at instantiation of the Activity as an intent. We can then set the values for the screen views here, with some check of course. Now we need to add a listener for the confirm button at the bottom of the view (OK, doesn't matter wherever it is). The Listener is made on the next code block.

Saving to the database
We could save the database from here as well, but we want to have a single point for saving database details, so we will pass similar key value pair to the parent database as a bundle. Here, we add the different database keys with their corresponding values and with a RESULT_OK constant(defined in Android SDK), we send the bundle data with setResult. It is passed on to the ContactApp Activity when the application exits.

Let's go back to ContactApp.java where we interpret the results and save to the database. Do you remember sending some constant when spawning a new sub-Activity, this is where it's really useful. If the result code is RESULT_OK, which is returned by Activity if everything is fine, similar to return codes in C. Then we get all the data, like name, address, home, mobile. Now, if it is for a new contact, we run dbHelper.createRow and if it's an update, we just update the database.

Completed Files
If you want to have a look at the Completed File, it is here