How to address multiple content providers?

JJD picture JJD · Aug 15, 2012 · Viewed 10.5k times · Source

I created two content providers that work on two different tables of the same SQLite database. They share a single instance of SQLiteOpenHelper as described in the post of Ali Serghini. Each content provider is registered in AndroidManifest.xml as follows.

<provider
    android:name=".contentprovider.PostsContentProvider"
    android:authorities="com.example.myapp.provider"
    android:exported="false"
    android:multiprocess="true" >
</provider>
<provider
    android:name=".contentprovider.CommentsContentProvider"
    android:authorities="com.example.myapp.provider"
    android:exported="false"
    android:multiprocess="true" >
</provider>

Each content provider defines the needed content URIs and supplies an UriMatcher.

public class PostsProvider extends BaseContentProvider {

    private static final UriMatcher sUriMatcher = buildUriMatcher();
    private static final int POSTS = 100;
    private static final int POST_ID = 101;

    private static UriMatcher buildUriMatcher() {
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = CustomContract.CONTENT_AUTHORITY;
        matcher.addURI(authority, DatabaseProperties.TABLE_NAME_POSTS, POSTS);
        matcher.addURI(authority, DatabaseProperties.TABLE_NAME_POSTS + "/#", POST_ID);
        return matcher;
    }

...

public class CommentsProvider extends BaseContentProvider {

    protected static final UriMatcher sUriMatcher = buildUriMatcher();
    protected static final int COMMENTS = 200;
    protected static final int COMMENT_ID = 201;

    private static UriMatcher buildUriMatcher() {
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = CustomContract.CONTENT_AUTHORITY;
        matcher.addURI(authority, DatabaseProperties.TABLE_NAME_COMMENTS, COMMENTS);
        matcher.addURI(authority, DatabaseProperties.TABLE_NAME_COMMENTS + "/#", COMMENT_ID);
        return matcher;
    }

When I invoke the content resolver to insert posts, the PostsContentProvider is targeted. When I try to insert comments, however, the content resolver does not refer to the CommentsContentProvider as expected, but calls upon the PostsContentProvider. The result is the following exception which I throw in the PostsContentProvider.

UnsupportedOperationException: Unknown URI: content://com.example.myapp.provider/comments

Is it possible to output all available content URIs currently registered with an content provider?

Answer

nandeesh picture nandeesh · Aug 15, 2012

The android:authorities needs to be unique for each content provider. The documentation is here quoted from doc

The content: scheme identifies the data as belonging to a content provider and the authority (com.example.project.healthcareprovider) identifies the particular provider. The authority therefore must be unique.