androidandroid-contentproviderandroid-contentresolver

Failed to find provider info error


I am trying to have a contentprovider , but I am having trouble because I am getting an error of "Failed to find provider info for com.example.alex.hopefulyworks"

Here is the manifest and the contentprovider

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.alex.hopefulythisworks" >

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <provider android:name=".ColorContentProvider"
            android:authorities="com.example.alex.hopefulythisworks.ColorContentProvider"
            android:enabled="true"
            android:exported="true" >
        </provider>

    </application>

</manifest>





    package com.example.alex.hopefulythisworks;
     ....
    public class ColorContentProvider extends ContentProvider {

    private ColorHelper database;

    private static final String AUTHORITY
            = "com.example.alex.hopefulythisworks";

    private static final String BASE_PATH
            = "tasks";

    public static final Uri CONTENT_URI
            = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
    public static final String CONTENT_URI_PREFIX
            = "content://" + AUTHORITY + "/" + BASE_PATH + "/";

    private static final UriMatcher sURIMatcher =
            new UriMatcher(UriMatcher.NO_MATCH);

    private static final int COLOR = 1;
    private static final int COLOR_ROW = 2;

    static {
        sURIMatcher.addURI(AUTHORITY, BASE_PATH, COLOR);
        sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", COLOR_ROW);
    }



    @Override
    public boolean onCreate() {
        database = new ColorHelper(getContext());
       Log.d("contentprovider" , "inside content provider oncreate ");
        return false;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        int uriType = sURIMatcher.match(uri);

        SQLiteDatabase sqlDB = database.getWritableDatabase();

        long id = 0;
        switch (uriType) {
            case COLOR:
                id = sqlDB.insert(ColorTable.TABLE_TASK,
                        null, values);
                break;
            default:
                throw new IllegalArgumentException("Unknown URI: "
                        + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return Uri.parse( CONTENT_URI_PREFIX + id);
    }

    @Override
    public String getType(Uri uri) {
        return null;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {

        // check if the caller has requested a column which does not exists
        ColorTable.validateProjection( projection );

        // Using SQLiteQueryBuilder instead of query() method
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

        queryBuilder.setTables( ColorTable.TABLE_TASK );

        switch ( sURIMatcher.match(uri) ) {
            case COLOR:
                break;
            case COLOR_ROW:
                // add the task ID to the original query
                queryBuilder.appendWhere( ColorTable.COLUMN_ID + "=" + uri.getLastPathSegment() );
                break;
            default:
                throw new IllegalArgumentException("Invalid URI: " + uri);
        }

        System.out.println("before null check");
        if(database == null){
            System.out.println("database is null");
            database = new ColorHelper(getContext());
        }
        System.out.println("after null check");

        SQLiteDatabase db = database.getWritableDatabase();
        Cursor cursor = queryBuilder.query( db, projection, selection,
                selectionArgs, null, null, sortOrder);

        // notify listeners
        cursor.setNotificationUri(getContext().getContentResolver(), uri);

        return cursor;
    }


    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase sqlDB = database.getWritableDatabase();
        int rowsDeleted = 0;
        switch ( sURIMatcher.match(uri) ) {
            case COLOR:
                rowsDeleted = sqlDB.delete(ColorTable.TABLE_TASK, selection, selectionArgs);
                break;
            case COLOR_ROW:
                String id = uri.getLastPathSegment();
                if (TextUtils.isEmpty(selection)) {
                    rowsDeleted = sqlDB.delete( ColorTable.TABLE_TASK,
                            ColorTable.COLUMN_ID + "=" + id,
                            null);
                } else {
                    rowsDeleted = sqlDB.delete( ColorTable.TABLE_TASK,
                            ColorTable.COLUMN_ID + "=" + id
                                    + " and " + selection,
                            selectionArgs);
                }
                break;
            default:
                throw new IllegalArgumentException("Invalid URI: " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return rowsDeleted;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection , String[] selectionArgs) {


        SQLiteDatabase sqlDB = database.getWritableDatabase();
        int rowsUpdated = 0;
        switch ( sURIMatcher.match(uri) ) {
            case COLOR:
                rowsUpdated = sqlDB.update( ColorTable.TABLE_TASK,
                        values,
                        selection,
                        selectionArgs);
                break;
            case COLOR_ROW:
                String id = uri.getLastPathSegment();
                if (TextUtils.isEmpty(selection)) {
                    rowsUpdated = sqlDB.update( ColorTable.TABLE_TASK,
                            values,
                            ColorTable .COLUMN_ID + "=" + id,
                            null );
                } else {
                    rowsUpdated = sqlDB.update( ColorTable.TABLE_TASK,
                            values,
                            ColorTable.COLUMN_ID + "=" + id
                                    + " and " + selection,
                            selectionArgs);
                }
                break;
            default:
                throw new IllegalArgumentException("Invalid URI: " + uri);
        }

        getContext().getContentResolver().notifyChange(uri, null);
        return rowsUpdated;
    }





}

Solution

  • authorities need to have only the package name, and name is the complete package and class name.

        <provider android:name="com.example.alex.hopefulythisworks.ColorContentProvider"
            android:authorities="com.example.alex.hopefulythisworks"
            android:enabled="true"
            android:exported="true" >
        </provider>
    

    Remember that this needs to match the same that you're using to build the Uri:

     private static final String AUTHORITY = "com.example.alex.hopefulythisworks";
    

    Android docs