From 3c0c9ba2e6b37b9e935d3dbba207105e0fd54fdc Mon Sep 17 00:00:00 2001 From: David Katrinka Date: Sat, 5 Jul 2025 17:54:24 +0200 Subject: [PATCH] added sqlite to app --- .../example/airquality/FavoritesActivity.java | 36 ++- .../com/example/airquality/MainActivity.java | 22 +- .../airquality/SearchCityActivity.java | 5 +- .../airquality/utils/DatabaseHelper.java | 213 ++++++++++++++++++ .../airquality/utils/PreferencesManager.java | 2 +- 5 files changed, 263 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/com/example/airquality/utils/DatabaseHelper.java diff --git a/app/src/main/java/com/example/airquality/FavoritesActivity.java b/app/src/main/java/com/example/airquality/FavoritesActivity.java index 45c5485..1bf8f91 100644 --- a/app/src/main/java/com/example/airquality/FavoritesActivity.java +++ b/app/src/main/java/com/example/airquality/FavoritesActivity.java @@ -16,6 +16,7 @@ import com.example.airquality.databinding.ActivityFavoritesBinding; import com.example.airquality.types.City; import com.example.airquality.utils.BaseCompatActivity; import com.example.airquality.utils.CityAdapter; +import com.example.airquality.utils.DatabaseHelper; import com.example.airquality.utils.PreferencesManager; import com.example.airquality.utils.Weather3hAdapter; @@ -49,19 +50,34 @@ public class FavoritesActivity extends BaseCompatActivity { } private City[] getFavoriteList() { - // Get from db - City[] cities = new City[] { - new City("Belgrade", "RS", 44.7866, 20.4489, "2025-07-04 12:30"), - new City("Novi Sad", "RS", 45.2671, 19.8335, "2025-07-03 09:15"), - new City("Niš", "RS", 43.3209, 21.8958, "2025-07-02 18:45"), - new City("Subotica", "RS", 46.1000, 19.6667, "2025-07-01 14:10"), - new City("Kragujevac", "RS", 44.0128, 20.9110, "2025-06-30 07:50") - }; + DatabaseHelper dbHelper = new DatabaseHelper(this); + List cityList = dbHelper.getAllCities(); + return cityList.toArray(new City[0]); - return cities; +// City[] cities = new City[] { +// new City("Belgrade", "RS", 44.7866, 20.4489, "2025-07-04 12:30"), +// new City("Novi Sad", "RS", 45.2671, 19.8335, "2025-07-03 09:15"), +// new City("Niš", "RS", 43.3209, 21.8958, "2025-07-02 18:45"), +// new City("Subotica", "RS", 46.1000, 19.6667, "2025-07-01 14:10"), +// new City("Kragujevac", "RS", 44.0128, 20.9110, "2025-06-30 07:50") +// }; +// +// return cities; } + private void setEnteredDateTime(City city) { - // Search one item by city.name and change for him enteredAt to now() + DatabaseHelper dbHelper = new DatabaseHelper(this); + + // Get current timestamp, e.g. "2025-07-05 16:45" + String currentTimestamp = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm", java.util.Locale.getDefault()).format(new java.util.Date()); + + boolean success = dbHelper.updateCityLastEnteredAt(city.name, city.country, currentTimestamp); + + Toast.makeText( + this, + success ? "Updated last entered time for " + city.name : "Failed to update last entered time for " + city.name, + Toast.LENGTH_SHORT + ).show(); } diff --git a/app/src/main/java/com/example/airquality/MainActivity.java b/app/src/main/java/com/example/airquality/MainActivity.java index ed1273b..6e862f6 100644 --- a/app/src/main/java/com/example/airquality/MainActivity.java +++ b/app/src/main/java/com/example/airquality/MainActivity.java @@ -14,6 +14,7 @@ import com.android.volley.toolbox.Volley; import com.example.airquality.api.ForecastAPIRequest; import com.example.airquality.types.City; import com.example.airquality.types.Weather3h; +import com.example.airquality.utils.DatabaseHelper; import com.example.airquality.utils.PreferencesManager; import com.example.airquality.utils.ToolbarCompatActivity; import com.example.airquality.utils.Weather3hAdapter; @@ -45,11 +46,26 @@ public class MainActivity extends ToolbarCompatActivity { } private void saveOffline(Weather3h[] weathers) { - // Save to db + DatabaseHelper dbHelper = new DatabaseHelper(this); // Make sure you have context here + + dbHelper.deleteAllWeather(); + + for (Weather3h weather : weathers) { + boolean success = dbHelper.addOneWeather(weather); + if (!success) { + Toast.makeText(this, "Failed to insert data for dt: " + weather.getDt(), Toast.LENGTH_SHORT).show(); + } + } + + Toast.makeText(this, "Weather data saved successfully!", Toast.LENGTH_SHORT).show(); } private Weather3h[] loadOffline() { - // Load from db - return new Weather3h[] { }; + DatabaseHelper dbHelper = new DatabaseHelper(this); + List weatherList = dbHelper.getAllWeather(); + + Toast.makeText(this, "Loaded " + weatherList.size() + " weather entries", Toast.LENGTH_SHORT).show(); + + return weatherList.toArray(new Weather3h[0]); } @Override diff --git a/app/src/main/java/com/example/airquality/SearchCityActivity.java b/app/src/main/java/com/example/airquality/SearchCityActivity.java index 6a65788..a5d2353 100644 --- a/app/src/main/java/com/example/airquality/SearchCityActivity.java +++ b/app/src/main/java/com/example/airquality/SearchCityActivity.java @@ -19,6 +19,7 @@ import com.example.airquality.databinding.ActivitySearchCityBinding; import com.example.airquality.types.City; import com.example.airquality.utils.BaseCompatActivity; import com.example.airquality.utils.CityAdapter; +import com.example.airquality.utils.DatabaseHelper; import com.example.airquality.utils.PreferencesManager; import com.example.airquality.utils.Weather3hAdapter; @@ -44,7 +45,9 @@ public class SearchCityActivity extends BaseCompatActivity { } private void addToFavorite(City city) { - // Add to db + DatabaseHelper dbHelper = new DatabaseHelper(this); + boolean success = dbHelper.addOneCity(city); + Toast.makeText(this, success ? "City added to favorites!" : "Failed to add city.", Toast.LENGTH_SHORT).show(); } private void loadCities() { diff --git a/app/src/main/java/com/example/airquality/utils/DatabaseHelper.java b/app/src/main/java/com/example/airquality/utils/DatabaseHelper.java new file mode 100644 index 0000000..43aa2ae --- /dev/null +++ b/app/src/main/java/com/example/airquality/utils/DatabaseHelper.java @@ -0,0 +1,213 @@ +package com.example.airquality.utils; + + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +import com.example.airquality.types.City; +import com.example.airquality.types.Weather3h; + +import java.util.ArrayList; +import java.util.List; + +public class DatabaseHelper extends SQLiteOpenHelper { + + //weather info + public static final String DATABASE_NAME = "weather.db"; + public static final int DATABASE_VERSION = 2; + + public static final String WEATHER_TABLE = "WEATHER_TABLE"; + public static final String COLUMN_ID = "id"; // ← New ID column + public static final String COLUMN_DT = "dt"; + public static final String COLUMN_DATE_TIME = "dateTime"; + public static final String COLUMN_TEMP = "temperature"; + public static final String COLUMN_TEMP_MIN = "tempMin"; + public static final String COLUMN_TEMP_MAX = "tempMax"; + public static final String COLUMN_PRESSURE = "pressure"; + public static final String COLUMN_HUMIDITY = "humidity"; + public static final String COLUMN_WIND_SPEED = "windSpeed"; + public static final String COLUMN_WIND_DEG = "windDeg"; + public static final String COLUMN_DESCRIPTION = "description"; + public static final String COLUMN_ICON = "icon"; + + //favorite cities + public static final String CITIES_TABLE = "FAVORITE_CITIES"; + public static final String COLUMN_CITY_ID = "id"; + public static final String COLUMN_CITY_NAME = "name"; + public static final String COLUMN_CITY_COUNTRY = "country"; + public static final String COLUMN_CITY_LATITUDE = "latitude"; + public static final String COLUMN_CITY_LONGITUDE = "longitude"; + public static final String COLUMN_CITY_LAST_ENTERED = "lastEnteredAt"; + + public DatabaseHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + String createWeatherTable = "CREATE TABLE " + WEATHER_TABLE + " (" + + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + COLUMN_DT + " INTEGER, " + + COLUMN_DATE_TIME + " TEXT, " + + COLUMN_TEMP + " REAL, " + + COLUMN_TEMP_MIN + " REAL, " + + COLUMN_TEMP_MAX + " REAL, " + + COLUMN_PRESSURE + " INTEGER, " + + COLUMN_HUMIDITY + " INTEGER, " + + COLUMN_WIND_SPEED + " REAL, " + + COLUMN_WIND_DEG + " INTEGER, " + + COLUMN_DESCRIPTION + " TEXT, " + + COLUMN_ICON + " TEXT" + + ")"; + + String createCitiesTable = "CREATE TABLE " + CITIES_TABLE + " (" + + COLUMN_CITY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + COLUMN_CITY_NAME + " TEXT NOT NULL, " + + COLUMN_CITY_COUNTRY + " TEXT NOT NULL, " + + COLUMN_CITY_LATITUDE + " REAL NOT NULL, " + + COLUMN_CITY_LONGITUDE + " REAL NOT NULL, " + + COLUMN_CITY_LAST_ENTERED + " TEXT" + + ")"; + + db.execSQL(createWeatherTable); + db.execSQL(createCitiesTable); + + + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + db.execSQL("DROP TABLE IF EXISTS " + WEATHER_TABLE); + db.execSQL("DROP TABLE IF EXISTS " + CITIES_TABLE); + onCreate(db); + } + + + //functions for weather info + public boolean addOneWeather(Weather3h weather) { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues cv = new ContentValues(); + + cv.put(COLUMN_DT, weather.getDt()); + cv.put(COLUMN_DATE_TIME, weather.getDateTime()); + cv.put(COLUMN_TEMP, weather.getTemp()); + cv.put(COLUMN_TEMP_MIN, weather.getTempMin()); + cv.put(COLUMN_TEMP_MAX, weather.getTempMax()); + cv.put(COLUMN_PRESSURE, weather.getPressure()); + cv.put(COLUMN_HUMIDITY, weather.getHumidity()); + cv.put(COLUMN_WIND_SPEED, weather.getWindSpeed()); + cv.put(COLUMN_WIND_DEG, weather.getWindDeg()); + cv.put(COLUMN_DESCRIPTION, weather.getDescription()); + cv.put(COLUMN_ICON, weather.getIconCode()); + + long insertResult = db.insert(WEATHER_TABLE, null, cv); + db.close(); + + return insertResult != -1; + } + + + public List getAllWeather() { + List weatherList = new ArrayList<>(); + SQLiteDatabase db = this.getReadableDatabase(); + + String query = "SELECT * FROM " + WEATHER_TABLE + " ORDER BY " + COLUMN_DT + " ASC"; + Cursor cursor = db.rawQuery(query, null); + + if (cursor.moveToFirst()) { + do { + int dt = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_DT)); + String dateTime = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_DATE_TIME)); + double temp = cursor.getDouble(cursor.getColumnIndexOrThrow(COLUMN_TEMP)); + double tempMin = cursor.getDouble(cursor.getColumnIndexOrThrow(COLUMN_TEMP_MIN)); + double tempMax = cursor.getDouble(cursor.getColumnIndexOrThrow(COLUMN_TEMP_MAX)); + int pressure = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_PRESSURE)); + int humidity = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_HUMIDITY)); + double windSpeed = cursor.getDouble(cursor.getColumnIndexOrThrow(COLUMN_WIND_SPEED)); + int windDeg = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_WIND_DEG)); + String description = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_DESCRIPTION)); + String icon = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_ICON)); + + Weather3h weather = new Weather3h(dt, dateTime, temp, tempMin, tempMax, + pressure, humidity, windSpeed, windDeg, description, icon); + + weatherList.add(weather); + } while (cursor.moveToNext()); + } + + cursor.close(); + db.close(); + + return weatherList; + } + + public void deleteAllWeather() { + SQLiteDatabase db = this.getWritableDatabase(); + db.delete(WEATHER_TABLE, null, null); + db.close(); + } + + //functions for favorite cities + public boolean addOneCity(City city) { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues cv = new ContentValues(); + + cv.put(COLUMN_CITY_NAME, city.name); + cv.put(COLUMN_CITY_COUNTRY, city.country); + cv.put(COLUMN_CITY_LATITUDE, city.latitude); + cv.put(COLUMN_CITY_LONGITUDE, city.longitude); + cv.put(COLUMN_CITY_LAST_ENTERED, city.lastEnteredAt); + + long result = db.insert(CITIES_TABLE, null, cv); + db.close(); + + return result != -1; + } + + public boolean updateCityLastEnteredAt(String name, String country, String newTimestamp) { + SQLiteDatabase db = this.getWritableDatabase(); + ContentValues cv = new ContentValues(); + + cv.put(COLUMN_CITY_LAST_ENTERED, newTimestamp); + + int rowsAffected = db.update( + CITIES_TABLE, + cv, + COLUMN_CITY_NAME + " = ? AND " + COLUMN_CITY_COUNTRY + " = ?", + new String[]{name, country} + ); + + db.close(); + return rowsAffected > 0; + } + + public List getAllCities() { + List cities = new ArrayList<>(); + SQLiteDatabase db = this.getReadableDatabase(); + + String query = "SELECT * FROM " + CITIES_TABLE + " ORDER BY " + COLUMN_CITY_LAST_ENTERED + " DESC"; + Cursor cursor = db.rawQuery(query, null); + + if (cursor.moveToFirst()) { + do { + String name = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_CITY_NAME)); + String country = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_CITY_COUNTRY)); + double latitude = cursor.getDouble(cursor.getColumnIndexOrThrow(COLUMN_CITY_LATITUDE)); + double longitude = cursor.getDouble(cursor.getColumnIndexOrThrow(COLUMN_CITY_LONGITUDE)); + String lastEnteredAt = cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_CITY_LAST_ENTERED)); + + City city = new City(name, country, latitude, longitude, lastEnteredAt); + cities.add(city); + } while (cursor.moveToNext()); + } + + cursor.close(); + db.close(); + + return cities; + } +} + diff --git a/app/src/main/java/com/example/airquality/utils/PreferencesManager.java b/app/src/main/java/com/example/airquality/utils/PreferencesManager.java index d94c489..2430b1d 100644 --- a/app/src/main/java/com/example/airquality/utils/PreferencesManager.java +++ b/app/src/main/java/com/example/airquality/utils/PreferencesManager.java @@ -26,7 +26,7 @@ public class PreferencesManager { double longitude = prefs.getFloat("city_longitude", 46.1f); double latitude = prefs.getFloat("city_latitude", 19.6667f); - return new City(cityName, country, longitude, latitude); + return new City(cityName, country, latitude, longitude); } public static void setCity(Context context, City city) { SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);