Курсор базы данных SQLite возвращает неправильные идентификаторы ресурса - PullRequest
3 голосов
/ 14 мая 2019

Я пытаюсь использовать ссылки на ресурсы для рисования и String из базы данных SQLite для отображения соответствующих ресурсов во фрагменте. У меня есть вспомогательный файл базы данных для заполнения базы данных, файл утилит базы данных для создания курсора (или просто получения данных курсора в массиве) и файл фрагмента.

    DatabaseHelper.java
    DatabaseHelper(Context context) {
            super(context, DB_NAME, null, DB_VERSION);
        }

        private void updateMyDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
            if (oldVersion == 1) {
                db.execSQL("CREATE TABLE FOOD (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                        + "NAME TEXT, "
                        + "IMAGE_RESOURCE_ID INTEGER, "
                        + "QUOTE INTEGER);");

                insertFood(db,"Alcohol", R.drawable.alcohol, R.string.symptom9);
}

private static void insertFood(SQLiteDatabase db, String name, int toxicity, int resourceId, int quote){
        ContentValues foodValues = new ContentValues();
        foodValues.put("NAME", name);
        foodValues.put("TOXICITY", toxicity);
        foodValues.put("IMAGE_RESOURCE_ID", resourceId);
        foodValues.put("QUOTE", quote);
        db.insert("FOOD", null, foodValues);
    }
}

Здесь R.drawable.alcohol = 2131099733

Я использую Android Studio и при наведении указателя мыши на значения, которые добавляю в базу данных, и отображаю чертеж с использованием одного из этих значений, он отображается правильно, но когда я запрашиваю курсор (или массив на основе курсор), значение, которое включает курсор, полностью отличается от значения, хранящегося в базе данных, и приводит к ошибке «ресурс не найден».

Я попытался вернуть массив данных из вспомогательного метода, но он также дал неверные целочисленные ссылки для рисованных объектов и строк, поэтому вместо этого я возвращаю курсор из вспомогательного метода:

DatabaseUtilities.java
//get all of the database data for a particular food given that food's name
    public static Cursor getFoodById(Context context, long itemId){

        try {
            SQLiteOpenHelper DatabaseHelper = new DatabaseHelper(context);
            SQLiteDatabase db = DatabaseHelper.getReadableDatabase();
            return db.query(DatabaseHelper.FOOD,
                    new String[]{
                            DatabaseHelper.NAME, DatabaseHelper.IMAGE_RESOURCE_ID,
                            DatabaseHelper.QUOTE},
                    "_id = ?", new String[] {Long.toString(itemId)}, null, null, null
            );

        } catch (SQLiteException e) {
            //TODO Add toast - food not available
            return null;
        }
    }

Наконец, я пытаюсь отобразить значения здесь:

DetailFragment.java
 @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        Cursor items = DatabaseUtilities.getFoodById(getActivity(), itemId);
        if(items.moveToFirst()) {    
            //set appropriate img
            int img = items.getInt(1);
            ImageView photo = (ImageView) view.getRootView().findViewById(R.id.detail_photo);
            photo.setImageResource(img);

            int quote = items.getInt(2);
            TextView desc = (TextView) view.getRootView().findViewById(R.id.detail_text);
            String descText = getString(quote);
            desc.setText(descText);
        }
    }

Это вывод журнала всех столбцов курсора из последнего файла:

DetailFragment - cursor: Alcohol, 2131165269, 2131558463

Значение после Alcohol должно быть R.drawable.alcohol, 2131099733, но вместо этого курсор возвращает 2131165269. То же самое в случае со ссылкой на строку после ссылки для рисования. Кроме того, курсор возвращает разные значения для каждой вставленной строки, это просто неправильные значения, и я не знаю, откуда они берутся или есть ли способ преобразовать их в правильные значения.

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

1 Ответ

4 голосов
/ 14 мая 2019

Не храните в таблице целочисленные идентификаторы ресурсов.
Их значения не обязательно будут одинаковыми каждый раз, когда вы вносите изменения в ресурсы и перекомпилируете свой проект.
Вместо этого сохраняйте идентификаторы ресурсов как строковые литералы.
Поэтому измените определение таблицы на:

CREATE TABLE FOOD (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
                    + "NAME TEXT, "
                    + "IMAGE_RESOURCE_ID TEXT, "
                    + "QUOTE TEXT);

Теперь сохраните в столбцах IMAGE_RESOURCE_ID и QUOTE идентификаторы строк.
Когда вы извлекаете такой строковый идентификатор из таблицы с помощью курсора, вы можете получить его целочисленный идентификатор следующим образом:

int drawableId = getResources().getIdentifier(drawableString, "drawable", getPackageName());
int stringId = getResources().getIdentifier(stringString, "string", getPackageName()); 

Возможно, вам потребуется указать действительные значения Context до getResources() и getPackageName(), например:

context.getResources().getIdentifier(drawableString, "drawable", context.getPackageName());

Замените drawableString и stringString на значения, которые вы извлекли из таблицы для изображения и строки.
Если вы внесете предложенные выше изменения в определение таблицы, вы должны удалить приложение из устройства / эмулятора и повторно запустить, чтобы база данных была удалена и воссоздана с новым определением таблицы.

...