Android Tutorial: Content Provider Basics

This is the first part of a three part tutorial covering Android’s content providers. Here I’m going to introduce content providers and to cover the basic concepts you need to make use of existing ones or to write content providers on your own.

What are content providers?

Content providers are Android’s central mechanism that enables you to access data of other applications – mostly information stored in databases or flat files. As such content providers are one of Android’s central component types to support the modular approach common to Android. Without content providers accessing data of other apps would be a mess.

Content providers support the four basic operations, normally called CRUD-operations. CRUD is the acronym for create, read, update and delete. With content providers those objects simply represent data – most often a record (tuple) of a database – but they could also be a photo on your SD-card or a video on the web.

Android provides some standard content providers to access contacts, media files, preferences and so on. I am going to show you how to use these content providers in the second part of this tutorial.

In the third part I am going to explain the basics you need to write a content provider yourself. Your content provider makes accessing your data that much easier for developers of other apps. Furthermore using content providers also makes the development of widgets easier.

Content URIs

The most important concept to understand when dealing with content providers is the content URI. Whenever you want to access data from a content provider you have to specify a URI. URIs for content providers look like this:

content://authority/optionalPath/optionalId

They contain four parts: The scheme to use, an authority, an optional path and an optional id.

  • The scheme for content providers is always “content”. The colon and double-slash “://” are a fixed part of the URI-RFC and separate the scheme from the authority.
  • The next part is the authority for the content provider. Authorities have to be unique for every content provider. Thus the naming conventions should follow the Java package name rules. That is you should use the reversed domain name of your organization plus a qualifier for each and every content provider you publish. The Android documentation recommends to use the fully qualified class name of your ContentProvider-subclass.
  • The third part, the optional path, is used to distinguish the kinds of data your content provider offers. The content provider for Android’s mediastore, for example, distinguishes between audio files, video files and images using different paths for each of these types of media. This way a content provider can support different types of data that are nevertheless related. For totally unrelated data though you should use different content providers – and thus different authorities.
  • The last element is the optional id, which – if present – must be numeric. The id is used whenever you want to access a single record (e.g. a specific video file).

There are two types of URIs: directory- and id-based URIs. If no id is specified a URI is automatically a directory-based URI.

  • You use directory-based URIs to access multiple elements of the same type (e.g. all songs of a band). All CRUD-operations are possible with directory-based URIs.
  • You use id-based URIs if you want to access a specific element. You cannot create objects using an id-based URI – but reading, updating and deleting is possible.

The path of content URIs can contain additional information to limit the scope. The MediaStore content provider for example distinguishes between audio and other types. In addition to this it offers URIs that limit its operations to albums only or others to genres only. Content providers normally have constants for the URIs they support. You will see some examples of URIs in part II and part III.

Content Types

Besides URIs another important concept to understand is the use of content types. Content types also have a standardized format which was first defined in RFC 1049 and refined in RFC 2045.

A content type consist of a media type and a subtype divided by a slash. A typical example is “image/png”. The media type “image” describes the content as an image file which is further specified to be of the Portable Network Graphic variety by the subtype “png”.

As with URIs there is also a standard for content types in Android. Table 2 lists the only two media types that Android accepts for content providers. As you can see, those two media types match the two types of URIs mentioned above.

The media types used for content providers
Type Usage Constant
vnd.android.cursor.item Used for single records ContentResolver.CURSOR_ITEM_BASE_TYPE
vnd.android.cursor.dir Used for multiple records ContentResolver.CURSOR_DIR_BASE_TYPE

The subtype on the other hand is used for content provider specific details and should differ for all types your content provider supports. The naming convention for subtypes is vnd.yourcompanyname.contenttype. For our sample project the subtype is “vnd.cpsample.lentitems”.

Most content providers support multiple subtypes. In the case of a media player for example you might have subtypes for genre, band, titles, musicians and so on.

Which standard Content Providers are available?

A number of content providers are part of Android’s API. All these standard providers are defined in the package android.provider. The following table lists the standard providers and what they are used for.

The standard content providers of Android
Provider Since     Usage
Browser SDK 1 Manages your web-searches, bookmarks and browsing-history.
CalendarContract SDK 14 Manages the calendars on the user’s device.
CallLog SDK 1 Keeps track of your call history.
Contacts SDK 1 The old and deprecated content provider for managing contacts. You should only use this provider if you need to support an SDK prior to SDK 5!
ContactsContract SDK 5 Deals with all aspects of contact management. Supersedes the Contacts-content provider.
MediaStore SDK 1 The content provider responsible for all your media files like music, video and pictures.
Settings SDK 1 Manages all global settings of your device.
UserDictionary SDK 3 Keeps track of words you add to the default dictionary.

