Home | History | Annotate | Download | only in providers
      1 page.title=Content Provider Basics
      2 @jd:body
      3 <div id="qv-wrapper">
      4 <div id="qv">
      5 <!-- In this document -->
      6 <h2>In this document</h2>
      7 <ol>
      8     <li>
      9         <a href="#Basics">Overview</a>
     10         <ol>
     11             <li>
     12                 <a href="#ClientProvider">Accessing a provider</a>
     13             </li>
     14             <li>
     15                 <a href="#ContentURIs">Content URIs</a>
     16             </li>
     17         </ol>
     18     </li>
     19     <li>
     20         <a href="#SimpleQuery">Retrieving Data from the Provider</a>
     21         <ol>
     22             <li>
     23                 <a href="#RequestPermissions">Requesting read access permission</a>
     24             </li>
     25             <li>
     26                 <a href="#Query">Constructing the query</a>
     27             </li>
     28             <li>
     29                 <a href="#DisplayResults">Displaying query results</a>
     30             </li>
     31             <li>
     32                 <a href="#GettingResults">Getting data from query results</a>
     33             </li>
     34         </ol>
     35     </li>
     36     <li>
     37         <a href="#Permissions">Content Provider Permissions</a>
     38     </li>
     39     <li>
     40         <a href="#Modifications">Inserting, Updating, and Deleting Data</a>
     41         <ol>
     42             <li>
     43                 <a href="#Inserting">Inserting data</a>
     44             </li>
     45             <li>
     46                 <a href="#Updating">Updating data</a>
     47             </li>
     48             <li>
     49                 <a href="#Deleting">Deleting data</a>
     50             </li>
     51         </ol>
     52     </li>
     53     <li>
     54         <a href="#DataTypes">Provider Data Types</a>
     55     </li>
     56     <li>
     57         <a href="#AltForms">Alternative Forms of Provider Access</a>
     58         <ol>
     59             <li>
     60                 <a href="#Batch">Batch access</a>
     61             </li>
     62             <li>
     63                 <a href="#Intents">Data access via intents</a>
     64             </li>
     65         </ol>
     66     </li>
     67     <li>
     68         <a href="#ContractClasses">Contract Classes</a>
     69     </li>
     70     <li>
     71         <a href="#MIMETypeReference">MIME Type Reference</a>
     72     </li>
     73 </ol>
     74 
     75     <!-- Key Classes -->
     76 <h2>Key classes</h2>
     77     <ol>
     78         <li>
     79             {@link android.content.ContentProvider}
     80         </li>
     81         <li>
     82             {@link android.content.ContentResolver}
     83         </li>
     84         <li>
     85             {@link android.database.Cursor}
     86         </li>
     87         <li>
     88             {@link android.net.Uri}
     89         </li>
     90     </ol>
     91 
     92     <!-- Related Samples -->
     93 <h2>Related Samples</h2>
     94     <ol>
     95         <li>
     96         <a
     97         href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html">
     98         Cursor (People)</a>
     99         </li>
    100         <li>
    101         <a
    102         href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html">
    103         Cursor (Phones)</a>
    104         </li>
    105     </ol>
    106 
    107     <!-- See also -->
    108 <h2>See also</h2>
    109     <ol>
    110         <li>
    111             <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
    112             Creating a Content Provider</a>
    113         </li>
    114         <li>
    115             <a href="{@docRoot}guide/topics/providers/calendar-provider.html">
    116             Calendar Provider</a>
    117         </li>
    118     </ol>
    119 </div>
    120 </div>
    121 
    122     <!-- Intro paragraphs -->
    123 <p>
    124     A content provider manages access to a central repository of data. A provider
    125     is part of an Android application, which often provides its own UI for working with
    126     the data. However, content providers are primarily intended to be used by other
    127     applications, which access the provider using a provider client object. Together, providers
    128     and provider clients offer a consistent, standard interface to data that also handles
    129     inter-process communication and secure data access.
    130 </p>
    131 <p>
    132     This topic describes the basics of the following:
    133 </p>
    134     <ul>
    135         <li>How content providers work.</li>
    136         <li>The API you use retrieve data from a content provider.</li>
    137         <li>The API you use to insert, update, or delete data in a content provider.</li>
    138         <li>Other API features that facilitate working with providers.</li>
    139     </ul>
    140 
    141     <!-- Basics -->
    142 <h2 id="Basics">Overview</h2>
    143 <p>
    144     A content provider presents data to external applications as one or more tables that are
    145     similar to the tables found in a relational database. A row represents an instance of some type
    146     of data the provider collects, and each column in the row represents an individual piece of
    147     data collected for an instance.
    148 </p>
    149 <p>
    150     For example, one of the built-in providers in the Android platform is the user dictionary, which
    151     stores the spellings of non-standard words that the user wants to keep. Table 1 illustrates what
    152     the data might look like in this provider's table:
    153 </p>
    154 <p class="table-caption">
    155     <strong>Table 1:</strong> Sample user dictionary table.
    156 </p>
    157 <table id="table1" style="width: 50%;">
    158     <tr>
    159         <th style="width:20%" align="center" scope="col">word</th>
    160         <th style="width:20%" align="center" scope="col">app id</th>
    161         <th style="width:20%" align="center" scope="col">frequency</th>
    162         <th style="width:20%" align="center" scope="col">locale</th>
    163         <th style="width:20%" align="center" scope="col">_ID</th>
    164     </tr>
    165     <tr>
    166         <td align="center" scope="row">mapreduce</td>
    167         <td align="center">user1</td>
    168         <td align="center">100</td>
    169         <td align="center">en_US</td>
    170         <td align="center">1</td>
    171     </tr>
    172     <tr>
    173         <td align="center" scope="row">precompiler</td>
    174         <td align="center">user14</td>
    175         <td align="center">200</td>
    176         <td align="center">fr_FR</td>
    177         <td align="center">2</td>
    178     </tr>
    179     <tr>
    180         <td align="center" scope="row">applet</td>
    181         <td align="center">user2</td>
    182         <td align="center">225</td>
    183         <td align="center">fr_CA</td>
    184         <td align="center">3</td>
    185     </tr>
    186     <tr>
    187         <td align="center" scope="row">const</td>
    188         <td align="center">user1</td>
    189         <td align="center">255</td>
    190         <td align="center">pt_BR</td>
    191         <td align="center">4</td>
    192     </tr>
    193     <tr>
    194         <td align="center" scope="row">int</td>
    195         <td align="center">user5</td>
    196         <td align="center">100</td>
    197         <td align="center">en_UK</td>
    198         <td align="center">5</td>
    199     </tr>
    200 </table>
    201 <p>
    202     In table 1, each row represents an instance of a word that might not be
    203     found in a standard dictionary. Each column represents some data for that word, such as the
    204     locale in which it was first encountered. The column headers are column names that are stored in
    205     the provider. To refer to a row's locale, you refer to its <code>locale</code> column. For
    206     this provider, the <code>_ID</code> column serves as a "primary key" column that
    207     the provider automatically maintains.
    208 </p>
    209 <p class="note">
    210     <strong>Note:</strong> A provider isn't required to have a primary key, and it isn't required
    211     to use <code>_ID</code> as the column name of a primary key if one is present. However,
    212     if you want to bind data from a provider to a {@link android.widget.ListView}, one of the
    213     column names has to be <code>_ID</code>. This requirement is explained in more detail in the
    214     section <a href="#DisplayResults">Displaying query results</a>.
    215 </p>
    216 <h3 id="ClientProvider">Accessing a provider</h3>
    217 <p>
    218     An application accesses the data from a content provider with
    219     a {@link android.content.ContentResolver} client object. This object has methods that call
    220     identically-named methods in the provider object, an instance of one of the concrete
    221     subclasses of {@link android.content.ContentProvider}. The
    222     {@link android.content.ContentResolver} methods provide the basic
    223     "CRUD" (create, retrieve, update, and delete) functions of persistent storage.
    224 </p>
    225 <p>
    226     The {@link android.content.ContentResolver} object in the client application's
    227     process and the {@link android.content.ContentProvider} object in the application that owns
    228     the provider automatically handle inter-process communication.
    229     {@link android.content.ContentProvider} also acts as an abstraction layer between its
    230     repository of data and the external appearance of data as tables.
    231 </p>
    232 <p class="note">
    233     <strong>Note:</strong> To access a provider, your application usually has to request specific
    234     permissions in its manifest file. This is described in more detail in the section
    235     <a href="#Permissions">Content Provider Permissions</a>
    236 </p>
    237 <p>
    238     For example, to get a list of the words and their locales from the User Dictionary Provider,
    239     you call {@link android.content.ContentResolver#query ContentResolver.query()}.
    240     The {@link android.content.ContentResolver#query query()} method calls the
    241     {@link android.content.ContentProvider#query ContentProvider.query()} method defined by the 
    242     User Dictionary Provider. The following lines of code show a
    243     {@link android.content.ContentResolver#query ContentResolver.query()} call:
    244 <p>
    245 <pre>
    246 // Queries the user dictionary and returns results
    247 mCursor = getContentResolver().query(
    248     UserDictionary.Words.CONTENT_URI,   // The content URI of the words table
    249     mProjection,                        // The columns to return for each row
    250     mSelectionClause                    // Selection criteria
    251     mSelectionArgs,                     // Selection criteria
    252     mSortOrder);                        // The sort order for the returned rows
    253 </pre>
    254 <p>
    255     Table 2 shows how the arguments to
    256     {@link android.content.ContentResolver#query 
    257     query(Uri,projection,selection,selectionArgs,sortOrder)} match an SQL SELECT statement:
    258 </p>
    259 <p class="table-caption">
    260     <strong>Table 2:</strong> Query() compared to SQL query.
    261 </p>
    262 <table id="table2" style="width: 75%;">
    263     <tr>
    264         <th style="width:25%" align="center" scope="col">query() argument</th>
    265         <th style="width:25%" align="center" scope="col">SELECT keyword/parameter</th>
    266         <th style="width:50%" align="center" scope="col">Notes</th>
    267     </tr>
    268     <tr>
    269         <td align="center"><code>Uri</code></td>
    270         <td align="center"><code>FROM <em>table_name</em></code></td>
    271         <td><code>Uri</code> maps to the table in the provider named <em>table_name</em>.</td>
    272     </tr>
    273     <tr>
    274         <td align="center"><code>projection</code></td>
    275         <td align="center"><code><em>col,col,col,...</em></code></td>
    276         <td>
    277             <code>projection</code> is an array of columns that should be included for each row
    278             retrieved.
    279         </td>
    280     </tr>
    281     <tr>
    282         <td align="center"><code>selection</code></td>
    283         <td align="center"><code>WHERE <em>col</em> = <em>value</em></code></td>
    284         <td><code>selection</code> specifies the criteria for selecting rows.</td>
    285     </tr>
    286     <tr>
    287         <td align="center"><code>selectionArgs</code></td>
    288         <td align="center">
    289             (No exact equivalent. Selection arguments replace <code>?</code> placeholders in the
    290             selection clause.)
    291         </td>
    292     </tr>
    293     <tr>
    294         <td align="center"><code>sortOrder</code></td>
    295         <td align="center"><code>ORDER BY <em>col,col,...</em></code></td>
    296         <td>
    297             <code>sortOrder</code> specifies the order in which rows appear in the returned
    298             {@link android.database.Cursor}.
    299         </td>
    300     </tr>
    301 </table>
    302 <h3 id="ContentURIs">Content URIs</h3>
    303 <p>
    304     A <strong>content URI</strong> is a URI that identifies data in a provider. Content URIs
    305     include the symbolic name of the entire provider (its <strong>authority</strong>) and a
    306     name that points to a table (a <strong>path</strong>). When you call
    307     a client method to access a table in a provider, the content URI for the table is one of
    308     the arguments.
    309 </p>
    310 <p>
    311     In the preceding lines of code, the constant
    312     {@link android.provider.UserDictionary.Words#CONTENT_URI} contains the content URI of
    313     the user dictionary's "words" table. The {@link android.content.ContentResolver}
    314     object parses out the URI's authority, and uses it to "resolve" the provider by
    315     comparing the authority to a system table of known providers. The
    316     {@link android.content.ContentResolver} can then dispatch the query arguments to the correct
    317     provider.
    318 </p>
    319 <p>
    320     The {@link android.content.ContentProvider} uses the path part of the content URI to choose the
    321     table to access. A provider usually has a <strong>path</strong> for each table it exposes.
    322 </p>
    323 <p>
    324     In the previous lines of code, the full URI for the "words" table is:
    325 </p>
    326 <pre>
    327 content://user_dictionary/words
    328 </pre>
    329 <p>
    330     where the <code>user_dictionary</code> string is the provider's authority, and
    331     <code>words</code> string is the table's path. The string
    332     <code>content://</code> (the <strong>scheme</strong>) is always present,
    333     and identifies this as a content URI.
    334 </p>
    335 <p>
    336     Many providers allow you to access a single row in a table by appending an ID value
    337     to the end of the URI. For example, to retrieve a row whose <code>_ID</code> is
    338     <code>4</code> from user dictionary, you can use this content URI:
    339 </p>
    340 <pre>
    341 Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4);
    342 </pre>
    343 <p>
    344     You often use id values when you've retrieved a set of rows and then want to update or delete
    345     one of them.
    346 </p>
    347 <p class="note">
    348     <strong>Note:</strong> The {@link android.net.Uri} and {@link android.net.Uri.Builder} classes
    349     contain convenience methods for constructing well-formed Uri objects from strings. The
    350     {@link android.content.ContentUris} contains convenience methods for appending id values to
    351     a URI. The previous snippet uses {@link android.content.ContentUris#withAppendedId
    352     withAppendedId()} to append an id to the UserDictionary content URI.
    353 </p>
    354 
    355 
    356     <!-- Retrieving Data from the Provider -->
    357 <h2 id="SimpleQuery">Retrieving Data from the Provider</h2>
    358 <p>
    359     This section describes how to retrieve data from a provider, using the User Dictionary Provider
    360     as an example.
    361 </p>
    362 <p class="note">
    363     For the sake of clarity, the code snippets in this section call
    364     {@link android.content.ContentResolver#query ContentResolver.query()} on the "UI thread"". In 
    365     actual code, however, you should do queries asynchronously on a separate thread. One way to do 
    366     this is to use the {@link android.content.CursorLoader} class, which is described
    367     in more detail in the <a href="{@docRoot}guide/components/loaders.html">
    368     Loaders</a> guide. Also, the lines of code are snippets only; they don't show a complete
    369     application.
    370 </p>
    371 <p>
    372     To retrieve data from a provider, follow these basic steps:
    373 </p>
    374 <ol>
    375    <li>
    376         Request the read access permission for the provider.
    377    </li>
    378    <li>
    379         Define the code that sends a query to the provider.
    380    </li>
    381 </ol>
    382 <h3 id="RequestPermissions">Requesting read access permission</h3>
    383 <p>
    384     To retrieve data from a provider, your application needs "read access permission" for the
    385     provider. You can't request this permission at run-time; instead, you have to specify that
    386     you need this permission in your manifest, using the
    387 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
    388     element and the exact permission name defined by the
    389     provider. When you specify this element in your manifest, you are in effect "requesting" this
    390     permission for your application. When users install your application, they implicitly grant
    391     this request.
    392 </p>
    393 <p>
    394     To find the exact name of the read access permission for the provider you're using, as well
    395     as the names for other access permissions used by the provider, look in the provider's
    396     documentation.
    397 </p>
    398 <p>
    399     The role of permissions in accessing providers is described in more detail in the section
    400     <a href="#Permissions">Content Provider Permissions</a>.
    401 </p>
    402 <p>
    403     The User Dictionary Provider defines the permission
    404     <code>android.permission.READ_USER_DICTIONARY</code> in its manifest file, so an
    405     application that wants to read from the provider must request this permission.
    406 </p>
    407 <!-- Constructing the query -->
    408 <h3 id="Query">Constructing the query</h3>
    409 <p>
    410     The next step in retrieving data a provider is to construct a query. This first snippet
    411     defines some variables for accessing the User Dictionary Provider:
    412 </p>
    413 <pre class="prettyprint">
    414 
    415 // A "projection" defines the columns that will be returned for each row
    416 String[] mProjection =
    417 {
    418     UserDictionary.Words._ID,    // Contract class constant for the _ID column name
    419     UserDictionary.Words.WORD,   // Contract class constant for the word column name
    420     UserDictionary.Words.LOCALE  // Contract class constant for the locale column name
    421 };
    422 
    423 // Defines a string to contain the selection clause
    424 String mSelectionClause = null;
    425 
    426 // Initializes an array to contain selection arguments
    427 String[] mSelectionArgs = {""};
    428 
    429 </pre>
    430 <p>
    431     The next snippet shows how to use
    432     {@link android.content.ContentResolver#query ContentResolver.query()}, using the User Dictionary
    433     Provider as an example. A provider client query is similar to an SQL query, and it contains a 
    434     set of columns to return, a set of selection criteria, and a sort order.
    435 </p>
    436 <p>
    437     The set of columns that the query should return is called a <strong>projection</strong>
    438     (the variable <code>mProjection</code>).
    439 </p>
    440 <p>
    441     The expression that specifies the rows to retrieve is split into a selection clause and
    442     selection arguments. The selection clause is a combination of logical and Boolean expressions,
    443     column names, and values (the variable <code>mSelectionClause</code>). If you specify the 
    444     replaceable parameter <code>?</code> instead of a value, the query method retrieves the value 
    445     from the selection arguments array (the variable <code>mSelectionArgs</code>).
    446 </p>
    447 <p>
    448     In the next snippet, if the user doesn't enter a word, the selection clause is set to
    449     <code>null</code>, and the query returns all the words in the provider. If the user enters
    450     a word, the selection clause is set to <code>UserDictionary.Words.WORD + " = ?"</code> and
    451     the first element of selection arguments array is set to the word the user enters.
    452 </p>
    453 <pre class="prettyprint">
    454 /*
    455  * This defines a one-element String array to contain the selection argument.
    456  */
    457 String[] mSelectionArgs = {""};
    458 
    459 // Gets a word from the UI
    460 mSearchString = mSearchWord.getText().toString();
    461 
    462 // Remember to insert code here to check for invalid or malicious input.
    463 
    464 // If the word is the empty string, gets everything
    465 if (TextUtils.isEmpty(mSearchString)) {
    466     // Setting the selection clause to null will return all words
    467     mSelectionClause = null;
    468     mSelectionArgs[0] = "";
    469 
    470 } else {
    471     // Constructs a selection clause that matches the word that the user entered.
    472     mSelectionClause = UserDictionary.Words.WORD + " = ?";
    473 
    474     // Moves the user's input string to the selection arguments.
    475     mSelectionArgs[0] = mSearchString;
    476 
    477 }
    478 
    479 // Does a query against the table and returns a Cursor object
    480 mCursor = getContentResolver().query(
    481     UserDictionary.Words.CONTENT_URI,  // The content URI of the words table
    482     mProjection,                       // The columns to return for each row
    483     mSelectionClause                   // Either null, or the word the user entered
    484     mSelectionArgs,                    // Either empty, or the string the user entered
    485     mSortOrder);                       // The sort order for the returned rows
    486 
    487 // Some providers return null if an error occurs, others throw an exception
    488 if (null == mCursor) {
    489     /*
    490      * Insert code here to handle the error. Be sure not to use the cursor! You may want to
    491      * call android.util.Log.e() to log this error.
    492      *
    493      */
    494 // If the Cursor is empty, the provider found no matches
    495 } else if (mCursor.getCount() &lt; 1) {
    496 
    497     /*
    498      * Insert code here to notify the user that the search was unsuccessful. This isn't necessarily
    499      * an error. You may want to offer the user the option to insert a new row, or re-type the
    500      * search term.
    501      */
    502 
    503 } else {
    504     // Insert code here to do something with the results
    505 
    506 }
    507 </pre>
    508 <p>
    509     This query is analogous to the SQL statement:
    510 </p>
    511 <pre>
    512 SELECT _ID, word, locale FROM words WHERE word = &lt;userinput&gt; ORDER BY word ASC;
    513 </pre>
    514 <p>
    515     In this SQL statement, the actual column names are used instead of contract class constants.
    516 </p>
    517 <h4 id="Injection">Protecting against malicious input</h4>
    518 <p>
    519     If the data managed by the content provider is in an SQL database, including external untrusted
    520     data into raw SQL statements can lead to SQL injection.
    521 </p>
    522 <p>
    523     Consider this selection clause:
    524 </p>
    525 <pre>
    526 // Constructs a selection clause by concatenating the user's input to the column name
    527 String mSelectionClause =  "var = " + mUserInput;
    528 </pre>
    529 <p>
    530     If you do this, you're allowing the user to concatenate malicious SQL onto your SQL statement.
    531     For example, the user could enter "nothing; DROP TABLE *;"  for <code>mUserInput</code>, which
    532     would result in the selection clause <code>var = nothing; DROP TABLE *;</code>. Since the
    533     selection clause is treated as an SQL statement, this might cause the provider to erase all of
    534     the tables in the underlying SQLite database (unless the provider is set up to catch
    535     <a href="http://en.wikipedia.org/wiki/SQL_injection">SQL injection</a> attempts).
    536 </p>
    537 <p>
    538     To avoid this problem, use a selection clause that uses <code>?</code> as a replaceable
    539     parameter and a separate array of selection arguments. When you do this, the user input
    540     is bound directly to the query rather than being interpreted as part of an SQL statement.
    541     Because it's not treated as SQL, the user input can't inject malicious SQL. Instead of using
    542     concatenation to include the user input, use this selection clause:
    543 </p>
    544 <pre>
    545 // Constructs a selection clause with a replaceable parameter
    546 String mSelectionClause =  "var = ?";
    547 </pre>
    548 <p>
    549     Set up the array of selection arguments like this:
    550 </p>
    551 <pre>
    552 // Defines an array to contain the selection arguments
    553 String[] selectionArgs = {""};
    554 </pre>
    555 <p>
    556     Put a value in the selection arguments array like this:
    557 </p>
    558 <pre>
    559 // Sets the selection argument to the user's input
    560 selectionArgs[0] = mUserInput;
    561 </pre>
    562 <p>
    563     A selection clause that uses <code>?</code> as a replaceable parameter and an array of
    564     selection arguments array are preferred way to specify a selection, even if the provider isn't
    565     based on an SQL database.
    566 </p>
    567 <!-- Displaying the results -->
    568 <h3 id="DisplayResults">Displaying query results</h3>
    569 <p>
    570     The {@link android.content.ContentResolver#query ContentResolver.query()} client method always 
    571     returns a {@link android.database.Cursor} containing the columns specified by the query's 
    572     projection for the rows that match the query's selection criteria. A 
    573     {@link android.database.Cursor} object provides random read access to the rows and columns it 
    574     contains. Using {@link android.database.Cursor} methods, you can iterate over the rows in the 
    575     results, determine the data type of each column, get the data out of a column, and examine other
    576     properties of the results. Some {@link android.database.Cursor} implementations automatically 
    577     update the object when the provider's data changes, or trigger methods in an observer object 
    578     when the {@link android.database.Cursor} changes, or both.
    579 </p>
    580 <p class="note">
    581     <strong>Note:</strong> A provider may restrict access to columns based on the nature of the
    582     object making the query. For example, the Contacts Provider restricts access for some columns to
    583     sync adapters, so it won't return them to an activity or service.
    584 </p>
    585 <p>
    586     If no rows match the selection criteria, the provider
    587     returns a {@link android.database.Cursor} object for which
    588     {@link android.database.Cursor#getCount Cursor.getCount()} is 0 (an empty cursor).
    589 </p>
    590 <p>
    591     If an internal error occurs, the results of the query depend on the particular provider. It may
    592     choose to return <code>null</code>, or it may throw an {@link java.lang.Exception}.
    593 </p>
    594 <p>
    595     Since a {@link android.database.Cursor} is a "list" of rows, a good way to display the
    596     contents of a {@link android.database.Cursor} is to link it to a {@link android.widget.ListView}
    597     via a {@link android.widget.SimpleCursorAdapter}.
    598 </p>
    599 <p>
    600     The following snippet continues the code from the previous snippet. It creates a
    601     {@link android.widget.SimpleCursorAdapter} object containing the {@link android.database.Cursor}
    602     retrieved by the query, and sets this object to be the adapter for a
    603     {@link android.widget.ListView}:
    604 </p>
    605 <pre class="prettyprint">
    606 // Defines a list of columns to retrieve from the Cursor and load into an output row
    607 String[] mWordListColumns =
    608 {
    609     UserDictionary.Words.WORD,   // Contract class constant containing the word column name
    610     UserDictionary.Words.LOCALE  // Contract class constant containing the locale column name
    611 };
    612 
    613 // Defines a list of View IDs that will receive the Cursor columns for each row
    614 int[] mWordListItems = { R.id.dictWord, R.id.locale};
    615 
    616 // Creates a new SimpleCursorAdapter
    617 mCursorAdapter = new SimpleCursorAdapter(
    618     getApplicationContext(),               // The application's Context object
    619     R.layout.wordlistrow,                  // A layout in XML for one row in the ListView
    620     mCursor,                               // The result from the query
    621     mWordListColumns,                      // A string array of column names in the cursor
    622     mWordListItems,                        // An integer array of view IDs in the row layout
    623     0);                                    // Flags (usually none are needed)
    624 
    625 // Sets the adapter for the ListView
    626 mWordList.setAdapter(mCursorAdapter);
    627 </pre>
    628 <p class="note">
    629     <strong>Note:</strong> To back a {@link android.widget.ListView} with a
    630     {@link android.database.Cursor}, the cursor must contain a column named <code>_ID</code>.
    631     Because of this, the query shown previously retrieves the <code>_ID</code> column for the
    632     "words" table, even though the {@link android.widget.ListView} doesn't display it.
    633     This restriction also explains why most providers have a <code>_ID</code> column for each of
    634     their tables.
    635 </p>
    636 
    637         <!-- Getting data from query results -->
    638 <h3 id="GettingResults">Getting data from query results</h3>
    639 <p>
    640     Rather than simply displaying query results, you can use them for other tasks. For
    641     example, you can retrieve spellings from the user dictionary and then look them up in
    642     other providers. To do this, you iterate over the rows in the {@link android.database.Cursor}:
    643 </p>
    644 <pre class="prettyprint">
    645 
    646 // Determine the column index of the column named "word"
    647 int index = mCursor.getColumnIndex(UserDictionary.Words.WORD);
    648 
    649 /*
    650  * Only executes if the cursor is valid. The User Dictionary Provider returns null if
    651  * an internal error occurs. Other providers may throw an Exception instead of returning null.
    652  */
    653 
    654 if (mCursor != null) {
    655     /*
    656      * Moves to the next row in the cursor. Before the first movement in the cursor, the
    657      * "row pointer" is -1, and if you try to retrieve data at that position you will get an
    658      * exception.
    659      */
    660     while (mCursor.moveToNext()) {
    661 
    662         // Gets the value from the column.
    663         newWord = mCursor.getString(index);
    664 
    665         // Insert code here to process the retrieved word.
    666 
    667         ...
    668 
    669         // end of while loop
    670     }
    671 } else {
    672 
    673     // Insert code here to report an error if the cursor is null or the provider threw an exception.
    674 }
    675 </pre>
    676 <p>
    677     {@link android.database.Cursor} implementations contain several "get" methods for
    678     retrieving different types of data from the object. For example, the previous snippet
    679     uses {@link android.database.Cursor#getString getString()}. They also have a
    680     {@link android.database.Cursor#getType getType()} method that returns a value indicating
    681     the data type of the column.
    682 </p>
    683 
    684 
    685     <!-- Requesting permissions -->
    686 <h2 id="Permissions">Content Provider Permissions</h2>
    687 <p>
    688     A provider's application can specify permissions that other applications must have in order to
    689     access the provider's data. These permissions ensure that the user knows what data
    690     an application will try to access. Based on the provider's requirements, other applications
    691     request the permissions they need in order to access the provider. End users see the requested
    692     permissions when they install the application.
    693 </p>
    694 <p>
    695     If a provider's application doesn't specify any permissions, then other applications have no
    696     access to the provider's data. However, components in the provider's application always have
    697     full read and write access, regardless of the specified permissions.
    698 </p>
    699 <p>
    700     As noted previously, the User Dictionary Provider requires the
    701     <code>android.permission.READ_USER_DICTIONARY</code> permission to retrieve data from it.
    702     The provider has the separate <code>android.permission.WRITE_USER_DICTIONARY</code>
    703     permission for inserting, updating, or deleting data.
    704 </p>
    705 <p>
    706     To get the permissions needed to access a provider, an application requests them with a
    707 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
    708     element in its manifest file. When the Android Package Manager installs the application, a user 
    709     must approve all of the permissions the application requests. If the user approves all of them, 
    710     Package Manager continues the installation; if the user doesn't approve them, Package Manager
    711     aborts the installation.
    712 </p>
    713 <p>
    714     The following
    715 <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code> 
    716     element requests read access to the User Dictionary Provider:
    717 </p>
    718 <pre>
    719     &lt;uses-permission android:name="android.permission.READ_USER_DICTIONARY"&gt;
    720 </pre>
    721 <p>
    722     The impact of permissions on provider access is explained in more detail in the
    723     <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> guide.
    724 </p>
    725 
    726 
    727 <!-- Inserting, Updating, and Deleting Data -->
    728 <h2 id="Modifications">Inserting, Updating, and Deleting Data</h2>
    729 <p>
    730     In the same way that you retrieve data from a provider, you also use the interaction between
    731     a provider client and the provider's {@link android.content.ContentProvider} to modify data.
    732     You call a method of {@link android.content.ContentResolver} with arguments that are passed to
    733     the corresponding method of {@link android.content.ContentProvider}. The provider and provider
    734     client automatically handle security and inter-process communication.
    735 </p>
    736 <h3 id="Inserting">Inserting data</h3>
    737 <p>
    738     To insert data into a provider, you call the
    739     {@link android.content.ContentResolver#insert ContentResolver.insert()}
    740     method. This method inserts a new row into the provider and returns a content URI for that row.
    741     This snippet shows how to insert a new word into the User Dictionary Provider:
    742 </p>
    743 <pre class="prettyprint">
    744 // Defines a new Uri object that receives the result of the insertion
    745 Uri mNewUri;
    746 
    747 ...
    748 
    749 // Defines an object to contain the new values to insert
    750 ContentValues mNewValues = new ContentValues();
    751 
    752 /*
    753  * Sets the values of each column and inserts the word. The arguments to the "put"
    754  * method are "column name" and "value"
    755  */
    756 mNewValues.put(UserDictionary.Words.APP_ID, "example.user");
    757 mNewValues.put(UserDictionary.Words.LOCALE, "en_US");
    758 mNewValues.put(UserDictionary.Words.WORD, "insert");
    759 mNewValues.put(UserDictionary.Words.FREQUENCY, "100");
    760 
    761 mNewUri = getContentResolver().insert(
    762     UserDictionary.Word.CONTENT_URI,   // the user dictionary content URI
    763     mNewValues                          // the values to insert
    764 );
    765 </pre>
    766 <p>
    767     The data for the new row goes into a single {@link android.content.ContentValues} object, which
    768     is similar in form to a one-row cursor. The columns in this object don't need to have the
    769     same data type, and if you don't want to specify a value at all, you can set a column
    770     to <code>null</code> using {@link android.content.ContentValues#putNull ContentValues.putNull()}.
    771 </p>
    772 <p>
    773     The snippet doesn't add the <code>_ID</code> column, because this column is maintained
    774     automatically. The provider assigns a unique value of <code>_ID</code> to every row that is
    775     added. Providers usually use this value as the table's primary key.
    776 </p>
    777 <p>
    778     The content URI returned in <code>newUri</code> identifies the newly-added row, with
    779     the following format:
    780 </p>
    781 <pre>
    782 content://user_dictionary/words/&lt;id_value&gt;
    783 </pre>
    784 <p>
    785     The <code>&lt;id_value&gt;</code> is the contents of <code>_ID</code> for the new row.
    786     Most providers can detect this form of content URI automatically and then perform the requested
    787     operation on that particular row.
    788 </p>
    789 <p>
    790     To get the value of <code>_ID</code> from the returned {@link android.net.Uri}, call
    791     {@link android.content.ContentUris#parseId ContentUris.parseId()}.
    792 </p>
    793 <h3 id="Updating">Updating data</h3>
    794 <p>
    795     To update a row, you use a {@link android.content.ContentValues} object with the updated
    796     values just as you do with an insertion, and selection criteria just as you do with a query.
    797     The client method you use is
    798     {@link android.content.ContentResolver#update ContentResolver.update()}. You only need to add 
    799     values to the {@link android.content.ContentValues} object for columns you're updating. If you 
    800     want to clear the contents of a column, set the value to <code>null</code>.
    801 </p>
    802 <p>
    803     The following snippet changes all the rows whose locale has the language "en" to a
    804     have a locale of <code>null</code>. The return value is the number of rows that were updated:
    805 </p>
    806 <pre>
    807 // Defines an object to contain the updated values
    808 ContentValues mUpdateValues = new ContentValues();
    809 
    810 // Defines selection criteria for the rows you want to update
    811 String mSelectionClause = UserDictionary.Words.LOCALE +  "LIKE ?";
    812 String[] mSelectionArgs = {"en_%"};
    813 
    814 // Defines a variable to contain the number of updated rows
    815 int mRowsUpdated = 0;
    816 
    817 ...
    818 
    819 /*
    820  * Sets the updated value and updates the selected words.
    821  */
    822 mUpdateValues.putNull(UserDictionary.Words.LOCALE);
    823 
    824 mRowsUpdated = getContentResolver().update(
    825     UserDictionary.Words.CONTENT_URI,   // the user dictionary content URI
    826     mUpdateValues                       // the columns to update
    827     mSelectionClause                    // the column to select on
    828     mSelectionArgs                      // the value to compare to
    829 );
    830 </pre>
    831 <p>
    832     You should also sanitize user input when you call
    833     {@link android.content.ContentResolver#update ContentResolver.update()}. To learn more about 
    834     this, read the section <a href="#Injection">Protecting against malicious input</a>.
    835 </p>
    836 <h3 id="Deleting">Deleting data</h3>
    837 <p>
    838     Deleting rows is similar to retrieving row data: you specify selection criteria for the rows
    839     you want to delete and the client method returns the number of deleted rows.
    840     The following snippet deletes rows whose appid matches "user". The method returns the
    841     number of deleted rows.
    842 </p>
    843 <pre>
    844 
    845 // Defines selection criteria for the rows you want to delete
    846 String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?";
    847 String[] mSelectionArgs = {"user"};
    848 
    849 // Defines a variable to contain the number of rows deleted
    850 int mRowsDeleted = 0;
    851 
    852 ...
    853 
    854 // Deletes the words that match the selection criteria
    855 mRowsDeleted = getContentResolver().delete(
    856     UserDictionary.Words.CONTENT_URI,   // the user dictionary content URI
    857     mSelectionClause                    // the column to select on
    858     mSelectionArgs                      // the value to compare to
    859 );
    860 </pre>
    861 <p>
    862     You should also sanitize user input when you call
    863     {@link android.content.ContentResolver#delete ContentResolver.delete()}. To learn more about 
    864     this, read the section <a href="#Injection">Protecting against malicious input</a>.
    865 </p>
    866 <!-- Provider Data Types -->
    867 <h2 id="DataTypes">Provider Data Types</h2>
    868 <p>
    869     Content providers can offer many different data types. The User Dictionary Provider offers only
    870     text, but providers can also offer the following formats:
    871 </p>
    872     <ul>
    873         <li>
    874             integer
    875         </li>
    876         <li>
    877             long integer (long)
    878         </li>
    879         <li>
    880             floating point
    881         </li>
    882         <li>
    883             long floating point (double)
    884         </li>
    885     </ul>
    886 <p>
    887     Another data type that providers often use is Binary Large OBject (BLOB) implemented as a
    888     64KB byte array. You can see the available data types by looking at the
    889     {@link android.database.Cursor} class "get" methods.
    890 </p>
    891 <p>
    892     The data type for each column in a provider is usually listed in its documentation.
    893     The data types for the User Dictionary Provider are listed in the reference documentation
    894     for its contract class {@link android.provider.UserDictionary.Words} (contract classes are
    895     described in the section <a href="#ContractClasses">Contract Classes</a>).
    896     You can also determine the data type by calling {@link android.database.Cursor#getType
    897     Cursor.getType()}.
    898 </p>
    899 <p>
    900     Providers also maintain MIME data type information for each content URI they define. You can
    901     use the MIME type information to find out if your application can handle data that the
    902     provider offers, or to choose a type of handling based on the MIME type. You usually need the
    903     MIME type when you are working with a provider that contains complex
    904     data structures or files. For example, the {@link android.provider.ContactsContract.Data}
    905     table in the Contacts Provider uses MIME types to label the type of contact data stored in each
    906     row. To get the MIME type corresponding to a content URI, call
    907     {@link android.content.ContentResolver#getType ContentResolver.getType()}.
    908 </p>
    909 <p>
    910     The section <a href="#MIMETypeReference">MIME Type Reference</a> describes the
    911     syntax of both standard and custom MIME types.
    912 </p>
    913 
    914 
    915 <!-- Alternative Forms of Provider Access -->
    916 <h2 id="AltForms">Alternative Forms of Provider Access</h2>
    917 <p>
    918     Three alternative forms of provider access are important in application development:
    919 </p>
    920 <ul>
    921     <li>
    922         <a href="#Batch">Batch access</a>: You can create a batch of access calls with methods in
    923         the {@link android.content.ContentProviderOperation} class, and then apply them with
    924         {@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()}.
    925     </li>
    926     <li>
    927         Asynchronous queries: You should do queries in a separate thread. One way to do this is to
    928         use a {@link android.content.CursorLoader} object. The examples in the
    929         <a href="{@docRoot}guide/components/loaders.html">Loaders</a> guide demonstrate
    930         how to do this.
    931     </li>
    932     <li>
    933         <a href="#Intents">Data access via intents</a>: Although you can't send an intent
    934         directly to a provider, you can send an intent to the provider's application, which is
    935         usually the best-equipped to modify the provider's data.
    936     </li>
    937 </ul>
    938 <p>
    939     Batch access and modification via intents are described in the following sections.
    940 </p>
    941 <h3 id="Batch">Batch access</h3>
    942 <p>
    943     Batch access to a provider is useful for inserting a large number of rows, or for inserting
    944     rows in multiple tables in the same method call, or in general for performing a set of
    945     operations across process boundaries as a transaction (an atomic operation).
    946 </p>
    947 <p>
    948     To access a provider in "batch mode",
    949     you create an array of {@link android.content.ContentProviderOperation} objects and then
    950     dispatch them to a content provider with
    951     {@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()}. You pass the 
    952     content provider's <em>authority</em> to this  method, rather than a particular content URI. 
    953     This allows each {@link android.content.ContentProviderOperation} object in the array to work 
    954     against a different table. A call to {@link android.content.ContentResolver#applyBatch
    955     ContentResolver.applyBatch()} returns an array of results.
    956 </p>
    957 <p>
    958     The description of the {@link android.provider.ContactsContract.RawContacts} contract class
    959     includes a code snippet that demonstrates batch insertion. The
    960     <a href="{@docRoot}resources/samples/ContactManager/index.html">Contact Manager</a>
    961     sample application contains an example of batch access in its <code>ContactAdder.java</code>
    962     source file.
    963 </p>
    964 <div class="sidebox-wrapper">
    965 <div class="sidebox">
    966 <h2>Displaying data using a helper app</h2>
    967 <p>
    968     If your application <em>does</em> have access permissions, you still may want to use an
    969     intent to display data in another application. For example, the Calendar application accepts an
    970     {@link android.content.Intent#ACTION_VIEW} intent, which displays a particular date or event.
    971     This allows you to display calendar information without having to create your own UI.
    972     To learn more about this feature, see the
    973     <a href="{@docRoot}guide/topics/providers/calendar-provider.html">Calendar Provider</a> guide.
    974 </p>
    975 <p>
    976     The application to which you send the intent doesn't have to be the application
    977     associated with the provider. For example, you can retrieve a contact from the
    978     Contact Provider, then send an {@link android.content.Intent#ACTION_VIEW} intent
    979     containing the content URI for the contact's image to an image viewer.
    980 </p>
    981 </div>
    982 </div>
    983 <h3 id="Intents">Data access via intents</h3>
    984 <p>
    985     Intents can provide indirect access to a content provider. You allow the user to access
    986     data in a provider even if your application doesn't have access permissions, either by
    987     getting a result intent back from an application that has permissions, or by activating an
    988     application that has permissions and letting the user do work in it.
    989 </p>
    990 <h4>Getting access with temporary permissions</h4>
    991 <p>
    992     You can access data in a content provider, even if you don't have the proper access
    993     permissions, by sending an intent to an application that does have the permissions and
    994     receiving back a result intent containing "URI" permissions.
    995     These are permissions for a specific content URI that last until the activity that receives
    996     them is finished. The application that has permanent permissions grants temporary
    997     permissions by setting a flag in the result intent:
    998 </p>
    999 <ul>
   1000     <li>
   1001         <strong>Read permission:</strong>
   1002         {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}
   1003     </li>
   1004     <li>
   1005         <strong>Write permission:</strong>
   1006         {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}
   1007     </li>
   1008 </ul>
   1009 <p class="note">
   1010     <strong>Note:</strong> These flags don't give general read or write access to the provider
   1011     whose authority is contained in the content URI. The access is only for the URI itself.
   1012 </p>
   1013 <p>
   1014     A provider defines URI permissions for content URIs in its manifest, using the
   1015 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">android:grantUriPermission</a></code>
   1016     attribute of the 
   1017 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
   1018     element, as well as the
   1019 <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code>
   1020     child element of the
   1021 <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
   1022     element. The URI permissions mechanism is explained in more detail in the
   1023     <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a> guide,
   1024     in the section "URI Permissions".
   1025 </p>
   1026 <p>
   1027     For example, you can retrieve data for a contact in the Contacts Provider, even if you don't
   1028     have the {@link android.Manifest.permission#READ_CONTACTS} permission. You might want to do
   1029     this in an application that sends e-greetings to a contact on his or her birthday. Instead of
   1030     requesting {@link android.Manifest.permission#READ_CONTACTS}, which gives you access to all of
   1031     the user's contacts and all of their information, you prefer to let the user control which
   1032     contacts are used by your application. To do this, you use the following process:
   1033 </p>
   1034 <ol>
   1035     <li>
   1036         Your application sends an intent containing the action
   1037         {@link android.content.Intent#ACTION_PICK} and the "contacts" MIME type
   1038         {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE}, using the
   1039         method {@link android.app.Activity#startActivityForResult
   1040         startActivityForResult()}.
   1041     </li>
   1042     <li>
   1043         Because this intent matches the intent filter for the
   1044         People app's "selection" activity, the activity will come to the foreground.
   1045     </li>
   1046     <li>
   1047         In the selection activity, the user selects a
   1048         contact to update. When this happens, the selection activity calls
   1049         {@link android.app.Activity#setResult setResult(resultcode, intent)}
   1050         to set up a intent to give back to your application. The intent contains the content URI
   1051         of the contact the user selected, and the "extras" flags
   1052         {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}. These flags grant URI
   1053         permission to your app to read data for the contact pointed to by the
   1054         content URI. The selection activity then calls {@link android.app.Activity#finish()} to
   1055         return control to your application.
   1056     </li>
   1057     <li>
   1058         Your activity returns to the foreground, and the system calls your activity's
   1059         {@link android.app.Activity#onActivityResult onActivityResult()}
   1060         method. This method receives the result intent created by the selection activity in
   1061         the People app.
   1062     </li>
   1063     <li>
   1064         With the content URI from the result intent, you can read the contact's data
   1065         from the Contacts Provider, even though you didn't request permanent read access permission
   1066         to the provider in your manifest. You can then get the contact's birthday information
   1067         or his or her email address and then send the e-greeting.
   1068     </li>
   1069 </ol>
   1070 <h4>Using another application</h4>
   1071 <p>
   1072     A simple way to allow the user to modify data to which you don't have access permissions is to
   1073     activate an application that has permissions and let the user do the work there.
   1074 </p>
   1075 <p>
   1076     For example, the Calendar application accepts an
   1077     {@link android.content.Intent#ACTION_INSERT} intent, which allows you to activate the
   1078     application's insert UI. You can pass "extras" data in this intent, which the application
   1079     uses to pre-populate the UI. Because recurring events have a complex syntax, the preferred
   1080     way of inserting events into the Calendar Provider is to activate the Calendar app with an
   1081     {@link android.content.Intent#ACTION_INSERT} and then let the user insert the event there.
   1082 </p>
   1083 <!-- Contract Classes -->
   1084 <h2 id="ContractClasses">Contract Classes</h2>
   1085 <p>
   1086     A contract class defines constants that help applications work with the content URIs, column
   1087     names, intent actions, and other features of a content provider. Contract classes are not
   1088     included automatically with a provider; the provider's developer has to define them and then
   1089     make them available to other developers. Many of the providers included with the Android
   1090     platform have corresponding contract classes in the package {@link android.provider}.
   1091 </p>
   1092 <p>
   1093     For example, the User Dictionary Provider has a contract class
   1094     {@link android.provider.UserDictionary} containing content URI and column name constants. The
   1095     content URI for the "words" table is defined in the constant
   1096     {@link android.provider.UserDictionary.Words#CONTENT_URI UserDictionary.Words.CONTENT_URI}.
   1097     The {@link android.provider.UserDictionary.Words} class also contains column name constants,
   1098     which are used in the example snippets in this guide. For example, a query projection can be
   1099     defined as:
   1100 </p>
   1101 <pre>
   1102 String[] mProjection =
   1103 {
   1104     UserDictionary.Words._ID,
   1105     UserDictionary.Words.WORD,
   1106     UserDictionary.Words.LOCALE
   1107 };
   1108 </pre>
   1109 <p>
   1110     Another contract class is {@link android.provider.ContactsContract} for the Contacts Provider.
   1111     The reference documentation for this class includes example code snippets. One of its
   1112     subclasses, {@link android.provider.ContactsContract.Intents.Insert}, is a contract
   1113     class that contains constants for intents and intent data.
   1114 </p>
   1115 
   1116 
   1117 <!-- MIME Type Reference -->
   1118 <h2 id="MIMETypeReference">MIME Type Reference</h2>
   1119 <p>
   1120     Content providers can return standard MIME media types, or custom MIME type strings, or both.
   1121 </p>
   1122 <p>
   1123     MIME types have the format
   1124 </p>
   1125 <pre>
   1126 <em>type</em>/<em>subtype</em>
   1127 </pre>
   1128 <p>
   1129     For example, the well-known MIME type <code>text/html</code> has the <code>text</code> type and
   1130     the <code>html</code> subtype. If the provider returns this type for a URI, it means that a
   1131     query using that URI will return text containing HTML tags.
   1132 </p>
   1133 <p>
   1134     Custom MIME type strings, also called "vendor-specific" MIME types, have more
   1135     complex <em>type</em> and <em>subtype</em> values. The <em>type</em> value is always
   1136 </p>
   1137 <pre>
   1138 vnd.android.cursor.<strong>dir</strong>
   1139 </pre>
   1140 <p>
   1141     for multiple rows, or
   1142 </p>
   1143 <pre>
   1144 vnd.android.cursor.<strong>item</strong>
   1145 </pre>
   1146 <p>
   1147     for a single row.
   1148 </p>
   1149 <p>
   1150     The <em>subtype</em> is provider-specific. The Android built-in providers usually have a simple
   1151     subtype. For example, the when the Contacts application creates a row for a telephone number,
   1152     it sets the following MIME type in the row:
   1153 </p>
   1154 <pre>
   1155 vnd.android.cursor.item/phone_v2
   1156 </pre>
   1157 <p>
   1158     Notice that the subtype value is simply <code>phone_v2</code>.
   1159 </p>
   1160 <p>
   1161     Other provider developers may create their own pattern of subtypes based on the provider's
   1162     authority and table names. For example, consider a provider that contains train timetables.
   1163     The provider's authority is <code>com.example.trains</code>, and it contains the tables
   1164     Line1, Line2, and Line3. In response to the content URI
   1165 </p>
   1166 <p>
   1167 <pre>
   1168 content://com.example.trains/Line1
   1169 </pre>
   1170 <p>
   1171     for table Line1, the provider returns the MIME type
   1172 </p>
   1173 <pre>
   1174 vnd.android.cursor.<strong>dir</strong>/vnd.example.line1
   1175 </pre>
   1176 <p>
   1177      In response to the content URI
   1178 </p>
   1179 <pre>
   1180 content://com.example.trains/Line2/5
   1181 </pre>
   1182 <p>
   1183     for row 5 in table Line2, the provider returns the MIME type
   1184 </p>
   1185 <pre>
   1186 vnd.android.cursor.<strong>item</strong>/vnd.example.line2
   1187 </pre>
   1188 <p>
   1189     Most content providers define contract class constants for the MIME types they use. The
   1190     Contacts Provider contract class {@link android.provider.ContactsContract.RawContacts},
   1191     for example, defines the constant
   1192     {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE} for the MIME type of
   1193     a single raw contact row.
   1194 </p>
   1195 <p>
   1196     Content URIs for single rows are described in the section
   1197     <a href="#ContentURIs">Content URIs</a>.
   1198 </p>
   1199