Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix content provider url not found in android Content provider?

I have followed the below tutorial http://www.vogella.de/articles/AndroidSQLite/article.htm

But getting this exception after clicking on "confirm" button

01-20 10:18:14.585: E/AndroidRuntime(2006): Caused by: java.lang.IllegalArgumentException: Unknown URL content://com.example.todos.contentprovider/todos
01-20 10:18:14.585: E/AndroidRuntime(2006):     at android.content.ContentResolver.insert(ContentResolver.java:910)
01-20 10:18:14.585: E/AndroidRuntime(2006):     at com.example.todos.TodoDetailActivity.saveState(TodoDetailActivity.java:122)
01-20 10:18:14.585: E/AndroidRuntime(2006):     at com.example.todos.TodoDetailActivity.onPause(TodoDetailActivity.java:100)

TodoDetailActivity

public class TodoDetailActivity extends Activity {

    private Spinner mCategory;
    private EditText mTitleText;
    private EditText mBodyText;

    private Uri todoUri;

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setContentView(R.layout.todo_edit);

        mCategory = (Spinner) findViewById(R.id.category);
        mTitleText = (EditText) findViewById(R.id.todo_edit_summary);
        mBodyText = (EditText) findViewById(R.id.todo_edit_description);
        Button confirmButton = (Button) findViewById(R.id.todo_edit_button);

        Bundle extras = getIntent().getExtras();

        // check from the saved Instance
        todoUri = (bundle == null) ? null : (Uri) bundle
                .getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);

        // Or passed from the other activity
        if (extras != null) {
            todoUri = extras
                    .getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);

            fillData(todoUri);
        }

        confirmButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                if (TextUtils.isEmpty(mTitleText.getText().toString())) {
                    makeToast();
                } else {
                    setResult(RESULT_OK);
                    finish();
                }
            }

        });
    }

    private void fillData(Uri uri) {
        String[] projection = { TodoTable.COLUMN_SUMMARY,
                TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY };
        Cursor cursor = getContentResolver().query(uri, projection, null, null,
                null);
        if (cursor != null) {
            cursor.moveToFirst();
            String category = cursor.getString(cursor
                    .getColumnIndexOrThrow(TodoTable.COLUMN_CATEGORY));

            for (int i = 0; i < mCategory.getCount(); i++) {

                String s = (String) mCategory.getItemAtPosition(i);
                if (s.equalsIgnoreCase(category)) {
                    mCategory.setSelection(i);
                }
            }

            mTitleText.setText(cursor.getString(cursor
                    .getColumnIndexOrThrow(TodoTable.COLUMN_SUMMARY)));
            mBodyText.setText(cursor.getString(cursor
                    .getColumnIndexOrThrow(TodoTable.COLUMN_DESCRIPTION)));

            // always close the cursor
            cursor.close();
        }
    }

    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        saveState();
        outState.putParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
    }

    @Override
    protected void onPause() {
        super.onPause();
        saveState();
    }

    private void saveState() {
        String category = (String) mCategory.getSelectedItem();
        String summary = mTitleText.getText().toString();
        String description = mBodyText.getText().toString();

        // only save if either summary or description
        // is available

        if (description.length() == 0 && summary.length() == 0) {
            return;
        }

        ContentValues values = new ContentValues();
        values.put(TodoTable.COLUMN_CATEGORY, category);
        values.put(TodoTable.COLUMN_SUMMARY, summary);
        values.put(TodoTable.COLUMN_DESCRIPTION, description);

        if (todoUri == null) {
            // New todo
            todoUri = getContentResolver().insert(
                    MyTodoContentProvider.CONTENT_URI, values);
        } else {
            // Update todo
            getContentResolver().update(todoUri, values, null, null);
        }
    }

    private void makeToast() {
        Toast.makeText(TodoDetailActivity.this, "Please maintain a summary",
                Toast.LENGTH_LONG).show();
    }
}

MyTodoContentProvider

public class MyTodoContentProvider extends ContentProvider{

    //database
    private TodoDatabaseHelper database;

    //Used for the uriMatcher
    private static final int TODOS = 10;
    private static final int TODO_ID = 20;


