Using Uri Matcher to Figure Out the URIs

We've mentioned the UriMatcher class several times now; let's delve into it. Almost all methods in a content provider are overloaded with respect to the URI. For example, the same query() method is called whether you want to retrieve a single book or a list of multiple books. It is up to the method to know which type of URI is being requested. Android's UriMatcher utility class helps you identify the URI types.

Here's how it works: you tell an instance of UriMatcher what kind of URI patterns to expect. You will also associate a unique number with each pattern. Once these patterns are registered, you can then ask UriMatcher if the incoming URI matches a certain pattern.

As we've mentioned, our BookProvider content provider has two URI patterns: one for a collection of books, and one for a single book. The code in Listing 3-31 registers both these patterns using UriMatcher. It allocates 1 for a collection of books and a 2 for a single book (the URI patterns themselves are defined in the metadata for the books table).

Listing 3-31. Registering URI Patterns with UriMatcher private static final UriMatcher sUriMatcher; //define ids for each uri type private static final int INCOMING_BOOK_COLLECTION_URI_INDICATOR = 1; private static final int INCOMING_SINGLE_BOOK_URI_INDICATOR = 2;

static {

sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); //Register pattern for the books sUriMatcher.addURI(BookProviderMetaData.AUTHORITY

, INCOMING_BOOK_COLLECTION_URI_INDICATOR); //Register pattern for a single book sUriMatcher.addURI(BookProviderMetaData.AUTHORITY

INCOMING_SINGLE_BOOK_URI_INDICATOR);

Now that this registration is in place, you can see how UriMatcher plays a part in the query-method implementation:

switch (sUriMatcher.match(uri)) {

case INCOMING_BOOK_COLLECTION_URI_INDICATOR: case INCOMING_SINGLE_BOOK_URI_INDICATOR: default:

throw new IllegalArgumentException("Unknown URI " + uri);

Notice how the match method returns the same number that was registered earlier. The constructor of UriMatcher takes an integer to use for the root URI. UriMatcher returns this number if there are neither path segments nor authorities on the URL. UriMatcher also returns NO_MATCH when the patterns don't match. You can construct a UriMatcher with no root-matching code; in that case, Android initializes UriMatcher to NO_MATCH internally. So you could have written the code in Listing 3-31 as this instead:

static {

sUriMatcher = new UriMatcher(); sUriMatcher.addURI(BookProviderMetaData.AUTHORITY

, INCOMING_BOOK_COLLECTION_URI_INDICATOR);

sUriMatcher.addURI(BookProviderMetaData.AUTHORITY

INCOMING_SINGLE_BOOK_URI_INDICATOR);

0 0

Post a comment