summaryrefslogtreecommitdiffstats
path: root/docs/html/guide/topics/providers/content-providers.jd
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html/guide/topics/providers/content-providers.jd')
-rw-r--r--docs/html/guide/topics/providers/content-providers.jd994
1 files changed, 84 insertions, 910 deletions
diff --git a/docs/html/guide/topics/providers/content-providers.jd b/docs/html/guide/topics/providers/content-providers.jd
index 95331ce..1707f03 100644
--- a/docs/html/guide/topics/providers/content-providers.jd
+++ b/docs/html/guide/topics/providers/content-providers.jd
@@ -1,922 +1,96 @@
page.title=Content Providers
@jd:body
-
<div id="qv-wrapper">
<div id="qv">
-<h2>In this document</h2>
-<ol>
-<li><a href="#basics">Content provider basics</a></li>
-<li><a href="#querying">Querying a content provider</a></li>
-<li><a href="#modifying">Modifying data in a provider</a></li>
-<li><a href="#creating">Creating a content provider</a></li>
-<li><a href="#urisum">Content URI summary</a></li>
-</ol>
-<h2>Key classes</h2>
+<!-- In this document -->
+<h2>Topics</h2>
<ol>
-<li>{@link android.content.ContentProvider}</li>
-<li>{@link android.content.ContentResolver}</li>
-<li>{@link android.database.Cursor}</li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Content Provider Basics</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ Creating a Content Provider</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar Provider</a>
+ </li>
</ol>
-<h2>See also</h2>
-<ol>
- <li><a href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar Provider</a></li>
-</ol>
+ <!-- Related Samples -->
+<h2>Related Samples</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/samples/ContactManager/index.html">
+ Contact Manager</a> application
+ </li>
+ <li>
+ <a
+ href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html">
+ &quot;Cursor (People)&quot;
+ </a>
+ </li>
+ <li>
+ <a
+ href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html">
+ &quot;Cursor (Phones)&quot;</a>
+ </li>
+ </ol>
</div>
</div>
-
-<p>
-Content providers store and retrieve data and make it accessible to all
-applications. They're the only way to share data across applications; there's
-no common storage area that all Android packages can access.
-</p>
-
-<p>
-Android ships with a number of content providers for common data types
-(audio, video, images, personal contact information, and so on). You can
-see some of them listed in the {@link android.provider android.provider}
-package. You can query these providers for the data they contain (although,
-for some, you must acquire the proper permission to read the data).
-</p>
-
-<p class="note"><strong>Note:</strong> Android 4.0 introduces the Calendar
-Provider. For more information, see <a
-href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar
-Provider</a>.</p>
-<p>
-If you want to make your own data public, you have two options: You can
-create your own content provider (a {@link android.content.ContentProvider}
-subclass) or you can add the data to an existing provider &mdash; if there's
-one that controls the same type of data and you have permission to write to it.
-</p>
-
-<p>
-This document is an introduction to using content providers. After a
-brief discussion of the fundamentals, it explores how to query a content
-provider, how to modify data controlled by a provider, and how to create
-a content provider of your own.
-</p>
-
-
-<h2><a name="basics"></a>Content Provider Basics</h2>
-
-<p>
-How a content provider actually stores its data under the covers is
-up to its designer. But all content providers implement a common interface
-for querying the provider and returning results &mdash; as well as for
-adding, altering, and deleting data.
-</p>
-
-<p>
-It's an interface that clients use indirectly, most generally through
-{@link android.content.ContentResolver} objects. You get a ContentResolver
-by calling <code>{@link android.content.Context#getContentResolver
-getContentResolver()}</code> from within the implementation of an Activity
-or other application component:
-</p>
-
-<pre>ContentResolver cr = getContentResolver();</pre>
-
-<p>
-You can then use the ContentResolver's methods to interact with whatever
-content providers you're interested in.
-</p>
-
-<p>
-When a query is initiated, the Android system identifies the content provider
-that's the target of the query and makes sure that it is up and running.
-The system instantiates all ContentProvider objects; you never need to do it
-on your own. In fact, you never deal directly with ContentProvider objects
-at all. Typically, there's just a single instance of each type of
-ContentProvider. But it can communicate with multiple ContentResolver objects
-in different applications and processes. The interaction between processes is
-handled by the ContentResolver and ContentProvider classes.
-</p>
-
-
-<h3>The data model</h3>
-
-<p>
-Content providers expose their data as a simple table on a database model,
-where each row is a record and each column is data of a particular type
-and meaning. For example, information about people and their phone numbers
-might be exposed as follows:
-</p>
-
-<table>
- <tr>
- <th scope="col">_ID</th>
- <th scope="col">NUMBER</th>
- <th scope="col">NUMBER_KEY</th>
- <th scope="col">LABEL</th>
- <th scope="col">NAME</th>
- <th scope="col">TYPE</th>
- </tr>
- <tr>
- <td>13</td>
- <td>(425) 555 6677</td>
- <td>425 555 6677</td>
- <td>Kirkland office</td>
- <td>Bully Pulpit</td>
- <td>{@code TYPE_WORK}</td>
- </tr>
- <tr>
- <td>44</td>
- <td>(212) 555-1234</td>
- <td>212 555 1234</td>
- <td>NY apartment</td>
- <td>Alan Vain</td>
- <td>{@code TYPE_HOME}</td>
- </tr>
- <tr>
- <td>45</td>
- <td>(212) 555-6657</td>
- <td>212 555 6657</td>
- <td>Downtown office</td>
- <td>Alan Vain</td>
- <td>{@code TYPE_MOBILE}</td>
- </tr>
- <tr>
- <td>53</td>
- <td>201.555.4433</td>
- <td>201 555 4433</td>
- <td>Love Nest</td>
- <td>Rex Cars</td>
- <td>{@code TYPE_HOME}</td>
- </tr>
-</table>
-
-<p>
-Every record includes a numeric {@code _ID} field that uniquely identifies
-the record within the table. IDs can be used to match records in related
-tables &mdash; for example, to find a person's phone number in one table
-and pictures of that person in another.
-</p>
-
-<p>
-A query returns a {@link android.database.Cursor} object that can move from
-record to record and column to column to read the contents of each field.
-It has specialized methods for reading each type of data. So, to read a field,
-you must know what type of data the field contains. (There's more on query
-results and Cursor objects later.)
-</p>
-
-
-<h3><a name="uri"></a>URIs</h3>
-
-<p>
-Each content provider exposes a public URI (wrapped as a {@link android.net.Uri}
-object) that uniquely identifies its data set. A content provider that controls
-multiple data sets (multiple tables) exposes a separate URI for each one. All
-URIs for providers begin with the string "{@code content://}". The {@code content:}
-scheme identifies the data as being controlled by a content provider.
-</p>
-
-<p>
-If you're defining a content provider, it's a good idea to also define a
-constant for its URI, to simplify client code and make future updates cleaner.
-Android defines {@code CONTENT_URI} constants for all the providers that come
-with the platform. For example, the URI for the table that matches
-phone numbers to people and the URI for the table that holds pictures of
-people (both controlled by the Contacts content provider) are:
-</p>
-
-<p>
-<p style="margin-left: 2em">{@code android.provider.Contacts.Phones.CONTENT_URI}
-<br/>{@code android.provider.Contacts.Photos.CONTENT_URI}
-</p>
-
-<p>
-The URI constant is used in all interactions with the content provider.
-Every {@link android.content.ContentResolver} method takes the URI
-as its first argument. It's what identifies which provider the ContentResolver
-should talk to and which table of the provider is being targeted.
-</p>
-
-
-<h2><a name="querying"></a>Querying a Content Provider</h2>
-
-<p>
-You need three pieces of information to query a content provider:
-</p>
-
-<ul>
-<li>The URI that identifies the provider</li>
-<li>The names of the data fields you want to receive</li>
-<li>The data types for those fields</li>
-</ul>
-
-<p>
-If you're querying a particular record, you also need the ID for that record.
-</p>
-
-
-<h3>Making the query</h3>
-
-<p>
-To query a content provider, you can use either the
-<code>{@link android.content.ContentResolver#query ContentResolver.query()}</code>
-method or the <code>{@link android.app.Activity#managedQuery
-Activity.managedQuery()}</code> method.
-Both methods take the same set of arguments, and both return a
-Cursor object. However, {@code 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
-<code>{@link android.app.Activity#startManagingCursor
-Activity.startManagingCursor()}</code>.
-</p>
-
-<p>
-The first argument to either <code>{@link android.content.ContentResolver#query query()}</code>
-or <code>{@link android.app.Activity#managedQuery managedQuery()}</code> is the provider URI
-&mdash; the {@code CONTENT_URI} constant that identifies a particular
-ContentProvider and data set (see <a href="#uri">URIs</a> earlier).
-</p>
-
-<p>
-To restrict a query to just one record, you can append the {@code _ID} value for
-that record to the URI &mdash; 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:
-</p>
-
-<p style="margin-left: 2em">{@code content://. . . ./23}</p>
-
-<p>
-There are some helper methods, particularly
-<code>{@link android.content.ContentUris#withAppendedId
-ContentUris.withAppendedId()}</code> and <code>{@link
-android.net.Uri#withAppendedPath Uri.withAppendedPath()}</code>,
-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:
-</p>
-
-<pre>
-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);
-
-// Alternatively, 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);
-</pre>
-
-<p>
-The other arguments to the <code>{@link android.content.ContentResolver#query query()}</code>
-and <code>{@link android.app.Activity#managedQuery managedQuery()}</code> methods delimit
-the query in more detail. They are:
-</p>
-
-<ul>
-<li>The names of the data columns that should be returned. A {@code 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
-{@link android.provider.Contacts.Phones android.provider.Contacts.Phones} class
-defines constants for the names of the columns in the phone table illustrated
-earlier &mdash; {@code _ID}, {@code NUMBER}, {@code NUMBER_KEY}, {@code NAME},
-and so on.</li>
-
-<li><p>A filter detailing which rows to return, formatted as an SQL {@code WHERE}
-clause (excluding the {@code WHERE} itself). A {@code null} value returns
-all rows (unless the URI limits the query to a single record).</p></li>
-
-<li><p>Selection arguments.</p></li>
-
-<li><p>A sorting order for the rows that are returned, formatted as an SQL
-{@code ORDER BY} clause (excluding the {@code ORDER BY} itself). A {@code null}
-value returns the records in the default order for the table, which may be
-unordered.</p></li>
-</ul>
-
-<p>
-Let's look at an example query to retrieve a list of contact names and their
-primary phone numbers:
-</p>
-
-<pre>
-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;
-
-// Make the query.
-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");
-</pre>
-
-<p>
-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 {@code _COUNT} field of each record.
-</p>
-
-<p>
-The constants for the names of the columns are defined in various interfaces
-&mdash; {@code _ID} and {@code _COUNT} in
-{@link android.provider.BaseColumns BaseColumns}, {@code NAME} in {@link android.provider.Contacts.PeopleColumns PeopleColumns}, and {@code NUMBER}
-in {@link android.provider.Contacts.PhonesColumns PhoneColumns}. The
-{@link android.provider.Contacts.People Contacts.People} class implements
-each of these interfaces, which is why the code example above could refer
-to them using just the class name.
-</p>
-
-
-<h3>What a query returns</h3>
-
-<p>
-A query returns a set of zero or more database records. The names of the
-columns, their default order, and their data types are specific to each
-content provider.
-But every provider has an {@code _ID} column, which holds a unique numeric
-ID for each record. Every provider can also report the number
-of records returned as the {@code _COUNT} column; its value
-is the same for all rows.
-</p>
-
-<p>
-Here is an example result set for the query in the previous section:
-</p>
-
-<table border="1">
- <tbody>
- <tr>
- <th scope="col">_ID</th>
- <th scope="col">_COUNT</th>
- <th scope="col">NAME</th>
- <th scope="col">NUMBER</th>
- </tr>
- <tr>
- <td>44</td>
- <td>3</td>
- <td>Alan Vain</td>
- <td>212 555 1234</td>
- </tr>
- <tr>
- <td>13</td>
- <td>3</td>
- <td>Bully Pulpit</td>
- <td>425 555 6677</td>
- </tr>
- <tr>
- <td>53</td>
- <td>3</td>
- <td>Rex Cars</td>
- <td>201 555 4433</td>
- </tr>
- </tbody>
-</table>
-
-<p>
-The retrieved data is exposed by a {@link android.database.Cursor Cursor}
-object that can be used to iterate backward or forward through the result
-set. You can use this object only to read the data. To add, modify, or
-delete data, you must use a ContentResolver object.
-</p>
-
-
-<h3>Reading retrieved data</h3>
-
-<p>
-The Cursor object returned by a query provides access to a recordset of
-results. If you have queried for a specific record by ID, this set will
-contain only one value. Otherwise, it can contain multiple values.
-(If there are no matches, it can also be empty.) You
-can read data from specific fields in the record, but you must know the
-data type of the field, because the Cursor object has a separate method
-for reading each type of data &mdash; such as <code>{@link
-android.database.Cursor#getString getString()}</code>, <code>{@link
-android.database.Cursor#getInt getInt()}</code>, and <code>{@link
-android.database.Cursor#getFloat getFloat()}</code>.
-(However, for most types, if you call the method for reading strings,
-the Cursor object will give you the String representation of the data.)
-The Cursor lets you request the column name from the index of the column,
-or the index number from the column name.
-</p>
-
-<p>
-The following snippet demonstrates reading names and phone numbers from
-the query illustrated earlier:
-</p>
-
-<pre>
-import android.provider.Contacts.People;
-
-private void getColumnData(Cursor cur){
- if (cur.moveToFirst()) {
-
- String name;
- String phoneNumber;
- int nameColumn = cur.getColumnIndex(People.NAME);
- int phoneColumn = cur.getColumnIndex(People.NUMBER);
- String imagePath;
-
- do {
- // Get the field values
- name = cur.getString(nameColumn);
- phoneNumber = cur.getString(phoneColumn);
-
- // Do something with the values.
- ...
-
- } while (cur.moveToNext());
-
- }
-}
-</pre>
-
-<p>
-If a query can return binary data, such as an image or sound, the data
-may be directly entered in the table or the table entry for that data may be
-a string specifying a {@code content:} URI that you can use to get the data.
-In general, smaller amounts of data (say, from 20 to 50K or less) are most often
-directly entered in the table and can be read by calling
-<code>{@link android.database.Cursor#getBlob Cursor.getBlob()}</code>.
-It returns a byte array.
-</p>
-
-<p>
-If the table entry is a {@code content:} URI, you should never try to open
-and read the file directly (for one thing, permissions problems can make this
-fail). Instead, you should call
-<code>{@link android.content.ContentResolver#openInputStream
-ContentResolver.openInputStream()}</code> to get an
-{@link java.io.InputStream} object that you can use to read the data.
-</p>
-
-
-<h2><a name="modifying"></a>Modifying Data</h2>
-
-<p>
-Data kept by a content provider can be modified by:
-</p>
-
-<ul>
-<p><li>Adding new records</li>
-<li>Adding new values to existing records</li>
-<li>Batch updating existing records</li>
-<li>Deleting records</li>
-</ul>
-
-<p>
-All data modification is accomplished using {@link android.content.ContentResolver}
-methods. Some content providers require a more restrictive permission for writing
-data than they do for reading it. If you don't have permission to write to a
-content provider, the ContentResolver methods will fail.
-</p>
-
-
-<h3>Adding records</h3>
-
-<p>
-To add a new record to a content provider, first set up a map of key-value pairs
-in a {@link android.content.ContentValues} object, where each key matches
-the name of a column in the content provider and the value is the desired
-value for the new record in that column. Then call <code>{@link
-android.content.ContentResolver#insert ContentResolver.insert()}</code> and pass
-it the URI of the provider and the ContentValues map. This method returns
-the full URI of the new record &mdash; that is, the provider's URI with
-the appended ID for the new record. You can then use this URI to query and
-get a Cursor over the new record, and to further modify the record.
-Here's an example:
-</p>
-
-<pre>
-import android.provider.Contacts.People;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-
-ContentValues values = new ContentValues();
-
-// Add Abraham Lincoln to contacts and make him a favorite.
-values.put(People.NAME, "Abraham Lincoln");
-// 1 = the new contact is added to favorites
-// 0 = the new contact is not added to favorites
-values.put(People.STARRED, 1);
-
-Uri uri = getContentResolver().insert(People.CONTENT_URI, values);
-</pre>
-
-
-<h3>Adding new values</h3>
-
-<p>
-Once a record exists, you can add new information to it or modify
-existing information. For example, the next step in the example above would
-be to add contact information &mdash; like a phone number or an IM or e-mail
-address &mdash; to the new entry.
-</p>
-
-<p>
-The best way to add to a record in the Contacts database is to append
-the name of the table where the new data goes to the URI for the
-record, then use the amended URI to add the new data values. Each
-Contacts table exposes a name for this purpose as a {@code
-CONTENT_DIRECTORY} constant. The following code continues the previous
-example by adding a phone number and e-mail address for the record
-just created:
-</p>
-
-<pre>
-Uri phoneUri = null;
-Uri emailUri = null;
-
-// Add a phone number for Abraham Lincoln. Begin with the URI for
-// the new record just returned by insert(); it ends with the _ID
-// of the new record, so we don't have to add the ID ourselves.
-// Then append the designation for the phone table to this URI,
-// and use the resulting URI to insert the phone number.
-phoneUri = Uri.withAppendedPath(uri, People.Phones.CONTENT_DIRECTORY);
-
-values.clear();
-values.put(People.Phones.TYPE, People.Phones.TYPE_MOBILE);
-values.put(People.Phones.NUMBER, "1233214567");
-getContentResolver().insert(phoneUri, values);
-
-// Now add an email address in the same way.
-emailUri = Uri.withAppendedPath(uri, People.ContactMethods.CONTENT_DIRECTORY);
-
-values.clear();
-// ContactMethods.KIND is used to distinguish different kinds of
-// contact methods, such as email, IM, etc.
-values.put(People.ContactMethods.KIND, Contacts.KIND_EMAIL);
-values.put(People.ContactMethods.DATA, "test@example.com");
-values.put(People.ContactMethods.TYPE, People.ContactMethods.TYPE_HOME);
-getContentResolver().insert(emailUri, values);
-</pre>
-
-<p>
-You can place small amounts of binary data into a table by calling
-the version of <code>{@link android.content.ContentValues#put
-ContentValues.put()}</code> that takes a byte array.
-That would work for a small icon-like image or a short audio clip, for example.
-However, if you have a large amount of binary data to add, such as a photograph
-or a complete song, put a {@code content:} URI for the data in the table and call
-<code>{@link android.content.ContentResolver#openOutputStream
-ContentResolver.openOutputStream()}</code>
-with the file's URI. (That causes the content provider to store the data
-in a file and record the file path in a hidden field of the record.)
-</p>
-
-<p>
-In this regard, the {@link android.provider.MediaStore} content
-provider, the main provider that dispenses image, audio, and video
-data, employs a special convention: The same URI that is used with
-{@code query()} or {@code managedQuery()} to get meta-information
-about the binary data (such as, the caption of a photograph or the
-date it was taken) is used with {@code openInputStream()}
-to get the data itself. Similarly, the same URI that is used with
-{@code insert()} to put meta-information into a MediaStore record
-is used with {@code openOutputStream()} to place the binary data there.
-The following code snippet illustrates this convention:
-</p>
-
-<pre>
-import android.provider.MediaStore.Images.Media;
-import android.content.ContentValues;
-import java.io.OutputStream;
-
-// Save the name and description of an image in a ContentValues map.
-ContentValues values = new ContentValues(3);
-values.put(Media.DISPLAY_NAME, "road_trip_1");
-values.put(Media.DESCRIPTION, "Day 1, trip to Los Angeles");
-values.put(Media.MIME_TYPE, "image/jpeg");
-
-// Add a new record without the bitmap, but with the values just set.
-// insert() returns the URI of the new record.
-Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
-
-// Now get a handle to the file for that record, and save the data into it.
-// Here, sourceBitmap is a Bitmap object representing the file to save to the database.
-try {
- OutputStream outStream = getContentResolver().openOutputStream(uri);
- sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 50, outStream);
- outStream.close();
-} catch (Exception e) {
- Log.e(TAG, "exception while writing image", e);
-}
-</pre>
-
-
-<h3>Batch updating records</h3>
-
-<p>
-To batch update a group of records (for example, to change "NY" to "New York"
-in all fields), call the <code>{@link
-android.content.ContentResolver#update ContentResolver.update()}</code>
-method with the columns and values to change.
-</p>
-
-
-<h3><a name="deletingrecord"></a>Deleting a record</h3>
-
-<p>
-To delete a single record, call {<code>{@link
-android.content.ContentResolver#delete ContentResolver.delete()}</code>
-with the URI of a specific row.
-</p>
-
<p>
-To delete multiple rows, call <code>{@link
-android.content.ContentResolver#delete ContentResolver.delete()}</code>
-with the URI of the type of record to delete (for example, {@code android.provider.Contacts.People.CONTENT_URI}) and an SQL {@code WHERE}
-clause defining which rows to delete. (<i><b>Caution</b>:
-Be sure to include a valid {@code WHERE} clause if you're deleting a general
-type, or you risk deleting more records than you intended!</i>).
-</p>
-
-
-<h2><a name="creating"></a>Creating a Content Provider</h2>
-
-<p>
-To create a content provider, you must:
-</p>
-
-<ul>
-<li>Set up a system for storing the data. Most content providers
-store their data using Android's file storage methods or SQLite databases,
-but you can store your data any way you want. Android provides the
-{@link android.database.sqlite.SQLiteOpenHelper SQLiteOpenHelper}
-class to help you create a database and {@link
-android.database.sqlite.SQLiteDatabase SQLiteDatabase} to manage it.</li>
-
-<li><p>Extend the {@link android.content.ContentProvider} class to provide
-access to the data.</p></li>
-
-<li><p>Declare the content provider in the manifest file for your
-application (AndroidManifest.xml).</p></li>
-</ul>
-
-<p>
-The following sections have notes on the last two of these tasks.
-</p>
-
-
-<h3>Extending the ContentProvider class</h3>
-
-<p>
-You define a {@link android.content.ContentProvider} subclass to
-expose your data to others using the conventions expected by
-ContentResolver and Cursor objects. Principally, this means
-implementing six abstract methods declared in the ContentProvider class:
-</p>
-
-<p style="margin-left: 2em">{@code query()}
-<br/>{@code insert()}
-<br/>{@code update()}
-<br/>{@code delete()}
-<br/>{@code getType()}
-<br/>{@code onCreate()}</p>
-
-<p>
-The {@code query()} method must return a {@link android.database.Cursor} object
-that can iterate over the requested data. Cursor itself is an interface, but
-Android provides some ready-made Cursor objects that you can use. For example,
-{@link android.database.sqlite.SQLiteCursor} can iterate over data stored in
-an SQLite database. You get the Cursor object by calling any of the {@link
-android.database.sqlite.SQLiteDatabase SQLiteDatabase} class's {@code query()}
-methods. There are other Cursor implementations &mdash; such as {@link
-android.database.MatrixCursor} &mdash; for data not stored in a database.
-</p>
-
-<p>
-Because these ContentProvider methods can be called from
-various ContentResolver objects in different processes and threads,
-they must be implemented in a thread-safe manner.
-</p>
-
-<p>
-As a courtesy, you might also want to call <code>{@link android.content.ContentResolver#notifyChange(android.net.Uri,android.database.ContentObserver)
-ContentResolver.notifyChange()}</code> to notify listeners when there are
-modifications to the data.
-</p>
-
-<p>
-Beyond defining the subclass itself, there are other steps you should take
-to simplify the work of clients and make the class more accessible:
-</p>
-
-<ul>
-<li>Define a {@code public static final} {@link android.net.Uri}
-named {@code CONTENT_URI}. This is the string that represents the full
-{@code content:} URI that your content provider handles. You must define a
-unique string for this value. The best solution is to use the fully-qualified
-class name of the content provider (made lowercase). So, for example, the
-URI for a TransportationProvider class could be defined as follows:
-
-<pre>public static final Uri CONTENT_URI =
- Uri.parse("content://com.example.codelab.transportationprovider");</pre>
-
-<p>
-If the provider has subtables, also define {@code CONTENT_URI} constants for
-each of the subtables. These URIs should all have the same authority (since
-that identifies the content provider), and be distinguished only by their paths.
-For example:
-</p>
-
-<p style="margin-left: 2em">{@code content://com.example.codelab.transportationprovider/train}
-<br/>{@code content://com.example.codelab.transportationprovider/air/domestic}
-<br/>{@code content://com.example.codelab.transportationprovider/air/international}</p>
-
-<p>
-For an overview of {@code content:} URIs, see the <a href="#urisum">Content URI
-Summary</a> at the end of this document.
-</p></li>
-
-<li><p>Define the column names that the content provider will return to clients.
-If you are using an underlying database, these column names are typically
-identical to the SQL database column names they represent. Also define
-{@code public static} String constants that clients can use to specify
-the columns in queries and other instructions.
-</p>
-
-<p>
-Be sure to include an integer column named "{@code _id}"
-(with the constant {@code _ID}) for
-the IDs of the records. You should have this field whether or not you have
-another field (such as a URL) that is also unique among all records. If
-you're using the SQLite database, the {@code _ID} field should be the
-following type:
-</p>
-
-<p style="margin-left: 2em">{@code INTEGER PRIMARY KEY AUTOINCREMENT}</p>
-
-<p>
-The {@code AUTOINCREMENT} descriptor is optional. But without it, SQLite
-increments an ID counter field to the next number above the largest
-existing number in the column. If you delete the last row, the next row added
-will have the same ID as the deleted row. {@code AUTOINCREMENT} avoids this
-by having SQLite increment to the next largest value whether deleted or not.
-</p>
-</li>
-
-<li><p>Carefully document the data type of each column. Clients need this
-information to read the data.</p></li>
-
-<li><p>If you are handling a new data type, you must define a new MIME type
-to return in your implementation of <code>{@link
-android.content.ContentProvider#getType ContentProvider.getType()}</code>.
-The type depends in part on whether or not the {@code content:} URI submitted
-to {@code getType()} limits the request to a specific record. There's one
-form of the MIME type for a single record and another for multiple records.
-Use the {@link android.net.Uri Uri} methods to help determine what is being
-requested. Here is the general format for each type:</p></li>
-
-<ul>
-<li><p>For a single record:&nbsp;&nbsp;&nbsp; {@code vnd.android.cursor.item/vnd.<em>yourcompanyname.contenttype</em>}</p>
-
-<p>For example, a request for train record 122, like this URI,</p>
-<p style="margin-left: 2em">{@code content://com.example.transportationprovider/trains/122}</p>
-
-<p>might return this MIME type:</p>
-<p style="margin-left: 2em">{@code vnd.android.cursor.item/vnd.example.rail}</p>
-</li>
-
-<li><p>For multiple records:&nbsp;&nbsp;&nbsp; {@code vnd.android.cursor.dir/vnd.<em>yourcompanyname.contenttype</em>}</p>
-
-<p>For example, a request for all train records, like the following URI,</p>
-<p style="margin-left: 2em">{@code content://com.example.transportationprovider/trains}</p>
-
-<p>might return this MIME type:</p>
-<p style="margin-left: 2em">{@code vnd.android.cursor.dir/vnd.example.rail}</p>
-</li>
-</ul>
-
-<li><p>If you are exposing byte data that's too big to put in the table itself
-&mdash; such as a large bitmap file &mdash; the field that exposes the
-data to clients should actually contain a {@code content:} URI string.
-This is the field that gives clients access to the data file. The record
-should also have another field, named "{@code _data}" that lists the exact file
-path on the device for that file. This field is not intended to be read by
-the client, but by the ContentResolver. The client will call <code>{@link
-android.content.ContentResolver#openInputStream ContentResolver.openInputStream()}</code>
-on the user-facing field holding the URI for the item. The ContentResolver
-will request the "{@code _data}" field for that record, and because
-it has higher permissions than a client, it should be able to access
-that file directly and return a read wrapper for the file to the client.</p></li>
-
-</ul>
-
-<p>
-For an example of a private content provider implementation, see the
-NodePadProvider class in the Notepad sample application that ships with the SDK.
-</p>
-
-
-<h3>Declaring the content provider</h3>
-
-<p>
-To let the Android system know about the content provider you've developed,
-declare it with a {@code &lt;provider&gt;} element in the application's
-AndroidManifest.xml file. Content providers that are not declared in the
-manifest are not visible to the Android system
-</p>
-
-<p>
-The {@code name} attribute is the fully qualified name of the ContentProvider
-subclass. The {@code authorities} attribute is the authority part of the
-{@code content:} URI that identifies the provider.
-For example if the ContentProvider subclass is AutoInfoProvider, the
-{@code &lt;provider&gt;} element might look like this:
-</p>
-
-<pre>
-&lt;provider android:name="com.example.autos.AutoInfoProvider"
- android:authorities="com.example.autos.autoinfoprovider"
- . . . /&gt
-&lt;/provider&gt;
-</pre>
-
-<p>
-Note that the {@code authorities} attribute omits the path part of a
-{@code content:} URI. For example, if AutoInfoProvider controlled subtables
-for different types of autos or different manufacturers,
-</p>
-
-<p style="margin-left: 2em">{@code content://com.example.autos.autoinfoprovider/honda}
-<br/>{@code content://com.example.autos.autoinfoprovider/gm/compact}
-<br/>{@code content://com.example.autos.autoinfoprovider/gm/suv}</p>
-
-<p>
-those paths would not be declared in the manifest. The authority is what
-identifies the provider, not the path; your provider can interpret the path
-part of the URI in any way you choose.
-</p>
-
-<p>
-Other {@code &lt;provider&gt;} attributes can set permissions to read and
-write data, provide for an icon and text that can be displayed to users,
-enable and disable the provider, and so on. Set the {@code multiprocess}
-attribute to "{@code true}" if data does not need to be synchronized between
-multiple running versions of the content provider. This permits an instance
-of the provider to be created in each client process, eliminating the need
-to perform IPC.
-</p>
-
-
-<h2><a name="urisum"></a>Content URI Summary</h2>
-
-<p>
-Here is a recap of the important parts of a content URI:
-</p>
-
-<p>
-<img src="{@docRoot}images/content_uri.png" alt="Elements of a content URI"
-height="80" width="528">
-</p>
-
-<ol type="A">
-<li>Standard prefix indicating that the data is controlled by a
-content provider. It's never modified.</li>
-
-<li><p>The authority part of the URI; it identifies the content provider.
-For third-party applications, this should be a fully-qualified class name
-(reduced to lowercase) to ensure uniqueness. The authority is declared in
-the {@code &lt;provider&gt;} element's {@code authorities} attribute:</p>
-
-<pre>&lt;provider android:name=".TransportationProvider"
- android:authorities="com.example.transportationprovider"
- . . . &gt;</pre></li>
-
-<li><p>The path that the content provider uses to determine what kind of data is
-being requested. This can be zero or more segments long. If the content provider
-exposes only one type of data (only trains, for example), it can be absent.
-If the provider exposes several types, including subtypes, it can be several
-segments long &mdash; for example, "{@code land/bus}", "{@code land/train}",
-"{@code sea/ship}", and "{@code sea/submarine}" to give four possibilities.</p></li>
-
-<li><p>The ID of the specific record being requested, if any. This is the
-{@code _ID} value of the requested record. If the request is not limited to
-a single record, this segment and the trailing slash are omitted:</p>
-
-<p style="margin-left: 2em">{@code content://com.example.transportationprovider/trains}</p>
-</li>
-</ol>
-
-
+ Content providers manage access to a structured set of data. They encapsulate the
+ data, and provide mechanisms for defining data security. Content providers are the standard
+ interface that connects data in one process with code running in another process.
+</p>
+<p>
+ When you want to access data in a content provider, you use the
+ {@link android.content.ContentResolver} object in your
+ application's {@link android.content.Context} to communicate with the provider as a client.
+ The {@link android.content.ContentResolver} object communicates with the provider object, an
+ instance of a class that implements {@link android.content.ContentProvider}. The provider
+ object receives data requests from clients, performs the requested action, and
+ returns the results.
+</p>
+<p>
+ You don't need to develop your own provider if you don't intend to share your data with
+ other applications. However, you do need your own provider to provide custom search
+ suggestions in your own application. You also need your own provider if you want to copy and
+ paste complex data or files from your application to other applications.
+</p>
+<p>
+ Android itself includes content providers that manage data such as audio, video, images, and
+ personal contact information. You can see some of them listed in the reference
+ documentation for the
+ <code><a href="{@docRoot}reference/android/provider/package-summary.html">android.provider</a>
+ </code> package. With some restrictions, these providers are accessible to any Android
+ application.
+</p><p>
+ The following topics describe content providers in more detail:
+</p>
+<dl>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Content Provider Basics</a></strong>
+ </dt>
+ <dd>
+ How to access data in a content provider when the data is organized in tables.
+ </dd>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ Creating a Content Provider</a></strong>
+ </dt>
+ <dd>
+ How to create your own content provider.
+ </dd>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/calendar-provider.html">
+ Calendar Provider</a></strong>
+ </dt>
+ <dd>
+ How to access the Calendar Provider that is part of the Android platform.
+ </dd>
+</dl>