Я получаю следующую ошибку от CursorAdapter. Убедитесь, что курсор инициализирован правильно, прежде чем получить доступ к данным из него - PullRequest
0 голосов
/ 24 октября 2018

My Binder Class

public void bindView(View view, Context context, Cursor cursor) {


            mTitleText = (TextView) view.findViewById(R.id.recycle_title);
            mDateAndTimeText = (TextView) view.findViewById(R.id.recycle_date_time);
            mRepeatInfoText = (TextView)view.findViewById(R.id.recycle_repeat_info);
            mActiveImage = (ImageView) view.findViewById(R.id.active_image);
            mThumbnailImage = (ImageView) view.findViewById(R.id.thumbnail_image);

           int titleColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_TITLE);
            int dateColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_DATE);
            int timeColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_TIME);
            int repeatColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT);
            int repeatNoColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_NO);
            int repeatTypeColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_TYPE);
            int activeColumnIndex = cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_ACTIVE);
            int locationColumnIndex= cursor.getColumnIndex(AlarmReminderContract.AlarmReminderEntry.KEY_LOCATION);

            String title = cursor.getString(titleColumnIndex);
            String date = cursor.getString(dateColumnIndex);
            String time = cursor.getString(timeColumnIndex);
            String repeat = cursor.getString(repeatColumnIndex);
            String repeatNo = cursor.getString(repeatNoColumnIndex);
            String repeatType = cursor.getString(repeatTypeColumnIndex);
            String active = cursor.getString(locationColumnIndex);
            String loc = cursor.getString(activeLocation);
            String dateTime = date + " " + time;
            Log.e("msg_fa", loc);
            if (loc.equals(false)) {
                setReminderTitle(title);
                setReminderDateTime(dateTime);
                setReminderRepeatInfo(repeat, repeatNo, repeatType);
                setActiveImage(active);

            } else
            {
                setReminderTitle(title);
                setReminderDateTime("Place");
            }

    }

My Logcat Error

         E/CursorWindow: Failed to read row 0, column 8 from a CursorWindow which has 1 rows, 8 columns.
            2018-10-24 19:54:06.958 11109-11109/? E/AndroidRuntime: FATAL EXCEPTION: main
                Process:PID: 11109
                java.lang.IllegalStateException: Couldn't read row 0, col 8 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it.

Я могу получить доступ к столбцу данных данныхIndex 7, но не могу получить индексот 8

Код для моей базы данных HELPER

         public void onCreate(SQLiteDatabase sqLiteDatabase) {
            // Create a String that contains the SQL statement to create the reminder table
            String SQL_CREATE_ALARM_TABLE =  "CREATE TABLE " + AlarmReminderContract.AlarmReminderEntry.TABLE_NAME + " ("
                    + AlarmReminderContract.AlarmReminderEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_TITLE + " TEXT NOT NULL, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_DATE + " TEXT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_TIME + " TEXT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT + " TEXT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_NO + " TEXT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_TYPE + " TEXT, "
                    + AlarmReminderContract.AlarmReminderEntry.KEY_ACTIVE + " TEXT,"
                    +AlarmReminderContract.AlarmReminderEntry.KEY_LOCATION + " TEXT,"
                    + AlarmReminderContract.AlarmReminderEntry.latitude+" TEXT ,"
                    + AlarmReminderContract.AlarmReminderEntry.longitude+" TEXT" +" );";

            // Execute the SQL statement
            sqLiteDatabase.execSQL(SQL_CREATE_ALARM_TABLE);

Вставка в базу данных работает отлично, но эта проблема возникает, когда я прошу выбратьданные из восьмого индекса

Основная проблема, с которой я сталкиваюсь, заключается в том, что при попытке получить значение из индекса KEY_LOCATION происходит сбой приложения, а затем выдается ошибка, отображаемая вlogcat Я получаю значение до столбца 7 Я попытался обновить версию базы данных и изменить имя таблицы и имя базы данных, так как это не сработало, как ожидалось.

Вот мой класс провайдеров

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                        String sortOrder) {
        SQLiteDatabase database = mDbHelper.getReadableDatabase();

        // This cursor will hold the result of the query
        Cursor cursor = null;

        int match = sUriMatcher.match(uri);
        switch (match) {
            case REMINDER:
                cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, projection, selection, selectionArgs,
                        null, null, sortOrder);
                Log.i("msg","Reminder Invoked");
                break;
            case REMINDER_ID:
                selection = AlarmReminderContract.AlarmReminderEntry._ID + "=?";
                selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };


                cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, projection, selection, selectionArgs,
                        null, null, sortOrder);
                break;
            default:
                throw new IllegalArgumentException("Cannot query unknown URI " + uri);
        }

