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.
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:
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.
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.
|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.
|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.
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.