title: How to fix content provider url not found in android Content provider?
body: <p>I have followed the below tutorial <strong><a href="http://www.vogella.de/articles/AndroidSQLite/article.htm" rel="noreferrer">http://www.vogella.de/articles/AndroidSQLite/article.htm</a></strong> </p>
  
  <p>But getting this exception after clicking on "confirm" button</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>TodoDetailActivity</p>
  
  <pre><code>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 &lt; 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 &amp;&amp; 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();
      }
  }
  </code></pre>
  
  <p>MyTodoContentProvider</p>
  
  <pre><code>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&lt;String&gt; requestedColumns = new HashSet&lt;String&gt;(Arrays.asList(projection));
           HashSet&lt;String&gt; availableColumns = new HashSet&lt;String&gt;(Arrays.asList(available));
           if(projection != null)
           {
               if (!availableColumns.containsAll(requestedColumns)) {
                  throw new IllegalArgumentException("Unknown columns in projection");
                }
           }
  
       }
  }
  </code></pre>
  
  <p>TodoDatabaseHelper</p>
  
  <pre><code>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);
        }
  
  
  }
  </code></pre>