1 Ответ

0 голосов
/ 25 октября 2018

Проблема в том, что у Курсора есть только 8 (смещения 0-7) из 11 (смещений 0-10) столбцов в таблице.Следовательно, сообщение о том, что ему не удалось прочитать строку 0 (первая строка), столбец 8 (9-й столбец (местоположение)).

Курсор будет содержать только те столбцы, которые вы указали неявно или явно (SELECT *)подразумевает все столбцы, ноль в качестве второго параметра в методе запроса SQLIteDatabase приравнивается к SELECT * и, следовательно, подразумевает все столбцы).Это независимо от столбцов в базовой таблице или таблицах.

Может показаться, что массив String, переданный классу поставщика в качестве 2-го параметра (проекция), только явно указывает 8 столбцов.

Быстрое исправление (хотя и наиболее гибкое) заключается в использовании null вставка проекция в качестве второго параметра при вызове метода SQLiteDatabase query .

Таким образом, вместо: -

database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, projection, selection, selectionArgs,
                    null, null, sortOrder);

Вы можете использовать: -

database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, null, selection, selectionArgs,
                    null, null, sortOrder);

Таким образом, весь метод запроса может быть: -

public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                    String sortOrder) {
    SQLiteDatabase database = mDbHelper.getReadableDatabase();

    // This cursor will hold the result of the query
    Cursor cursor = null;

    int match = sUriMatcher.match(uri);
    switch (match) {
        case REMINDER:
            cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, 
                    null, //<<<<<<<<<< CHANGED 
                    selection, 
                    selectionArgs,
                    null, null, sortOrder);
            Log.i("msg","Reminder Invoked");
            break;
        case REMINDER_ID:
            selection = AlarmReminderContract.AlarmReminderEntry._ID + "=?";
            selectionArgs = new String[] { String.valueOf(ContentUris.parseId(uri)) };


            cursor = database.query(AlarmReminderContract.AlarmReminderEntry.TABLE_NAME, 
                    null, //<<<<<<<<<< CHANGED 
                    selection, 
                    selectionArgs,
                    null, null, sortOrder);
            break;
        default:
            throw new IllegalArgumentException("Cannot query unknown URI " + uri);
    }
}
  • Обратите внимание, что второй параметр String[] projection, переданный методу, будет избыточным.

Альтернативой может быть изменение вызова метода класса класса поставщика.(как указано выше), чтобы передаваемый массив String включал дополнительные столбцы при вызове метода query класса провайдера.

например,

String[] projection_columns = new String[]{
    AlarmReminderContract.AlarmReminderEntry._ID,
    AlarmReminderContract.AlarmReminderEntry.KEY_TITLE,
    AlarmReminderContract.AlarmReminderEntry.KEY_DATE,
    AlarmReminderContract.AlarmReminderEntry.KEY_TIME,
    AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT,
    AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_NO,
    AlarmReminderContract.AlarmReminderEntry.KEY_REPEAT_TYPE,
    AlarmReminderContract.AlarmReminderEntry.KEY_LOCATION,
    AlarmReminderContract.AlarmReminderEntry.KEY_ACTIVE,
    AlarmReminderContract.AlarmReminderEntry.latitude,
    AlarmReminderContract.AlarmReminderEntry.longitude
}

your_provider.query(your_uri, project_columns,your_selection, your_selectionargs, you_sortorder);
...