Android Reading Data Using Uri

Now you know that to retrieve data from a content provider you need to use URIs
supplied by that content provider. Because the URIs defined by a content provider are
unique to that provider, it is important that these URIs are documented and available to
programmers to see and then call. The providers that come with Android do this by
defining constants representing these URI strings. 
Consider these three URIs defined by helper classes in the Android SDK: 
MediaStore.Images.Media.INTERNAL_CONTENT_URI 
MediaStore.Images.Media.EXTERNAL_CONTENT_URI 
Contacts.People.CONTENT_URI 
The equivalent textual URI strings would be as follows:
content://media/internal/images
content://media/external/images
content://contacts/people/ 
The MediaStore provider defines two URIs and the Contacts provider defines one URI. If
you notice, these constants are defined using a hierarchical scheme. For example the
content URI example for the contacts is pointed out as Contacts.People.CONTENT_URI.
This is because the databases of contacts may have a lot of tables to represent the
entitities of a Contact. People is one of the tables or a collection. Each primary entity of a
database may carry its own content URI, however, all rooted at the base authority name
(such as contacts://contacts in the case of contacts provider). 

NOTE:  In the reference Contacts.People.CONTENT_URI, Contacts is a java package and
People is the interface within that package.
Given these URIs, the code to retrieve a single row of people from the contacts provider
looks like this: 
Uri peopleBaseUri = Contacts.People.CONTENT_URI;
Uri myPersonUri = peopleBaseUri.withAppendedId(Contacts.People.CONTENT_URI, 23);
 
//Query for this record.
//managedQuery is a method on Activity class
Cursor cur = managedQuery(myPersonUri, null, null, null);
Notice how the Contacts.People.CONTENT_URI is predefined as a constant in the People
class. In this example, the code takes the root URI, adds a specific person ID to it, and
makes a call to the managedQuery method. 
As part of the query against this URI, it is possible to specify a sort order, the columns to
select, and a where clause. These additional parameters are set to null in this example.
NOTE:  A content provider should list which columns it supports by implementing a set of
interfaces or by listing the column names as constants. However, the class or interface that
defines constants for columns should also make the column types clear through a column
naming convention, or comments or documentation, as there is no formal way to indicate the
type of a column through constants.
Listing 3–20 shows how to retrieve a cursor with a specific list of columns from the
People table of the contacts content provider, based on the previous example.
Listing 3–20. Retrieving a Cursor from a Content Provider
// An array specifying which columns to return. 
string[] projection = new string[] {
    People._ID,
    People.NAME,
    People.NUMBER,
};
 
// Get the base URI for People table in Contacts Content Provider.
// ie. content://contacts/people/
Uri mContactsUri = Contacts.People.CONTENT_URI;  
       
// Best way to retrieve a query; returns a managed query. 
Cursor managedCursor = managedQuery( mContactsUri,
                        projection, //Which columns to return. 
                        null,       // WHERE clause
                        Contacts.People.NAME + " ASC"); // Order-by clause.

Notice how a projection is merely an array of strings representing column names. So
unless you know what these columns are, you’ll find it difficult to create a projection.
You should look for these column names in the same class that provides the URI, in this
case the People class. Let’s look at the other column names defined in this class: 
CUSTOM_RINGTONE
DISPLAY_NAME
LAST_TIME_CONTACTED
NAME
NOTES
PHOTO_VERSION
SEND_TO_VOICE_MAIL
STARRED
TIMES_CONTACTED
You can discover more about each of these columns by looking at the SDK
documentation for the android.provider.Contacts.PeopleColumns class, available at
this URL:
http://code.google.com/android/reference/android/provider/
Contacts.PeopleColumns.html
As alluded to earlier, a database like contacts contains several tables, each of which is
represented by a class or an interface to describe its columns and their types. Let’s take
a look at the package android.providers.Contacts, documented at the following URL: 
http://code.google.com/android/reference/android/provider/Contacts.html
You will see that this package has the following nested classes or interfaces: 
ContactMethods
Extensions
Groups
Organizations
People
Phones
Photos
Settings
Each of these classes represents a table name in the contacts.db database, and each
table is responsible for describing its own URI structure. Plus, a corresponding Columns
interface is defined for each class to identify the column names, such as PeopleColumns. 
Let’s revisit the cursor that is returned: it contains zero or more records. Column names,
order, and type are provider specific. However, every row returned has a default column
called _id representing a unique ID for that row.

原文地址:https://www.cnblogs.com/enricozhang/p/1750285.html