5 min read

This article is written by Sunny Kumar Aditya and Vikash Kumar Karn, the authors of Android SQLite Essentials. There are four essential components in an Android Application: activity, service, broadcast receiver, and content provider. Content provider is used to manage access to structured set of data. They encapsulate the data and provide abstraction as well as the mechanism for defining data security. However, content providers are primarily intended to be used by other applications that access the provider using a provider’s client object. Together, providers and provider clients offer a consistent, standard interface to data that also handles inter-process communication and secure data access.

(For more resources related to this topic, see here.)

A content provider allows one app to share data with other applications. By design, an Android SQLite database created by an application is private to the application; it is excellent if you consider the security point of view but troublesome when you want to share data across different applications. This is where a content provider comes to the rescue; you can easily share data by building your content provider. It is important to note that although our discussion would focus on a database, a content provider is not limited to it. It can also be used to serve file data that normally goes into files, such as photos, audio, or videos. The interaction between Application A and B happens while exchanging data can be seen in the following diagram:

Here we have an Application A, whose activity needs to access the database of Application B. As we already read, the database of the Application B is stored in the internal memory and cannot be directly accessed by Application A. This is where the Content Provider comes into the picture; it allows us to share data and modify access to other applications. The content provider implements methods for querying, inserting, updating, and deleting data in databases. Application A now requests the content provider to perform some desired operations on behalf of it. We would explore the use of Content Provider to fetch contacts from a phone’s contact database.

Using existing content providers

Android lists a lot of standard content providers that we can use. Some of them are Browser, CalendarContract, CallLog, Contacts, ContactsContract, MediaStore, userDictionary, and so on.

We will fetch contacts from a phone’s contact list with the help of system’s existing ContentProvider and ContentResolver. We will be using the ContactsContract provider for this purpose.

What is a content resolver?

The ContentResolver object in the application’s context is used to communicate with the provider as a client. The ContentResolver object communicates with the provider object—an instance of a class that implements ContentProvider. The provider object receives data requests from clients, performs the requested action, and returns the results.

ContentResolver is the single, global instance in our application that provides access to other application’s content provider; we do not need to worry about handling inter-process communication. The ContentResolver methods provide the basic CRUD (create, retrieve, update, and delete) functions of persistent storage; it has methods that call identically named methods in the provider object but does not know the implementation.

In the code provided in the corresponding AddNewContactActivity class, we will initiate picking of contact by building an intent object, Intent.ACTION_PICK, that allows us to pick an item from a data source; in addition, all we need to know is the URI of the provider, which in our case is ContactsContract.Contacts.CONTENT_URI:

public void pickContact() {
   try {
      Intent cIntent = new Intent(Intent.ACTION_PICK,
         ContactsContract.Contacts.CONTENT_URI);
      startActivityForResult(cIntent, PICK_CONTACT);
   } catch (Exception e) {
      e.printStackTrace();
      Log.i(TAG, "Exception while picking contact");
   }
}

The code used in this article is placed at GitHub: https://github.com/sunwicked/Ch3-PersonalContactManager/tree/master

This functionality is also provided by Messaging, Gallery, and Contacts. The Contacts screen will pop up allowing us to browse or search for contacts we require to migrate to our new application. In onActivityResult, that is our next stop, we will use the method to handle our corresponding request to pick and use contacts. Let’s look at the code we have to add to pick contacts from an Android’s contact provider:

protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{
.
.

else if (requestCode == PICK_CONTACT) {
   if (resultCode == Activity.RESULT_OK)

   {
      Uri contactData = data.getData();
         Cursor c = getContentResolver().query(contactData, null, null,
            null, null);
         if (c.moveToFirst()) {
            String id = c
               .getString(c.getColumnIndexOrThrow(ContactsContract.Contacts._ID));

            String hasPhone = c
               .getString(c.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));

            if (hasPhone.equalsIgnoreCase("1")) {
               Cursor phones = getContentResolver().query(ContactsContract.
			   CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.
			   Phone.CONTACT_ID + " = " + id, null, null);
               phones.moveToFirst();
               contactPhone.setText(phones.getString(phones.getColumnIndex("data1")));

               contactName
                  .setText(phones.getString(phones.getColumnIndex(ContactsContract.Contacts.
				  DISPLAY_NAME)));

 }
…..

We start by checking whether the request code is matching ours, and then we cross check resultcode. We get the content resolver object by making a call to getcontentresolver on the Context object; it is a method of the android.content.Context class. As we are in an activity that inherits from Context, we do not need to be explicit in making a call to it; same goes for services. We will now check whether the contact we picked has a phone number or not. After verifying the necessary details, we pull data that we require, such as contact name and phone number, and set them in relevant fields.

Summary

This article reflects on how to access and share data in Android via content providers and how to construct a content provider. We also talk about content resolvers and how they are used to communicate with the providers as a client.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here