    private static final String AUTHORITY =  "com.example.todos.contentprovider";
    private static final String BASE_PATH = "todos";
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY+ "/" + BASE_PATH);

    public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE +"/todos";

    public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/todo";

     private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    static {
        sURIMatcher.addURI(AUTHORITY, BASE_PATH, TODOS);
        sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", TODO_ID);
    }

    @Override
    public boolean onCreate()
    {
        database = new TodoDatabaseHelper(getContext());
        return false;
    }

    @Override
    public Cursor query(Uri uri,String[] projection, String selection,
              String[] selectionArgs, String sortOrder)
    {
        // Uisng SQLiteQueryBuilder instead of query() method
        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

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

        //set the table
        queryBuilder.setTables(TodoTable.TABLE_TODO);

        int uriType = sURIMatcher.match(uri);
        switch (uriType) {
        case TODOS:
            break;

        case TODO_ID:
             // adding the ID to the original query
             queryBuilder.appendWhere(TodoTable.COLUMN_ID + "="
                      + uri.getLastPathSegment());
            break;

        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }
        SQLiteDatabase db = database.getWritableDatabase();
        Cursor cursor = queryBuilder.query(db, projection, selection,
                selectionArgs, null, null, sortOrder);

     // make sure that potential listeners are getting notified
        cursor.setNotificationUri(getContext().getContentResolver(), uri);

        return cursor;

    }

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

     @Override
      public Uri insert(Uri uri, ContentValues values)
     {
         int uriType = sURIMatcher.match(uri);
         SQLiteDatabase sqlDB = database.getWritableDatabase();
         long id = 0;
         switch (uriType) {
        case TODOS:
            id =  sqlDB.insert(TodoTable.TABLE_TODO, null, values);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }
         getContext().getContentResolver().notifyChange(uri, null);
          return Uri.parse(BASE_PATH + "/" + id);
     }

     @Override
     public int delete(Uri uri, String selection,String[] selectionArgs)
     {
         int uriType = sURIMatcher.match(uri);
         SQLiteDatabase sqlDB  = database.getWritableDatabase();
         int rowsDeleted = 0;
         switch (uriType) {

        case TODOS:
            rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,selection, selectionArgs);
            break;

        case TODO_ID:
            String id = uri.getLastPathSegment();
            if(TextUtils.isEmpty(selection))
            {
                rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,TodoTable.COLUMN_ID + "=" + id,null);
            }
            else
            {
                rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,TodoTable.COLUMN_ID + "=" + id + "and" + selection ,selectionArgs);
            }

        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }
         getContext().getContentResolver().notifyChange(uri, null);
        return rowsDeleted;
     }

     @Override
     public int update(Uri uri,ContentValues values,String selection,String[] selectionArgs)
     {
         int uriType = sURIMatcher.match(uri);
         SQLiteDatabase sqlDb = database.getWritableDatabase();
         int rowsUpdated = 0;
         switch (uriType) {
        case TODOS:
            rowsUpdated = sqlDb.update(TodoTable.TABLE_TODO, values, selection, selectionArgs);
            break;
        case TODO_ID:
            String id = uri.getLastPathSegment();
            if(TextUtils.isEmpty(selection))
            {
                rowsUpdated = sqlDb.update(TodoTable.TABLE_TODO, values, TodoTable.COLUMN_ID + "=" +  id, null);
            }
            else
            {
                rowsUpdated = sqlDb.update(TodoTable.TABLE_TODO, values, TodoTable.COLUMN_ID + "=" + id + "and" + selection, selectionArgs);
            }
            break;
        default:
            throw new IllegalArgumentException("Unknown URI: " + uri);
        }
         getContext().getContentResolver().notifyChange(uri, null);
         return rowsUpdated;
     }


     private void checkColumns(String[] projection)
     {
         String[] available = {TodoTable.COLUMN_CATEGORY,TodoTable.COLUMN_SUMMARY,TodoTable.COLUMN_DESCRIPTION,TodoTable.COLUMN_ID};
         HashSet<String> requestedColumns = new HashSet<String>(Arrays.asList(projection));
         HashSet<String> availableColumns = new HashSet<String>(Arrays.asList(available));
         if(projection != null)
         {
             if (!availableColumns.containsAll(requestedColumns)) {
                throw new IllegalArgumentException("Unknown columns in projection");
              }
         }

     }
}

TodoDatabaseHelper

public class TodoDatabaseHelper extends SQLiteOpenHelper{

    private static final String DATABASE_NAME = "todotable.db";
    private static final int DATABASE_VERSION = 1;


    public TodoDatabaseHelper(Context context)
    {
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
    }

    //Method is called during creation of database
    @Override
    public void onCreate(SQLiteDatabase database)
    {
        TodoTable.onCreate(database);
    }

    // Method is called during an upgrade of the database,
      // e.g. if you increase the database version
      @Override
      public void onUpgrade(SQLiteDatabase database, int oldVersion,
          int newVersion) {
        TodoTable.onUpgrade(database, oldVersion, newVersion);
      }


}
like image 244
venu Avatar asked Jan 20 '14 04:01

venu


People also ask

What is content URL in Android?

A content URI is a URI that identifies data in a provider. Content URIs include the symbolic name of the entire provider (its authority) and a name that points to a table (a path). When you call a client method to access a table in a provider, the content URI for the table is one of the arguments.

How do I access my content provider?

To access the content, define a content provider URI address. Create a database to store the application data. Implement the six abstract methods of ContentProvider class. Register the content provider in AndroidManifest.

Why do we need content provider in Android?

Content providers can help an application manage access to data stored by itself, stored by other apps, and provide a way to share data with other apps. They encapsulate the data, and provide mechanisms for defining data security.


2 Answers

You are using

private static final String AUTHORITY =  "com.example.todos.contentprovider";
// It should same as you defined in manifest

So this

Caused by: java.lang.IllegalArgumentException: Unknown URL content://com.example.todos.contentprovider/todos 

So make sure you define your ContentProvider with same authority in manifest.xml

<provider
       android:authorities="com.example.todos.contentprovider"
       android:name=".YOUR_ContentProvider" >
</provider> 

Hope this will work for you.

like image 189
Amit Gupta Avatar answered Oct 02 '22 09:10

Amit Gupta


Also ensure that you give android:exported="true" in manifest.xml, also ensure they are placed inside </application> not inside </activity>.

<provider
        android:name="com.example.todos.contentprovider"
        android:authorities="com.example.todos.contentprovider.MyTodoContentProvider"
        android:exported="true">
    </provider>
like image 23
Ajay Deepak Avatar answered Oct 02 '22 07:10

Ajay Deepak