Android Content Provider with Multiple Tables
<p>I am using an android content provider and I have a few tables I am inserting data into. The first table has three columns and in my usecontentprovider class I display all the rows being added using a toast message at the bottom. Everything was working OK. Then I then tried to include another table which has two columns (id2, id3) and I tried to query that table and display the rows being added and whenever I do that I get an error saying Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 3 columns. I am not sure what I am doing wrong, so any help would be greatly appreciated. </p>

<pre><code>public class UseContentProvideActivity extends Activity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);



            // add the 1st course
            ContentValues values = new ContentValues();
            values.put(MyContentProvider._ID, 1510);
            values.put(MyContentProvider.NAME, "Jordan");
            values.put(MyContentProvider.GRADE, 9);
            Uri uri = getContentResolver().insert(MyContentProvider.CONTENT_URI,
                            values);


            ContentValues values2 = new ContentValues();
            values2.put(MyContentProvider._ID2, 1510);
            values2.put(MyContentProvider._ID3, 9000);
            Uri uri2 = getContentResolver().insert(MyContentProvider.CONTENT_URI2,
                            values);
            uri2 = getContentResolver().insert(
                            Uri.parse("content://cs.ecl.provider.Courses/friend"), values);




            // query added highschooler
            Toast.makeText(this, "Added Schooler:", Toast.LENGTH_SHORT).show();
            Uri allDescs = Uri.parse("content://cs.ecl.provider.Courses/highschooler");
            Cursor cl = managedQuery(allDescs, null, null, null, "name");
            if (cl.moveToFirst()) {
                    do {
                            Toast.makeText(
                                            this,
                                            cl.getString(cl.getColumnIndex(MyContentProvider._ID))
                                                            + ", "
                                                            + cl.getString(cl
                                                                            .getColumnIndex(MyContentProvider.NAME))
                                                            + ", "
                                                            + cl.getString(cl
                                                                            .getColumnIndex(MyContentProvider.GRADE)),

                                            Toast.LENGTH_LONG).show();
                    } while (cl.moveToNext());
            }


            //2nd table
            // query added friends
                            Toast.makeText(this, "Added Friend:", Toast.LENGTH_SHORT).show();
                            Uri allDescs2 = Uri.parse("content://cs.ecl.provider.Courses/friend");
                            Cursor cl2 = managedQuery(allDescs2, null, null, null, "name");
                            if (cl2.moveToFirst()) {
                                    do {
                                            Toast.makeText(
                                                            this,
                                                            cl2.getString(cl2.getColumnIndex(MyContentProvider._ID2))
                                                                            + ", "
                                                                            + cl2.getString(cl2
                                                                                            .getColumnIndex(MyContentProvider._ID3))
                                                                            ,

                                                            Toast.LENGTH_LONG).show();
                                    } while (cl2.moveToNext());
                            }

            getContentResolver().delete(
                            Uri.parse("content://cs.ecl.provider.Courses/highschooler"), null,
                            null);
    }
</code></pre>

<p>}</p>

