• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Content Providers
2@jd:body
3
4<div id="qv-wrapper">
5<div id="qv">
6
7<h2>In this document</h2>
8<ol>
9<li><a href="#basics">Content provider basics</a></li>
10<li><a href="#querying">Querying a content provider</a></li>
11<li><a href="#modifying">Modifying data in a provider</a></li>
12<li><a href="#creating">Creating a content provider</a></li>
13<li><a href="#urisum">Content URI summary</a></li>
14</ol>
15
16<h2>Key classes</h2>
17<ol>
18<li>{@link android.content.ContentProvider}</li>
19<li>{@link android.content.ContentResolver}</li>
20<li>{@link android.database.Cursor}</li>
21</ol>
22</div>
23</div>
24
25<p>
26Content providers store and retrieve data and make it accessible to all
27applications.  They're the only way to share data across applications; there's
28no common storage area that all Android packages can access.
29</p>
30
31<p>
32Android ships with a number of content providers for common data types
33(audio, video, images, personal contact information, and so on).  You can
34see some of them listed in the {@link android.provider android.provider}
35package.  You can query these providers for the data they contain (although,
36for some, you must acquire the proper permission to read the data).
37</p>
38
39<p>
40If you want to make your own data public, you have two options:  You can
41create your own content provider (a {@link android.content.ContentProvider}
42subclass) or you can add the data to an existing provider &mdash; if there's
43one that controls the same type of data and you have permission to write to it.
44</p>
45
46<p>
47This document is an introduction to using content providers.  After a
48brief discussion of the fundamentals, it explores how to query a content
49provider, how to modify data controlled by a provider, and how to create
50a content provider of your own.
51</p>
52
53
54<h2><a name="basics"></a>Content Provider Basics</h2>
55
56<p>
57How a content provider actually stores its data under the covers is
58up to its designer.  But all content providers implement a common interface
59for querying the provider and returning results &mdash; as well as for
60adding, altering, and deleting data.
61</p>
62
63<p>
64It's an interface that clients use indirectly, most generally through
65{@link android.content.ContentResolver} objects.  You get a ContentResolver
66by calling <code>{@link android.content.Context#getContentResolver
67getContentResolver()}</code> from within the implementation of an Activity
68or other application component:
69</p>
70
71<pre>ContentResolver cr = getContentResolver();</pre>
72
73<p>
74You can then use the ContentResolver's methods to interact with whatever
75content providers you're interested in.
76</p>
77
78<p>
79When a query is initiated, the Android system identifies the content provider
80that's the target of the query and makes sure that it is up and running.
81The system instantiates all ContentProvider objects; you never need to do it
82on your own.  In fact, you never deal directly with ContentProvider objects
83at all.  Typically, there's just a single instance of each type of
84ContentProvider.  But it can communicate with multiple ContentResolver objects
85in different applications and processes.  The interaction between processes is
86handled by the ContentResolver and ContentProvider classes.
87</p>
88
89
90<h3>The data model</h3>
91
92<p>
93Content providers expose their data as a simple table on a database model,
94where each row is a record and each column is data of a particular type
95and meaning.  For example, information about people and their phone numbers
96might be exposed as follows:
97</p>
98
99<table>
100   <tr>
101      <th scope="col">_ID</th>
102      <th scope="col">NUMBER</th>
103      <th scope="col">NUMBER_KEY</th>
104      <th scope="col">LABEL</th>
105      <th scope="col">NAME</th>
106      <th scope="col">TYPE</th>
107   </tr>
108   <tr>
109      <td>13</td>
110      <td>(425) 555 6677</td>
111      <td>425 555 6677</td>
112      <td>Kirkland office</td>
113      <td>Bully Pulpit</td>
114      <td>{@code TYPE_WORK}</td>
115   </tr>
116   <tr>
117      <td>44</td>
118      <td>(212) 555-1234</td>
119      <td>212 555 1234</td>
120      <td>NY apartment</td>
121      <td>Alan Vain</td>
122      <td>{@code TYPE_HOME}</td>
123   </tr>
124   <tr>
125      <td>45</td>
126      <td>(212) 555-6657</td>
127      <td>212 555 6657</td>
128      <td>Downtown office</td>
129      <td>Alan Vain</td>
130      <td>{@code TYPE_MOBILE}</td>
131   </tr>
132   <tr>
133      <td>53</td>
134      <td>201.555.4433</td>
135      <td>201 555 4433</td>
136      <td>Love Nest</td>
137      <td>Rex Cars</td>
138      <td>{@code TYPE_HOME}</td>
139   </tr>
140</table>
141
142<p>
143Every record includes a numeric {@code _ID} field that uniquely identifies
144the record within the table.  IDs can be used to match records in related
145tables &mdash; for example, to find a person's phone number in one table
146and pictures of that person in another.
147</p>
148
149<p>
150A query returns a {@link android.database.Cursor} object that can move from
151record to record and column to column to read the contents of each field.
152It has specialized methods for reading each type of data.  So, to read a field,
153you must know what type of data the field contains.  (There's more on query
154results and Cursor objects later.)
155</p>
156
157
158<h3><a name="uri"></a>URIs</h3>
159
160<p>
161Each content provider exposes a public URI (wrapped as a {@link android.net.Uri}
162object) that uniquely identifies its data set.  A content provider that controls
163multiple data sets (multiple tables) exposes a separate URI for each one.  All
164URIs for providers begin with the string "{@code content://}".  The {@code content:}
165scheme identifies the data as being controlled by a content provider.
166</p>
167
168<p>
169If you're defining a content provider, it's a good idea to also define a
170constant for its URI, to simplify client code and make future updates cleaner.
171Android defines {@code CONTENT_URI} constants for all the providers that come
172with the platform.  For example, the URI for the table that matches
173phone numbers to people and the URI for the table that holds pictures of
174people (both controlled by the Contacts content provider) are:
175</p>
176
177<p>
178<p style="margin-left: 2em">{@code android.provider.Contacts.Phones.CONTENT_URI}
179<br/>{@code android.provider.Contacts.Photos.CONTENT_URI}
180</p>
181
182<p>
183The URI constant is used in all interactions with the content provider.
184Every {@link android.content.ContentResolver} method takes the URI
185as its first argument.  It's what identifies which provider the ContentResolver
186should talk to and which table of the provider is being targeted.
187</p>
188
189
190<h2><a name="querying"></a>Querying a Content Provider</h2>
191
192<p>
193You need three pieces of information to query a content provider:
194</p>
195
196<ul>
197<li>The URI that identifies the provider</li>
198<li>The names of the data fields you want to receive</li>
199<li>The data types for those fields</li>
200</ul>
201
202<p>
203If you're querying a particular record, you also need the ID for that record.
204</p>
205
206
207<h3>Making the query</h3>
208
209<p>
210To query a content provider, you can use either the
211<code>{@link android.content.ContentResolver#query ContentResolver.query()}</code>
212method or the <code>{@link  android.app.Activity#managedQuery
213Activity.managedQuery()}</code> method.
214Both methods take the same set of arguments, and both return a
215Cursor object.  However, {@code managedQuery()}
216causes the activity to manage the life cycle of the Cursor.  A managed Cursor
217handles all of the niceties, such as unloading itself when the activity pauses,
218and requerying itself when the activity restarts.  You can ask an Activity to
219begin managing an unmanaged Cursor object for you by calling
220<code>{@link android.app.Activity#startManagingCursor
221Activity.startManagingCursor()}</code>.
222</p>
223
224<p>
225The first argument to either <code>{@link android.content.ContentResolver#query query()}</code>
226or <code>{@link android.app.Activity#managedQuery managedQuery()}</code> is the provider URI
227&mdash; the {@code CONTENT_URI} constant that identifies a particular
228ContentProvider and data set (see <a href="#uri">URIs</a> earlier).
229</p>
230
231<p>
232To restrict a query to just one record, you can append the {@code _ID} value for
233that record to the URI &mdash; that is, place a string matching the ID as the
234last segment of the path part of the URI.  For example, if the ID is 23,
235the URI would be:
236</p>
237
238<p style="margin-left: 2em">{@code content://. . . ./23}</p>
239
240<p>
241There are some helper methods, particularly
242<code>{@link android.content.ContentUris#withAppendedId
243ContentUris.withAppendedId()}</code> and <code>{@link
244android.net.Uri#withAppendedPath Uri.withAppendedPath()}</code>,
245that make it easy to append an ID to a URI.  Both are static methods that return
246a Uri object with the ID added.  So, for example, if you were looking for record
24723 in the database of people contacts, you might construct a query as follows:
248</p>
249
250<pre>
251import android.provider.Contacts.People;
252import android.content.ContentUris;
253import android.net.Uri;
254import android.database.Cursor;
255
256// Use the ContentUris method to produce the base URI for the contact with _ID == 23.
257Uri myPerson = ContentUris.withAppendedId(People.CONTENT_URI, 23);
258
259// Alternatively, use the Uri method to produce the base URI.
260// It takes a string rather than an integer.
261Uri myPerson = Uri.withAppendedPath(People.CONTENT_URI, "23");
262
263// Then query for this specific record:
264Cursor cur = managedQuery(myPerson, null, null, null, null);
265</pre>
266
267<p>
268The other arguments to the <code>{@link android.content.ContentResolver#query query()}</code>
269and <code>{@link android.app.Activity#managedQuery managedQuery()}</code> methods delimit
270the query in more detail.  They are:
271</p>
272
273<ul>
274<li>The names of the data columns that should be returned.  A {@code null}
275value returns all columns.  Otherwise, only columns that are listed by name
276are returned.  All the content providers that come with the platform define
277constants for their columns.  For example, the
278{@link android.provider.Contacts.Phones android.provider.Contacts.Phones} class
279defines constants for the names of the columns in the phone table illustrated
280earlier &mdash; {@code _ID}, {@code NUMBER}, {@code NUMBER_KEY}, {@code NAME},
281and so on.</li>
282
283<li><p>A filter detailing which rows to return, formatted as an SQL {@code WHERE}
284clause (excluding the {@code WHERE} itself).  A {@code null} value returns
285all rows (unless the URI limits the query to a single record).</p></li>
286
287<li><p>Selection arguments.</p></li>
288
289<li><p>A sorting order for the rows that are returned, formatted as an SQL
290{@code ORDER BY} clause (excluding the {@code ORDER BY} itself).  A {@code null}
291value returns the records in the default order for the table, which may be
292unordered.</p></li>
293</ul>
294
295<p>
296Let's look at an example query to retrieve a list of contact names and their
297primary phone numbers:
298</p>
299
300<pre>
301import android.provider.Contacts.People;
302import android.database.Cursor;
303
304// Form an array specifying which columns to return.
305String[] projection = new String[] {
306                             People._ID,
307                             People._COUNT,
308                             People.NAME,
309                             People.NUMBER
310                          };
311
312// Get the base URI for the People table in the Contacts content provider.
313Uri contacts =  People.CONTENT_URI;
314
315// Make the query.
316Cursor managedCursor = managedQuery(contacts,
317                         projection, // Which columns to return
318                         null,       // Which rows to return (all rows)
319                         null,       // Selection arguments (none)
320                         // Put the results in ascending order by name
321                         People.NAME + " ASC");
322</pre>
323
324<p>
325This query retrieves data from the People table of the Contacts content
326provider.  It gets the name, primary phone number, and unique record ID for
327each contact.  It also reports the number of records that are returned as
328the {@code _COUNT} field of each record.
329</p>
330
331<p>
332The constants for the names of the columns are defined in various interfaces
333&mdash; {@code _ID} and {@code _COUNT} in
334{@link android.provider.BaseColumns BaseColumns}, {@code NAME} in {@link android.provider.Contacts.PeopleColumns PeopleColumns}, and {@code NUMBER}
335in {@link android.provider.Contacts.PhonesColumns PhoneColumns}.  The
336{@link android.provider.Contacts.People Contacts.People} class implements
337each of these interfaces, which is why the code example above could refer
338to them using just the class name.
339</p>
340
341
342<h3>What a query returns</h3>
343
344<p>
345A query returns a set of zero or more database records.  The names of the
346columns, their default order, and their data types are specific to each
347content provider.
348But every provider has an {@code _ID} column, which holds a unique numeric
349ID for each record.  Every provider can also report the number
350of records returned as the {@code _COUNT} column; its value
351is the same for all rows.
352</p>
353
354<p>
355Here is an example result set for the query in the previous section:
356</p>
357
358<table border="1">
359   <tbody>
360      <tr>
361         <th scope="col">_ID</th>
362         <th scope="col">_COUNT</th>
363         <th scope="col">NAME</th>
364         <th scope="col">NUMBER</th>
365      </tr>
366      <tr>
367         <td>44</td>
368         <td>3</td>
369         <td>Alan Vain</td>
370         <td>212 555 1234</td>
371      </tr>
372      <tr>
373         <td>13</td>
374         <td>3</td>
375         <td>Bully Pulpit</td>
376         <td>425 555 6677</td>
377      </tr>
378      <tr>
379         <td>53</td>
380         <td>3</td>
381         <td>Rex Cars</td>
382         <td>201 555 4433</td>
383      </tr>
384   </tbody>
385</table>
386
387<p>
388The retrieved data is exposed by a {@link android.database.Cursor Cursor}
389object that can be used to iterate backward or forward through the result
390set.  You can use this object only to read the data.  To add, modify, or
391delete data, you must use a ContentResolver object.
392</p>
393
394
395<h3>Reading retrieved data</h3>
396
397<p>
398The Cursor object returned by a query provides access to a recordset of
399results.  If you have queried for a specific record by ID, this set will
400contain only one value.  Otherwise, it can contain multiple values.
401(If there are no matches, it can also be empty.)  You
402can read data from specific fields in the record, but you must know the
403data type of the field, because the Cursor object has a separate method
404for reading each type of data &mdash; such as <code>{@link
405android.database.Cursor#getString getString()}</code>, <code>{@link
406android.database.Cursor#getInt getInt()}</code>, and <code>{@link
407android.database.Cursor#getFloat getFloat()}</code>.
408(However, for most types, if you call the method for reading strings,
409the Cursor object will give you the String representation of the data.)
410The Cursor lets you request the column name from the index of the column,
411or the index number from the column name.
412</p>
413
414<p>
415The following snippet demonstrates reading names and phone numbers from
416the query illustrated earlier:
417</p>
418
419<pre>
420import android.provider.Contacts.People;
421
422private void getColumnData(Cursor cur){
423    if (cur.moveToFirst()) {
424
425        String name;
426        String phoneNumber;
427        int nameColumn = cur.getColumnIndex(People.NAME);
428        int phoneColumn = cur.getColumnIndex(People.NUMBER);
429        String imagePath;
430
431        do {
432            // Get the field values
433            name = cur.getString(nameColumn);
434            phoneNumber = cur.getString(phoneColumn);
435
436	    // Do something with the values.
437            ...
438
439        } while (cur.moveToNext());
440
441    }
442}
443</pre>
444
445<p>
446If a query can return binary data, such as an image or sound, the data
447may be directly entered in the table or the table entry for that data may be
448a string specifying a {@code content:} URI that you can use to get the data.
449In general, smaller amounts of data (say, from 20 to 50K or less) are most often
450directly entered in the table and can be read by calling
451<code>{@link android.database.Cursor#getBlob Cursor.getBlob()}</code>.
452It returns a byte array.
453</p>
454
455<p>
456If the table entry is a {@code content:} URI, you should never try to open
457and read the file directly (for one thing, permissions problems can make this
458fail).  Instead, you should call
459<code>{@link android.content.ContentResolver#openInputStream
460ContentResolver.openInputStream()}</code> to get an
461{@link java.io.InputStream} object that you can use to read the data.
462</p>
463
464
465<h2><a name="modifying"></a>Modifying Data</h2>
466
467<p>
468Data kept by a content provider can be modified by:
469</p>
470
471<ul>
472<p><li>Adding new records</li>
473<li>Adding new values to existing records</li>
474<li>Batch updating existing records</li>
475<li>Deleting records</li>
476</ul>
477
478<p>
479All data modification is accomplished using {@link android.content.ContentResolver}
480methods.  Some content providers require a more restrictive permission for writing
481data than they do for reading it.  If you don't have permission to write to a
482content provider, the ContentResolver methods will fail.
483</p>
484
485
486<h3>Adding records</h3>
487
488<p>
489To add a new record to a content provider, first set up a map of key-value pairs
490in a {@link android.content.ContentValues} object, where each key matches
491the name of a column in the content provider and the value is the desired
492value for the new record in that column.  Then call <code>{@link
493android.content.ContentResolver#insert ContentResolver.insert()}</code> and pass
494it the URI of the provider and the ContentValues map.  This method returns
495the full URI of the new record &mdash; that is, the provider's URI with
496the appended ID for the new record.  You can then use this URI to query and
497get a Cursor over the new record, and to further modify the record.
498Here's an example:
499</p>
500
501<pre>
502import android.provider.Contacts.People;
503import android.content.ContentResolver;
504import android.content.ContentValues;
505
506ContentValues values = new ContentValues();
507
508// Add Abraham Lincoln to contacts and make him a favorite.
509values.put(People.NAME, "Abraham Lincoln");
510// 1 = the new contact is added to favorites
511// 0 = the new contact is not added to favorites
512values.put(People.STARRED, 1);
513
514Uri uri = getContentResolver().insert(People.CONTENT_URI, values);
515</pre>
516
517
518<h3>Adding new values</h3>
519
520<p>
521Once a record exists, you can add new information to it or modify
522existing information.  For example, the next step in the example above would
523be to add contact information &mdash; like a phone number or an IM or e-mail
524address &mdash; to the new entry.
525</p>
526
527<p>
528The best way to add to a record in the Contacts database is to append
529the name of the table where the new data goes to the URI for the
530record, then use the amended URI to add the new data values.  Each
531Contacts table exposes a name for this purpose as a {@code
532CONTENT_DIRECTORY} constant.  The following code continues the previous
533example by adding a phone number and e-mail address for the record
534just created:
535</p>
536
537<pre>
538Uri phoneUri = null;
539Uri emailUri = null;
540
541// Add a phone number for Abraham Lincoln.  Begin with the URI for
542// the new record just returned by insert(); it ends with the _ID
543// of the new record, so we don't have to add the ID ourselves.
544// Then append the designation for the phone table to this URI,
545// and use the resulting URI to insert the phone number.
546phoneUri = Uri.withAppendedPath(uri, People.Phones.CONTENT_DIRECTORY);
547
548values.clear();
549values.put(People.Phones.TYPE, People.Phones.TYPE_MOBILE);
550values.put(People.Phones.NUMBER, "1233214567");
551getContentResolver().insert(phoneUri, values);
552
553// Now add an email address in the same way.
554emailUri = Uri.withAppendedPath(uri, People.ContactMethods.CONTENT_DIRECTORY);
555
556values.clear();
557// ContactMethods.KIND is used to distinguish different kinds of
558// contact methods, such as email, IM, etc.
559values.put(People.ContactMethods.KIND, Contacts.KIND_EMAIL);
560values.put(People.ContactMethods.DATA, "test@example.com");
561values.put(People.ContactMethods.TYPE, People.ContactMethods.TYPE_HOME);
562getContentResolver().insert(emailUri, values);
563</pre>
564
565<p>
566You can place small amounts of binary data into a table by calling
567the version of <code>{@link android.content.ContentValues#put
568ContentValues.put()}</code> that takes a byte array.
569That would work for a small icon-like image or a short audio clip, for example.
570However, if you have a large amount of binary data to add, such as a photograph
571or a complete song, put a {@code content:} URI for the data in the table and call
572<code>{@link android.content.ContentResolver#openOutputStream
573ContentResolver.openOutputStream()}</code>
574with the file's URI.  (That causes the content provider to store the data
575in a file and record the file path in a hidden field of the record.)
576</p>
577
578<p>
579In this regard, the {@link android.provider.MediaStore} content
580provider, the main provider that dispenses image, audio, and video
581data, employs a special convention:  The same URI that is used with
582{@code query()} or {@code managedQuery()} to get meta-information
583about the binary data (such as, the caption of a photograph or the
584date it was taken) is used with {@code openInputStream()}
585to get the data itself.  Similarly, the same URI that is used with
586{@code insert()} to put meta-information into a MediaStore record
587is used with {@code openOutputStream()} to place the binary data there.
588The following code snippet illustrates this convention:
589</p>
590
591<pre>
592import android.provider.MediaStore.Images.Media;
593import android.content.ContentValues;
594import java.io.OutputStream;
595
596// Save the name and description of an image in a ContentValues map.
597ContentValues values = new ContentValues(3);
598values.put(Media.DISPLAY_NAME, "road_trip_1");
599values.put(Media.DESCRIPTION, "Day 1, trip to Los Angeles");
600values.put(Media.MIME_TYPE, "image/jpeg");
601
602// Add a new record without the bitmap, but with the values just set.
603// insert() returns the URI of the new record.
604Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);
605
606// Now get a handle to the file for that record, and save the data into it.
607// Here, sourceBitmap is a Bitmap object representing the file to save to the database.
608try {
609    OutputStream outStream = getContentResolver().openOutputStream(uri);
610    sourceBitmap.compress(Bitmap.CompressFormat.JPEG, 50, outStream);
611    outStream.close();
612} catch (Exception e) {
613    Log.e(TAG, "exception while writing image", e);
614}
615</pre>
616
617
618<h3>Batch updating records</h3>
619
620<p>
621To batch update a group of records (for example, to change "NY" to "New York"
622in all fields), call the <code>{@link
623android.content.ContentResolver#update ContentResolver.update()}</code>
624method with the columns and values to change.
625</p>
626
627
628<h3><a name="deletingrecord"></a>Deleting a record</h3>
629
630<p>
631To delete a single record, call {<code>{@link
632android.content.ContentResolver#delete ContentResolver.delete()}</code>
633with the URI of a specific row.
634</p>
635
636<p>
637To delete multiple rows, call <code>{@link
638android.content.ContentResolver#delete ContentResolver.delete()}</code>
639with the URI of the type of record to delete (for example, {@code android.provider.Contacts.People.CONTENT_URI}) and an SQL {@code WHERE}
640clause defining which rows to delete.  (<i><b>Caution</b>:
641Be sure to include a valid {@code WHERE} clause if you're deleting a general
642type, or you risk deleting more records than you intended!</i>).
643</p>
644
645
646<h2><a name="creating"></a>Creating a Content Provider</h2>
647
648<p>
649To create a content provider, you must:
650</p>
651
652<ul>
653<li>Set up a system for storing the data.  Most content providers
654store their data using Android's file storage methods or SQLite databases,
655but you can store your data any way you want.  Android provides the
656{@link android.database.sqlite.SQLiteOpenHelper SQLiteOpenHelper}
657class to help you create a database and {@link
658android.database.sqlite.SQLiteDatabase SQLiteDatabase} to manage it.</li>
659
660<li><p>Extend the {@link android.content.ContentProvider} class to provide
661access to the data.</p></li>
662
663<li><p>Declare the content provider in the manifest file for your
664application (AndroidManifest.xml).</p></li>
665</ul>
666
667<p>
668The following sections have notes on the last two of these tasks.
669</p>
670
671
672<h3>Extending the ContentProvider class</h3>
673
674<p>
675You define a {@link android.content.ContentProvider} subclass to
676expose your data to others using the conventions expected by
677ContentResolver and Cursor objects.  Principally, this means
678implementing six abstract methods declared in the ContentProvider class:
679</p>
680
681<p style="margin-left: 2em">{@code query()}
682<br/>{@code insert()}
683<br/>{@code update()}
684<br/>{@code delete()}
685<br/>{@code getType()}
686<br/>{@code onCreate()}</p>
687
688<p>
689The {@code query()} method must return a {@link android.database.Cursor} object
690that can iterate over the requested data.  Cursor itself is an interface, but
691Android provides some ready-made Cursor objects that you can use.  For example,
692{@link android.database.sqlite.SQLiteCursor} can iterate over data stored in
693an SQLite database.  You get the Cursor object by calling any of the {@link
694android.database.sqlite.SQLiteDatabase SQLiteDatabase} class's {@code query()}
695methods.  There are other Cursor implementations &mdash; such as {@link
696android.database.MatrixCursor} &mdash; for data not stored in a database.
697</p>
698
699<p>
700Because these ContentProvider methods can be called from
701various ContentResolver objects in different processes and threads,
702they must be implemented in a thread-safe manner.
703</p>
704
705<p>
706As a courtesy, you might also want to call <code>{@link android.content.ContentResolver#notifyChange(android.net.Uri,android.database.ContentObserver)
707ContentResolver.notifyChange()}</code> to notify listeners when there are
708modifications to the data.
709</p>
710
711<p>
712Beyond defining the subclass itself, there are other steps you should take
713to simplify the work of clients and make the class more accessible:
714</p>
715
716<ul>
717<li>Define a {@code public static final} {@link android.net.Uri}
718named {@code CONTENT_URI}.  This is the string that represents the full
719{@code content:} URI that your content provider handles.  You must define a
720unique string for this value.  The best solution is to use the fully-qualified
721class name of the content provider (made lowercase).  So, for example, the
722URI for a TransportationProvider class could be defined as follows:
723
724<pre>public static final Uri CONTENT_URI =
725               Uri.parse("content://com.example.codelab.transportationprovider");</pre>
726
727<p>
728If the provider has subtables, also define {@code CONTENT_URI} constants for
729each of the subtables.  These URIs should all have the same authority (since
730that identifies the content provider), and be distinguished only by their paths.
731For example:
732</p>
733
734<p style="margin-left: 2em">{@code content://com.example.codelab.transportationprovider/train}
735<br/>{@code content://com.example.codelab.transportationprovider/air/domestic}
736<br/>{@code content://com.example.codelab.transportationprovider/air/international}</p>
737
738<p>
739For an overview of {@code content:} URIs, see the <a href="#urisum">Content URI
740Summary</a> at the end of this document.
741</p></li>
742
743<li><p>Define the column names that the content provider will return to clients.
744If you are using an underlying database, these column names are typically
745identical to the SQL database column names they represent.  Also define
746{@code public static} String constants that clients can use to specify
747the columns in queries and other instructions.
748</p>
749
750<p>
751Be sure to include an integer column named "{@code _id}"
752(with the constant {@code _ID}) for
753the IDs of the records.  You should have this field whether or not you have
754another field (such as a URL) that is also unique among all records.  If
755you're using the SQLite database, the {@code _ID} field should be the
756following type:
757</p>
758
759<p style="margin-left: 2em">{@code INTEGER PRIMARY KEY AUTOINCREMENT}</p>
760
761<p>
762The {@code AUTOINCREMENT} descriptor is optional.  But without it, SQLite
763increments an ID counter field to the next number above the largest
764existing number in the column.  If you delete the last row, the next row added
765will have the same ID as the deleted row.  {@code AUTOINCREMENT} avoids this
766by having SQLite increment to the next largest value whether deleted or not.
767</p>
768</li>
769
770<li><p>Carefully document the data type of each column.  Clients need this
771information to read the data.</p></li>
772
773<li><p>If you are handling a new data type, you must define a new MIME type
774to return in your implementation of <code>{@link
775android.content.ContentProvider#getType ContentProvider.getType()}</code>.
776The type depends in part on whether or not the {@code content:} URI submitted
777to {@code getType()} limits the request to a specific record.  There's one
778form of the MIME type for a single record and another for multiple records.
779Use the {@link android.net.Uri Uri} methods to help determine what is being
780requested.  Here is the general format for each type:</p></li>
781
782<ul>
783<li><p>For a single record:&nbsp;&nbsp;&nbsp; {@code vnd.android.cursor.item/vnd.<em>yourcompanyname.contenttype</em>}</p>
784
785<p>For example, a request for train record 122, like this URI,</p>
786<p style="margin-left: 2em">{@code content://com.example.transportationprovider/trains/122}</p>
787
788<p>might return this MIME type:</p>
789<p style="margin-left: 2em">{@code vnd.android.cursor.item/vnd.example.rail}</p>
790</li>
791
792<li><p>For multiple records:&nbsp;&nbsp;&nbsp; {@code vnd.android.cursor.dir/vnd.<em>yourcompanyname.contenttype</em>}</p>
793
794<p>For example, a request for all train records, like the following URI,</p>
795<p style="margin-left: 2em">{@code content://com.example.transportationprovider/trains}</p>
796
797<p>might return this MIME type:</p>
798<p style="margin-left: 2em">{@code vnd.android.cursor.dir/vnd.example.rail}</p>
799</li>
800</ul>
801
802<li><p>If you are exposing byte data that's too big to put in the table itself
803&mdash; such as a large bitmap file &mdash; the field that exposes the
804data to clients should actually contain a {@code content:} URI string.
805This is the field that gives clients access to the data file.  The record
806should also have another field, named "{@code _data}" that lists the exact file
807path on the device for that file.  This field is not intended to be read by
808the client, but by the ContentResolver.  The client will call <code>{@link
809android.content.ContentResolver#openInputStream ContentResolver.openInputStream()}</code>
810on the user-facing field holding the URI for the item.  The ContentResolver
811will request the "{@code _data}" field for that record, and because
812it has higher permissions than a client, it should be able to access
813that file directly and return a read wrapper for the file to the client.</p></li>
814
815</ul>
816
817<p>
818For an example of a private content provider implementation, see the
819NodePadProvider class in the Notepad sample application that ships with the SDK.
820</p>
821
822
823<h3>Declaring the content provider</h3>
824
825<p>
826To let the Android system know about the content provider you've developed,
827declare it with a {@code &lt;provider&gt;} element in the application's
828AndroidManifest.xml file.  Content providers that are not declared in the
829manifest are not visible to the Android system
830</p>
831
832<p>
833The {@code name} attribute is the fully qualified name of the ContentProvider
834subclass.  The {@code authorities} attribute is the authority part of the
835{@code content:} URI that identifies the provider.
836For example if the ContentProvider subclass is AutoInfoProvider, the
837{@code &lt;provider&gt;} element might look like this:
838</p>
839
840<pre>
841&lt;provider android:name="com.example.autos.AutoInfoProvider"
842          android:authorities="com.example.autos.autoinfoprovider"
843          . . . /&gt
844&lt;/provider&gt;
845</pre>
846
847<p>
848Note that the {@code authorities} attribute omits the path part of a
849{@code content:} URI.  For example, if AutoInfoProvider controlled subtables
850for different types of autos or different manufacturers,
851</p>
852
853<p style="margin-left: 2em">{@code content://com.example.autos.autoinfoprovider/honda}
854<br/>{@code content://com.example.autos.autoinfoprovider/gm/compact}
855<br/>{@code content://com.example.autos.autoinfoprovider/gm/suv}</p>
856
857<p>
858those paths would not be declared in the manifest.  The authority is what
859identifies the provider, not the path; your provider can interpret the path
860part of the URI in any way you choose.
861</p>
862
863<p>
864Other {@code &lt;provider&gt;} attributes can set permissions to read and
865write data, provide for an icon and text that can be displayed to users,
866enable and disable the provider, and so on.  Set the {@code multiprocess}
867attribute to "{@code true}" if data does not need to be synchronized between
868multiple running versions of the content provider.  This permits an instance
869of the provider to be created in each client process, eliminating the need
870to perform IPC.
871</p>
872
873
874<h2><a name="urisum"></a>Content URI Summary</h2>
875
876<p>
877Here is a recap of the important parts of a content URI:
878</p>
879
880<p>
881<img src="{@docRoot}images/content_uri.png" alt="Elements of a content URI"
882height="80" width="528">
883</p>
884
885<ol type="A">
886<li>Standard prefix indicating that the data is controlled by a
887content provider. It's never modified.</li>
888
889<li><p>The authority part of the URI; it identifies the content provider.
890For third-party applications, this should be a fully-qualified class name
891(reduced to lowercase) to ensure uniqueness.  The authority is declared in
892the {@code &lt;provider&gt;} element's {@code authorities} attribute:</p>
893
894<pre>&lt;provider android:name=".TransportationProvider"
895          android:authorities="com.example.transportationprovider"
896          . . .  &gt;</pre></li>
897
898<li><p>The path that the content provider uses to determine what kind of data is
899being requested.  This can be zero or more segments long.  If the content provider
900exposes only one type of data (only trains, for example), it can be absent.
901If the provider exposes several types, including subtypes, it can be several
902segments long &mdash; for example, "{@code land/bus}", "{@code land/train}",
903"{@code sea/ship}", and "{@code sea/submarine}" to give four possibilities.</p></li>
904
905<li><p>The ID of the specific record being requested, if any.  This is the
906{@code _ID} value of the requested record.  If the request is not limited to
907a single record, this segment and the trailing slash are omitted:</p>
908
909<p style="margin-left: 2em">{@code content://com.example.transportationprovider/trains}</p>
910</li>
911</ol>
912
913
914