With the introduction of the new ContactsContract
to replace the previous
Contacts API in Android 2.0, came a drastic increase in both functional capability
and API complexity for applications wishing to interact with the Contacts Provider.
This level of access allows applications to make very detailed and specific additions
and updates to the Contacts/People database on the device; however it can make some
of the common simpler operations seem like they require an unnecessary amount of code.
We are going to look at some ways to try to simplify some common interactions that
an application may need to have with the Contacts Provider through the use of a few
Intents that ContactsContract
provides. In this article, we are going to use Intents
to let the existing device Contacts UI handle the following operations, simply
returning a result to our application where appropriate:
- Selecting a contact
- Adding a new contact
- Searching for an existing contact to edit
The ContactsContract
API certainly provides all the functionality necessary for you
to build your own UI to manage the data your application is interested in by way of
making queries, updates, and inserts on the URIs for each table in the Content Provider.
However, in many cases the system-defined UI for these tasks is not only adequate,
but helps provide a consistent experience to the user.
Selecting (Picking) A Contact
This operation involves displaying a list of the the users contacts so they can select one to perform further actions on (perhaps to send that person and email or call them). Rather than creating your own picker UI, you can use the following code to create an Intent and launch the Contacts application’s existing picker:
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setData(ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
Since we have launched the new Activity expecting a result, onActivityResult()
will be called when the user is finished, and the data Uri
will contain a lookup
URI that can be used to inspect the details of the Contact selected by the user:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == PICK_CONTACT && resultCode == RESULT_OK) {
//returns a lookup URI to the contact just selected
Uri selectedContact = data.getData();
}
}
Adding a New Contact
This operation involves inserting a new contact on the user’s device.
Due to the large number of tables involved in storing all the common kinds of data
(phone, email, address, etc.), constructing this insert using the raw provider
queries can be quite daunting. ContactsContract
provides a series of actions and
extras in the ContactsContract.Intents.Insert
utility class.
Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
// Just two examples of information you can send to pre-fill data
intent.putExtra(ContactsContract.Intents.Insert.NAME, "Dave Smith");
intent.putExtra(ContactsContract.Intents.Insert.COMPANY, "Xcellent Creations, Inc.");
startActivityForResult(intent, ADD_CONTACT);
There is a host of extras defined in ContactsContract.Intents.Insert
that can be
used to pre-fill data in the add form, but here is a list of some more common choices:
ContactsContract.Intents.Insert.NAME
- Full name of the new contact
ContactsContract.Intents.Insert.COMPANY
- Company/Organization of the new contact
ContactsContract.Intents.Insert.EMAIL
- Email address of the new contact
ContactsContract.Intents.Insert.PHONE
- Phone number of the new contact
ContactsContract.Intents.Insert.POSTAL
- Address for the new contact
As with the picker, launching the new Activity with a result expectation will call
onActivityResult()
with a lookup Uri
for the newly created Contact record,
so that your application can display the details of the insert if you wish.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == ADD_CONTACT && resultCode == RESULT_OK) {
//returns a lookup URI to the contact just inserted
Uri newContact = data.getData();
}
}
Search for a Contact
Finally, the ContactsContract
API includes another convenience intent to look for
a specific contact record by telephone number or email address. The Intent action
ContactsContract.Intents.SHOW_OR_CREATE_CONTACT
can be passed with a mailto:
or tel:
scheme Uri
, and it will search for a matching contact. If a match is
found, the contacts details are displayed for further review or editing (all within
the standard Contacts application UI). If no match is found, by default a dialog will
be displayed asking if the user would like to create a contact with the given email
or phone.
Intent intent = new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT);
//PICK ONE of the following:
//For searching via telephone number
// intent.setData(Uri.fromParts("tel", "8001234567", null));
//For searching via email address
// intent.setData(Uri.fromParts("mailto", "johndoe@gmail.com", null));
//We'll use an email search for the example
intent.setData(Uri.fromParts("mailto", "johndoe@gmail.com", null));
startActivity(intent);
The same extra parameters may be passed along with the Intent to pre-fill the entry
form in case the matched contact is edited or if the user opts to create a new contact.
In addition, a special extra is defined (ContactsContract.Intents.EXTRA_FORCE_CREATE
)
that allows you to skip over the user dialog and immediately open the create contact
form if no matches are found.
Here is an example that includes some fields to be pre-filled and skips the dialog for creating a new contact:
Intent intent = new Intent(ContactsContract.Intents.SHOW_OR_CREATE_CONTACT);
intent.setData(Uri.fromParts("tel", "8001234567", null));
//If no match and we create, skip the user prompt dialog
intent.putExtra(ContactsContract.Intents.EXTRA_FORCE_CREATE, true);
//Values to tag along for an insert
intent.putExtra(ContactsContract.Intents.Insert.NAME, "David Smith");
intent.putExtra(ContactsContract.Intents.Insert.COMPANY, "Xcellent Creations, Inc.");
startActivity(intent);
Notice in this case that we aren’t interested in any result returned by the Contacts
application. With the SHOW_OR_CREATE_CONTACT
Intent, no interesting data is returned
from the operation.
Hopefully these tips will help take the complexity out of using the Contacts API for those cases where your application does not need to utilize the full access of the Content Provider!