<pre><code>public class MyContentProvider extends ContentProvider {

    public static final String PROVIDER_NAME = "cs.ecl.provider.Courses";

    // first url
    public static final Uri CONTENT_URI = Uri.parse("content://"
                    + PROVIDER_NAME + "/highschooler");

    // second url
    public static final Uri CONTENT_URI2 = Uri.parse("content://"
                    + PROVIDER_NAME + "/friend");

    // third url
    public static final Uri CONTENT_URI3 = Uri.parse("content://"
                    + PROVIDER_NAME + "/like");

    public static final String _ID = "_id";
    public static final String NAME = "name";
    public static final String GRADE = "grade";

    public static final String _ID2 = "_id1";
    public static final String _ID3 = "_id2";


    private static final int COURSES = 1;
    private static final int COURSE_ID = 2;

    // 2nd
    private static final int COURSES2 = 3;
    private static final int COURSE2_ID = 4;


    private static final UriMatcher uriMatcher;
    static {
            uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
            uriMatcher.addURI(PROVIDER_NAME, "highschooler", COURSES);
            uriMatcher.addURI(PROVIDER_NAME, "highschooler/#", COURSE_ID);

            // second table
            uriMatcher.addURI(PROVIDER_NAME, "friend", COURSES2);
            uriMatcher.addURI(PROVIDER_NAME, "friend/#", COURSE2_ID);


    }

    // for using SQLite database
    private SQLiteDatabase coursesDB;
    private static final String DATABASE_NAME = "Lab2";
    private static final String DATABASE_TABLE = "Highschooler";

    // 2nd table
    private static final String DATABASE_TABLE2 = "Friend";


    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_CREATE = "create table "
                    // + DATABASE_TABLE + " (_id integer primary key autoincrement, "
                    + DATABASE_TABLE + " (_id integer, "
                    + "name text not null, grade integer);";

    private static final String DATABASE_CREATE2 = "create table "
    // + DATABASE_TABLE + " (_id integer primary key autoincrement, "
                    + DATABASE_TABLE2 + " (_id1 integer, " + "_id2 integer);";


    // for using SQLite database
    private static class DatabaseHelper extends SQLiteOpenHelper {
            DatabaseHelper(Context context) {
                    super(context, DATABASE_NAME, null, DATABASE_VERSION);
            }

            @Override
            public void onCreate(SQLiteDatabase db) {
                    db.execSQL(DATABASE_CREATE);
                    db.execSQL(DATABASE_CREATE2);
            }

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                    db.execSQL("DROP TABLE IF EXISTS descs");
                    onCreate(db);
            }
    }

    @Override
    public int delete(Uri arg0/* uri */, String arg1/* selection */,
String[] arg2/* delectionArgs */) {
            int count = 0;
            switch (uriMatcher.match(arg0)) {
            case COURSES:
                    count = coursesDB.delete(DATABASE_TABLE, arg1, arg2);
                    break;
            case COURSE_ID:
                    String id = arg0.getPathSegments().get(1);
                    count = coursesDB.delete(DATABASE_TABLE, _ID + " = " + id
                                    + (!TextUtils.isEmpty(arg1) ? " AND (" + arg1 + ')' : ""),
                                    arg2);
                    break;
            default:
                    throw new IllegalArgumentException("Unknown URI " + arg0);
            }
            getContext().getContentResolver().notifyChange(arg0, null);
            return count;
    }

    @Override
    public String getType(Uri uri) {
            switch (uriMatcher.match(uri)) {
            // get all courses
            case COURSES:
                    return "vnd.android.cursor.dir/vnd.ecl.courses ";
                    // get one course
            case COURSE_ID:
                    return "vnd.android.cursor.item/vnd.ecl.courses ";

                    // new stuff
                    // get all courses
            case COURSES2:
                    return "vnd.android.cursor.dir/vnd.ecl.courses2 ";
                    // get one course
            case COURSE2_ID:
                    return "vnd.android.cursor.item/vnd.ecl.courses2 ";

            default:
                    throw new IllegalArgumentException("Unsupported URI: " + uri);
            }
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {

             Uri _uri = null;
                switch (uriMatcher.match(uri)){
                case  COURSES:
                    System.out.println("GOT TO INSERT1");
                    long _ID1 = coursesDB.insert(DATABASE_TABLE, "", values);
                    //---if added successfully---
                    if (_ID1 &gt; 0) {
                        _uri = ContentUris.withAppendedId(CONTENT_URI, _ID1);
                        getContext().getContentResolver().notifyChange(_uri, null);
                    }
                    break;
                case COURSES2:
                    System.out.println("GOT TO INSERT2");
                    long _ID2 = coursesDB.insert(DATABASE_TABLE2, "", values);
                    //---if added successfully---
                    if (_ID2 &gt; 0) {
                        _uri = ContentUris.withAppendedId(CONTENT_URI2, _ID2);
                        getContext().getContentResolver().notifyChange(_uri, null);
                    }
                    break;
                default: throw new SQLException("Failed to insert row into " + uri);
                }
                return _uri;
            }

    @Override
    public boolean onCreate() {
            Context context = getContext();
            DatabaseHelper dbHelper = new DatabaseHelper(context);
            coursesDB = dbHelper.getWritableDatabase();
            return (coursesDB == null) ? false : true;

    }

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

            SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
            sqlBuilder.setTables(DATABASE_TABLE);

            if (uriMatcher.match(uri) == COURSE_ID)
                    // -- if getting one course --
                    sqlBuilder.appendWhere(_ID + " = " + uri.getPathSegments().get(1));

            if (sortOrder == null || sortOrder == "")
                    sortOrder = NAME;

            Cursor cl = sqlBuilder.query(coursesDB, projection, selection,
                            selectionArgs, null, null, sortOrder);

            // register to watch a content URI for changes
            cl.setNotificationUri(getContext().getContentResolver(), uri);
            return cl;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                    String[] selectionArgs) {
            int count = 0;
            switch (uriMatcher.match(uri)) {
            case COURSES:
                    count = coursesDB.update(DATABASE_TABLE, values, selection,
                                    selectionArgs);
                    break;
            case COURSE_ID:
                    count = coursesDB.update(
                                    DATABASE_TABLE,
                                    values,
                                    _ID
                                                    + " = "
                                                    + uri.getPathSegments().get(1)
                                                    + (!TextUtils.isEmpty(selection) ? " AND ("
                                                                    + selection + ')' : ""), selectionArgs);
                    break;
            default:
                    throw new IllegalArgumentException("Unknown URI " + uri);
            }
            getContext().getContentResolver().notifyChange(uri, null);
            return count;
    }
}
</code></pre>
