Sorted in hierarchic alphabetical order
This package contains classes used for callbacks to API queries
This interface is used in callback function classes for augmenting them with a custom response provided by the invoker of the callback
The CallbackResponseFunction parameter in the callback classes is nullable, therefore, pass null if no response handling is required/implemented
This class is used as the callback for fetching geocoding data from the OpeanWeather geocoding API to insert them into the geocoding data Room database such that they can be queried against upon recurring additions of the same city in addition to persistence
This class is used as the callback for fetching weather data from the OpenWeather current weather API to insert them into the weather data Room database such that they can be persisted in the app
Geocoding data is one-to-one mapped with its respective weather data
This class is used as the callback for updating weather data on-demand by contacting the API for updates - if any - and persisting these updates in the room database; insertion (update) is only done if the retrieved data is newer than the current data
This package contains the AsyncTask's used by the DAO for the MVVM architecture
This data class is used to aggreggate the parameters required for insertion of Geocode and Weather data (the "GW") in its respective AsyncTask
This class implements the AsyncTask for deletion of a weather data object from the Room database, and it is to be noted that foreign keys are set in place to propagate such a deletion into the other tables in the database - more on that later
This class implements the AsyncTask for insertion of a geocode-weather data pair provided as a GWAyncTaskParams object to be parsed and inserted into the Room database into the respective tables
This package contains the JSON API interfaces used by Retrofit for sending requests to the different APIs used by this application
This is the interface for contacting the OpenWeather's Geocoding API to get a city's geocoding data, for more information check: https://openweathermap.org/api/geocoding-api
I have opted for using the first city that is returned in response to the user query as I do not intend to handle multiple city matches
This is the interface for contacting OpenWeather's current weather API to get a city's weather using its geocoding data (namely latitude and longitude), for more information check: https://openweathermap.org/current
This package contains all the POJOs (plain-old-java-objects) used by the Retrofit and Room libraries as well as utility classes
This package contains utility converter classes to convert back and forth between Retrofit and Room POJOs
This class has static methods to convert GeocodingData from-to Room and Retrofit POJOs
This class has static methods to convert WeatherData from-to Room and Retrofit POJOs
This package contains the POJOs specific to the Retrofit library
The Retrofit POJO class for Geocoding data received from the Geocoding API
The Retrofit POJO class for Weather data received from the Current Weather API
This package contains the POJOs specific to the Room library
The Room database POJO class for Geocoding data to be inserted into the "geocoding" table in the sqlite database by Room with one-to-one mapping with the associated auxiliary weather data in the "weather_aux" table
The Room database POJO class for aggreggated Weather data to define the one-to-many relationship between auxiliary weather data and the different weather instances (check the Current Weather API documentation linked earlier for information on what this is)
The Room database POJO class for auxiliary weather data (unique per city) to be inserted into the "weather_aux" table in the sqlite database by Room with one-to-one mapping with the associated geocoding data in the "geocoding" table and one-to-many mapping to the child weather instance items from the "weather_instances" table as defined in the relationship in the above WeatherDataAggregatePOJO4RDB class
The Room database POJO class for weather instances in weather data (there can be multiple weather instances for one city's weather data retrieved from the API, and weather instances are not unique per weather data either) to be inserted into the "weather_instances" table in the sqlite database by Room with many-to-one mapping with the parent auxiliary weather data object from the "weather_aux" table as defined in the relationship in the WeatherDataAggregatePOJO4RDB class
This is a simple class defining constants used in the application
It is to be noted that the API key used is not defined in this class, it is only retrieved from BuildConfig which is where it is secretly defined for security purposes upon uploading to GitHub
The main activity class for the application in which view binding is used in the creation and configuration of
-
The main screen layout of a prompt or recycler view followed by the city search UI
-
The recycler view that contains weather cards for each city's geocoding and weather data
-
The view model through which the recycler view is continuously populated with up-to-date LiveData
-
An item touch helper to implement swipe functionalities in the recycler view (swipe left to request update*, right to remove)
-
Implementation of search logic for the click listener of the search button
-
All other design details and conditions and view responses to events, etc.
* Update requests have an internal threshold defined in the constants class within which an update request will not contact the API** and will keep the latest cached data as the up-to-date version
** Even upon contact with API, if the retrieved data is not newer than the latest cached data, the database will not be updated
The main DAO class in the MVVM architecture for accessing data in the sqlite database, defining the following queries and transactions
-
insertGeocodingData
; to insert geocoding data -
insertWeatherDataAux
; to insert auxiliary weather data -
insertWeatherDataInstance
; to insert weather instances in weather data -
insertGeocodingAndWeatherData
; to insert geocoding data as well as its associated weather data (auxiliary and instances) -
getAllWeatherData
; to retrieve all weather data entries (auxiliary data and its associated instances for each entry using the aggreggate WeatherDataAggregatePOJO4RDB) -
getWeatherGeocodingDataByWeatherAuxId
; to retrieve geocoding data for a certain city from the geocoding database through its auxiliary weather data identifier -
getGeocodingDataByCityCountry
; to retrieve geocoding data for a certain city from the geocoding database by its city and country names -
deleteWeatherData
; to delete weather data (deletes the auxiliary data and its associated instances)
The repository class in the MVVM architecture implemented as a Singleton for retrieving data from API or database through the following methods using MyDataAccessObject, the JSONAPIs, the Callbacks, and the AsyncTasks from earlier
-
insertGeocodingAndWeatherData
; invokes the AsyncTask associated with this database insertion operation -
getWeatherGeocodingDataByWeatherAuxId
; invokes the DAO method associated with this database query -
getGeocodingDataByCityCountry
; invokes the DAO method associated with this database query -
deleteWeatherData
; invokes the AsyncTask associated with this database deletion operation -
searchForAndInsertCity
; invokes an API call using the geocoding JSON API interface mentioned earlier and enqueues the callback for geocoding data search/retrieval and insertion into database upon retrieval from API -
getAndInsertWeatherByCityGeocode
; invokes an API call using the weather data JSON API interface mentioned earlier and enqueues the callback for weather data retrieval and insertion into database upon retrieval from API -
updateWeather
; invokes an API call using the weather data JSON API interface mentioned earlier and enqueues the callback for weather data update in database upon retrieval from API
The Room database abstraction class in the MVVM architecture implemented as a Singleton provoding the DAO object used to query the database
The ViewModel in the MVVM architecture which uses the repository to update its LiveData instance of aggreggated weather data which is used to populate the view in the MainActivity as explained earlier
The adapter class for the recycler view containing the logic and design of weather cards that populate the recycler view
-- MainActivity (RecyclerView with WeatherCardListAdapter, City Search UI)
-> MyViewModel (LiveData)
-> MyRepository
-> Retrofit (JSONAPIs, APICallbacks) / Room (MyRoomDatabase -> MyDataAccessObject, DAOAsyncTasks) *
-> Retrofit Library / Room Library
-> Android's sqlite database for the application or the API
For contacting Geocoding and Current Weather APIs from OpenWeather
Need it so that layout maintains its shape when soft keyboard appears for input
Need to use localProperties for secure storage of API KEY in the build configuration (which is not uploaded on GitHub)
Need to enable the viewBinding feature
Please refer to the SettingAndroidxDependencies.rtf file uploaded on this repository, it was written by our Dr. for the course in which I've made this task
Used for calling the OpenWeather APIs and implementing their callbacks, GSON to convert retrieved JSON to POJOs
com.squareup.retrofit2:converter-gson:2.4.0
com.squareup.retrofit2:retrofit:2.4.0
Used for loading and caching weather image icons from OpenWeather
com.squareup.picasso:picasso:2.8
Used for conversion from and to ISO country codes (ISO 3166-1, etc.) required for the Geocoding API country input
com.neovisionaries:nv-i18n:1.28
Other dependencies were automatically added by Android Studio, such as the JUnit framework that come with the basic project example, and the non-basic UI components such as RecyclerView, CardView, etc...
This is where the API KEY is stored and referenced from localProperties
There is currently a bug where a city may get disassociated with its respective weather data making its update operation fail, but I can't find a concrete set of steps to reproduce it yet
2022-12-02-18-50-54.mp4
This video shows removal of all added cities then adding four new ones
2022-12-02-18-51-48.mp4
This video shows how internal update interval is enforced vs. when no new data is available at the API end even if the update interval has passed
2022-12-02-18-53-14.mp4
This video shows a normal update operation with internal update interval passed and API has new data
2022-12-02-19-04-41.mp4
This video shows the handling of attempt to add already-added cities
2022-12-02-22-19-00.mp4
This video shows normal update operations on all existing cities