0

私はAndroidコンテンツプロバイダーを使用しており、データを挿入するテーブルがいくつかあります。最初のテーブルには3つの列があり、usecontentproviderクラスでは、下部にトーストメッセージを使用して追加されているすべての行を表示します。すべてが正常に機能していました。次に、2つの列(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。これは、Uri を で終了するときの UriMatcher コードです/friend。したがって、高校生のテーブルを調べようとしており、そのテーブルに無効な列名を指定しています(これが「列-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_TABLEコードに関するもう 1 つの注意事項: 変数を and DATABASE_TABLE2、またはCOURSESandよりもわかりやすいものにするようにしてくださいCOURSES2。記述変数を使用すると、特にコードが大きくなるにつれて、覚えやすくなります (私は現在 843 行の ContentProvider を使用していますが、まだ大きくなっています)。

私が言ったように、私は ContentProviders を初めて使用するので、コードを改善するために他にできることをいくつか見逃している可能性がありますが、私が提供した解決策は、コードを機能させるのに十分であるはずです.

于 2013-06-14T15:13:16.670 に答える