Please make use of the standard providers whenever you need data they provide. For example there are apps that ignore the UserDictionary (e.g. Swype). So the user might end up adding the same words in multiple apps – which is pretty annoying. Something like this will not help your rating in Android’s Market.

Of course you should always keep in mind that not all of the standard providers might be present on certain devices. E.g. a tablet might have no CallLog. Thus you should always test for availability. One way to do so is querying a content provider and checking if the returned cursor is null. That’s the return value when the provider doesn’t exist. The other CRUD-methods though throw an exception in case you pass in an unknown URI.

Lessons learned

In this part of this mini series you have learned all about the two types of URIs for content providers as well as about the two media types of content types. I have listed the standard providers that Android brings with it and that you can use in your projects. How to use them is the topic of the next part of this mini-series: Using content providers.

Share this article:

You can leave a response, or trackback from your own site.

17 Responses to “Android Tutorial: Content Provider Basics”

  1. kala says:

    Hi
    This is good and simple.thanks

  2. Vik says:

    thanks for a great tutorial
    its helps me as a beginner alot

  3. Shyam says:

    Thanx for tutorial

  4. Chuanyung says:

    Nice!

  5. Akhil says:

    this is simply one of the most brilliant tutorial i came across, just studied basic of content provider, going for part,

    You are good, everything is nice and so well explained.

  6. Anat says:

    well explained! thank you so much

  7. Zsolt Farkas says:

    Thanks for this & related tutorials. Still I am a little bit confused about the following:

    ContentProvider’s CRUD methods are basically running on the UI thread. I have seen examples making use of CursorLoader to run a ContentProvider query on the background, producing data for a ListView for example; but I have not come across an example using a ContentProvider’s insert, update or delete method on the background thread. Does it make any sense to use a ContentProvider’s insert, update or delete method together with a CursorLoader or any other object that places these operations in the background thread?

    I could adapt a background use of ContentProvider for an insert operation as well (with CursorLoader, actually) – it worked, but looking at the debugger I found that it opened up several new threads that would not cease after the insert operation was over. It just does not seem a neat solution…

  8. Hi Wolfram,
    I just wanted to say Thanks. Your ContentProvider tutorials are just what I needed to complete my project.

    Best Wishes,
    Monica

  9. Fabio says:

    I am using content providers in a simulation under Eclipse ADT, i.e. , I am using the emulator. Where are data corresponding to an URL like content://course.labs.contentproviderlab.provider/badges physically stored? In a directory on my PC?

    Actually, using this URL I get a crash
    03-12 07:42:31.438: E/AndroidRuntime(1285): java.lang.IllegalArgumentException: Unknown URL content://course.labs.contentproviderlab.provider/badges

    What does it exactly mean?

    • Your emulator image file is stored on your pc. Where the data of your provider can be found within the file system of the emulator is dependent on the kind of content provider you use. Most likely you se an SQLite backed content provider. In that case the data could be found in /data/data/your.package.name/databases. Here you can find a file containing your database. How to create the database and what to name it is up to you.

      The exception though is caused by the URL not being registered. You have to register your content provider in the AndroidManifest.xml file. You can find all the necessary information on how to do that in my tutorial on writing a content provider.

  10. Frie says:

    You are writing great tuorials, although I am a little bit confused about ID-based and Directory based URI’s.
    I am trying to update one record in a table and to approach that record I use ContentUris.withAppendedId. The Uri that I use is for a table called ‘categeories’ and the id is ’21′.
    But when I use that new Uri in the update method I get an error because the system only sees the ID in the URI and no longer the table in the original Uri: SQLiteException: while compiling: SELECT category from 21…..
    It should select category with id ’21′ from table ‘categories’.
    What am I doing wrong?

    • What you are doing as a client sounds about right. I assume the problem lies within your ContentProvider subclass. See my tutorial on writing a content provider.

      Did you correctly set up your UriMatcher entries and used your UriMatcher object to parse the uri in the update method? Those two are the most likely problems.

      If this is not sufficient to get you on track again, I suggest to post a question on SO (you can ping me via the contact form with a link to your question, when you have done so). Add your client code together with the UriMatcher part and the update() method of your provider to your question, so that anyone willing to help can understand what’s going on.

  11. hiren says:

    nice article helpful with me thanks for sharing.

  12. prashant says:

    Hi Wolfram,
    Thanks for the awesome post as always. In my app, I want to delete all the images, videos and all thumbnails. I am able to do that using the MediaStore Provider. What query I’ve is if there are a lot of images and videos, then the delete operation takes much time. So, I was looking for a handler kind of thing that will notify if the operation is completed. Meanwhile the operation, I’ll show a progress dialog. How can I accomplish this. Thanks in advance for any help.

Leave a Reply

You can also subscribe without commenting.