Querying a Content Provider

You need three pieces of information to query a content provider:

• The URI that identifies the provider

• The names of the data fields you want to receive

• The data types for those fields

If you're querying a particular record, you also need the ID for that record. Making the query

To query a content provider, you can use either the ContentResolver.query() method or the Activity.managedQuery() method. Both methods take the same set of arguments, and both return a Cursor object. However, managedQuery() causes the activity to manage the life cycle of the Cursor. A managed Cursor handles all of the niceties, such as unloading itself when the activity pauses, and requerying itself when the activity restarts. You can ask an Activity to begin managing an unmanaged Cursor object for you by calling Activity.startManagingCursor().

The first argument to either quervn or managedouervn is the provider URI — the content_uri constant that identifies a particular ContentProvider and data set (see URIs earlier).

To restrict a query to just one record, you can append the _id value for that record to the URI — that is, place a string matching the ID as the last segment of the path part of the URI. For example, if the ID is 23, the URI would be:

There are some helper methods, particularly Contenturis.withAppendedid() and uri.withAppendedPathn, that make it easy to append an ID to a URI. Both are static methods that return a Uri object with the ID added. So, for example, if you were looking for record 23 in the database of people contacts, you might construct a query as follows:

import android.provider.Contacts.People; import android.content.ContentUris; import android.net.Uri; import android.database.Cursor;

// Use the ContentUris method to produce the base URI for the contact with _ID == 23.

Uri myPerson = ContentUris.withAppendedId(People.CONTENT_URI, 23);

// Alternat ively, use the Uri method to produce the base URI. // It takes a string rather than an integer.

Uri myPerson = Uri.withAppendedPath(People.CONTENT_URI, "23"); // Then query for this specific record:

Cursor cur = managedQuery(myPerson, null, null, null, null);

The other arguments to the querv() and managedouervn methods delimit the query in more detail. They are:

• The names of the data columns that should be returned. A null value returns all columns. Otherwise, only columns that are listed by name are returned. All the content providers that come with the platform define constants for their columns. For example, the android.provider.Contacts.Phones class defines constants for the names of the columns in the phone table illustrated earlier — _id, number, number_key, name, and so on.

• A filter detailing which rows to return, formatted as an SQL where clause (excluding the where itself). A null value returns all rows (unless the URI limits the query to a single record).

• Selection arguments.

• A sorting order for the rows that are returned, formatted as an SQL order by clause (excluding the order by itself). A null value returns the records in the default order for the table, which may be unordered.

Let's look at an example query to retrieve a list of contact names and their primary phone numbers:

import android.provider.Contacts.People; import android.database.Cursor;

// Form an array specifying which columns to return. String[] projection = new String[] {

People._ID, People._COUNT, People.NAME, People.NUMBER

// Get the base URI for the People table in the Contacts content provider. Uri contacts = People.CONTENT_URI;

Cursor managedCursor = managedQuery(contacts, projection, // Which columns to return null, // Which rows to return (all rows)

null, // Selection arguments (none)

// Put the results in ascending order by name People.NAME + " ASC");

This query retrieves data from the People table of the Contacts content provider. It gets the name, primary phone number, and unique record ID for each contact. It also reports the number of records that are returned as the _count field of each record.

The constants for the names of the columns are defined in various interfaces — _id and _count in BaseColumns, name in PeopleColumns, and number in PhoneColumns. The Contacts.People class implements each of these interfaces, which is why the code example above could refer to them using just the class name.

0 0

Post a comment