0

我正在使用一个 android 内容提供程序,并且我有一些要插入数据的表。第一个表有三列,在我的 usecontentprovider 类中,我使用底部的 toast 消息显示正在添加的所有行。一切正常。然后我尝试包含另一个具有两列(id2,id3)的表,我尝试查询该表并显示正在添加的行,每当我这样做时,我都会收到一条错误消息,提示无法读取第 0 行,第 -1 列一个有 1 行 3 列的 CursorWindow。我不确定我做错了什么,所以任何帮助将不胜感激。

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);
    }

}

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 > 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 > 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;
    }
}
4

1 回答 1

1

当然,我对 ContentProviders 很陌生(本周才开始学习它们),但我认为您的问题就在这里:

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

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

您将表设置为DATABASE_TABLE,而不是使用开关来捕获 的出现COURSES2,这是您的 UriMatcher 代码,用于当您以 结束 Uri 时/friend。因此,它试图查看您的 Highschoolers 表,并且您为该表提供了无效的列名(我认为这就是它无法读取“列 -1”的原因)。

所以这里是你如何让它引用 Friends 表:

 public Cursor query(Uri uri, String[] projection, String selection,
                String[] selectionArgs, String sortOrder) {
     SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
     switch(uriMatcher.match(uri)){
         case COURSE_ID:
             // -- if getting one course --
             sqlBuilder.setTables(DATABASE_TABLE);
             sqlBuilder.appendWhere(_ID + " = " + uri.getPathSegments().get(1));
             break;
         case COURSES2
             sqlBuilder.setTables(DATABASE_TABLE2);
             break;
         default:
             throw new IllegalArgumentException("Bad Uri");
    }

关于您的代码的另一个注意事项:尝试使您的变量比DATABASE_TABLEand DATABASE_TABLE2, or COURSESand更具描述性COURSES2。使用描述性变量使事情更容易记住,尤其是随着代码的增长(我目前使用的是 843 行的 ContentProvider,而且它还在增长)。

就像我说的,我是 ContentProviders 的新手,所以我可能遗漏了你可以做的一些其他事情来改进你的代码,但我提供的解决方案应该足以让你的代码正常工作。

于 2013-06-14T15:13:16.670 回答