Хранение новых данных о погоде в городе и обновление существующих данных о погоде в базе данных Android SQLITE

#java #android #json #sqlite #openweathermap

#java #Android #json #sqlite #openweathermap

Вопрос:

Я использую OpenWeatherMap API для извлечения текущих данных о погоде в формате JSON.

Следующие данные являются примером:

 {"coord":{"lon":-83.05,"lat":42.33},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"base":"stations","main":{"temp":48.1,"pressure":1004.19,"humidity":100,"temp_min":48.1,"temp_max":48.1,"sea_level":1028.21,"grnd_level":1004.19},"wind":{"speed":15.23,"deg":315.508},"clouds":{"all":0},"dt":1477154497,"sys":{"message":0.1743,"country":"US","sunrise":1477137281,"sunset":1477175856},"id":4990729,"name":"Detroit","cod":200}
{"coord":{"lon":-87.65,"lat":41.85},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03d"}],"base":"stations","main":{"temp":51.38,"pressure":1009.38,"humidity":100,"temp_min":51.38,"temp_max":51.38,"sea_level":1031.85,"grnd_level":1009.38},"wind":{"speed":8.08,"deg":227.508},"clouds":{"all":48},"dt":1477154834,"sys":{"message":0.1714,"country":"US","sunrise":1477138345,"sunset":1477177000},"id":4887398,"name":"Chicago","cod":200}
{"coord":{"lon":-74.01,"lat":40.71},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"base":"stations","main":{"temp":48.14,"pressure":1008,"humidity":100,"temp_min":48.14,"temp_max":48.14,"sea_level":1011.38,"grnd_level":1008},"wind":{"speed":15.46,"deg":296.508},"rain":{"3h":2.2},"clouds":{"all":80},"dt":1477154848,"sys":{"message":0.1842,"country":"US","sunrise":1477134973,"sunset":1477173827},"id":5128581,"name":"New York","cod":200}
  

В качестве «фиктивных записей», которые могут быть удалены в любое время по выбору пользователя, эти три города вставляются в Create() (хотя теперь я понимаю, почему это может быть плохой идеей)

Я намерен обновить эти три фиктивные записи onCreate () или onResume () без создания самих новых записей, которые затем добавляются в ListView.

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

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

Но я совершенно невежественен и с чего начать «проверку». Вот мой метод вставки:

  public void insertRow(CustomListData weather){
    SQLiteDatabase db = this.getWritableDatabase();
        ContentValues insertValues = new ContentValues();
        insertValues.put("TEMP", weather.getTemperature());
        insertValues.put("CITYNAME", weather.getCity());
        insertValues.put("ZIP", weather.getZip());
        db.insert("weather_data", null, insertValues);
        db.close();
}
  

Редактировать:

СХЕМА:

 CREATE TABLE weather_data(_id INTEGER PRIMARY KEY AUTOINCREMENT, TEMP VARCHAR(5), CITYNAME VARCHAR(255), ZIP VARCHAR(6) );
  

ВТОРОЕ РЕДАКТИРОВАНИЕ:

WeatherDataStorage — вспомогательный класс

Комментарии:

1. пожалуйста, опубликуйте схему вашей таблицы «weather_data». Тогда я смогу предложить вам подходящее решение на основе этого.

2. Редактирование было произведено.

3. Как вы можете видеть из этого руководства androidhive.info/2011/11/android-sqlite-database-tutorial вам необходимо создать помощник sqlite, который может выполнять такие операции, как чтение, вставка, удаление, обновление и т.д. в базе данных. Когда дело доходит до обновления или удаления записи в руководстве, в качестве поля для идентификации строки используется id. Вам нужно изменить это на name, чтобы вместо этого использовалось название города.

4. Скажите, записи в вашей таблице должны иметь ZIP как уникальный. Я полагаю, вы имеете в виду почтовый индекс города. ЯВЛЯЕТСЯ ЛИ ПОЧТОВЫЙ ИНДЕКС УНИКАЛЬНЫМ ДЛЯ ВСЕХ ЗАПИСЕЙ???

5. В предыдущей схеме это было. Я столкнулся с ошибками из-за того, что они были добавлены onCreate (), и я не добавил их снова. Но я понимаю, что вы говорите о наличии уникального поля zip

Ответ №1:

Если вам нужно проверить, существует ли запись в таблице, самый быстрый способ сделать это — проверить этот способ (предполагая, что почтовый индекс уникален во всех записях) :

      public static boolean checkIfRecordExists(Context context, String tableName, 
                                String tableAttribute, String attributeValue) {

            Cursor cursor = context.getContentResolver().query(tableName,
            new String[]{"1"},
            tableAttribute   "=?,
            new String[]{attributeValue},
            null);

            boolean recordExists = (cursor !=null amp;amp; cursor.getCount() > 0);
            cursor.close();

            return recordExists;
     }
  

Таким образом, вы можете вызвать этот метод, чтобы проверить, существует ли запись в вашей таблице «weather_data».

 public void insertRow(CustomListData weather){
SQLiteDatabase db = this.getWritableDatabase();

//(Context context, String tableName, String tableAttribute, String attributeValue) 

    boolean recordExists = checkIfRecordExists(context, "weather_data", "ZIP", weather.getZip());

    if(!recordExists) {
        ContentValues insertValues = new ContentValues();
        insertValues.put("TEMP", weather.getTemperature());
        insertValues.put("CITYNAME", weather.getCity());
        insertValues.put("ZIP", weather.getZip());
        db.insert("weather_data", null, insertValues);
        db.close();
    }
}
  

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

Следовательно, при вызове служебного метода checkIfRecordExists с этими параметрами checkIfRecordExists(контекст, «weather_data», «ZIP», «DUMMY_ZIP_1234»),

Запрос преобразуется в ВЫБЕРИТЕ 1 ИЗ weather_data, ГДЕ ZIP = «DUMMY_ZIP_1234»

Вы запускаете запрос select, сохраняете результаты в курсоре и проверяете, содержит ли курсор какие-либо записи. Если курсор содержит некоторые записи, то это означает, что запись уже существует.

PS: если почтовый индекс уникален, пожалуйста, используйте почтовый индекс в качестве первичного ключа

Комментарии:

1. В каком контексте я должен передавать checkIfRecordExist()

2. Попробуйте эту программу один раз в своем коде. Все действия расширяют контекст. Я только что создал общий метод утилиты. Если вы используете этот код внутри действия, вызовите это: checkIfRecordExists(это, «weather_data», «ZIP», «DUMMY_ZIP_1234»). Это относится к действию. Если вы используете фрагмент, то используйте этот checkIfRecordExists(getActivity(), «weather_data», «ZIP», «DUMMY_ZIP_1234»),

3. Если этот ответ помог вам, пожалуйста, поддержите ответ и пометьте его как правильный. 🙂 Мы тратим много нашего времени на прояснение сомнений и публикацию наших ответов.

4. Я смог реализовать ваши предложения, однако я все еще получаю повторяющиеся записи при каждом новом создании приложения