Arcus is a simple weather app built completely with Jetpack Compose. Under the hood, it uses the Open-Meteo Weather API to fetch the data. It also uses either the OpenAI API or Google's Gemini client SDK to display a short whimsical summary of the current weather of a particular location. This app uses the Material 3 design system and also supports dynamic colors on supported devices.
- Demo
- Screenshots
- Tech Stack
- Remote API's
- Notable Features
- Themed App Icon
- Source code, Architecture, & Testing
- Building and running the app
Arcus-Emulator-Demo.mp4
The app also supports the "Themed Icons" feature available on Android 13 and later. If the user has opted in for the feature on a device that is running Android 13 and higher, the app's icon will be tinted to inherit the coloring of the user’s chosen wallpaper and other themes.
- Entirely written in Kotlin.
- Hilt for dependency injection.
- Jetpack Compose for UI and navigation.
- Coil compose for image loading and caching.
- Coil-gif for loading and displaying gif's.
- Coil-svg for loading and displaying svg's from URL's.
- Accompanist Placeholder for adding shimmer animation when loading an image.
- SplashScreen API for displaying a splashscreen in a backwards compatible way.
- Kotlin Coroutines for threading.
- Kotlin Flows for creating reactive streams.
- Mokito-Kotlin for mocking dependencies in unit tests.
- Retrofit for communicating with the Open-Meteo API.
- Room for database.
- Java 8 Date/Time API for dealing with date and time.
- Timber for logging.
- Work Manager for background tasks.
- Moshi + Moshi Kotlin CodeGen for deserializing responses from the API.
- Google play location services for getting the user’s location.
- Open-Meteo weather api for fetching weather information.
- Gemini / OpenAI API for generating a short, whimsical summary of the current weather of a particular location.
- Adaptive UI based on permissions 🪄
- The main permission that this app needs is the location permission. The UI of the app adapts based on whether the location permission is granted or not. If it is granted, the weather for the user’s current location would be displayed directly in the Home Screen. If it is not, that portion of the UI would simply not be displayed, ensuring that the UX is not undermined even if the user chooses to not provide the location permission.
- Themed splash screen 🎨
- In Android 12 and above, the background color of the splash screen matches the system theme. This minor detail, unique to this app, helps in improving the synergy of the app, with the rest of the system, from the moment the app is launched.
- Error handling
⚠️ - When an error is encountered, the app ensures that it displays an appropriate error message and also provides a way to retry the operation that caused the error to occur.
- All concrete implementations are prefixed by the term “Arcus”.
- Uses multi-repository pattern.
- MVVM architecture.
- Each package is considered as an individual module / submodule. Most notably, the data "module" is ensured that it is considered as a separate module and is ensured that it doesn't depend upon any other "modules" in the upper layers of the architecture.
- Commit messages follow the Conventional Commits specification.
- Consists of extensive unit tests with a predominant focus on testing the data layer.
- All api methods that use the “get” procedure under the hood, have the word “get” as the prefix of the method name. All repository methods that fetch some data have the prefix “fetch” in the name of the method. This way, api specific terminologies like “get” and “post” are abstracted away from the clients of the repositories.
- The app can be made to either use Gemini or Chat-GPT
for it's contextual text generation features. To use either of the two, make sure to get the access / api key for the chosen LLM service,
and paste it in the
local.properties
file as follows. - Add the API token to the
local.properties
file of your project in the following manner.
OPEN_AI_API_TOKEN = PASTE-YOUR-TOKEN-HERE
or
GOOGLE_GEMINI_API_KEY = PASTE-YOUR-TOKEN-HERE
- By default, the app uses Gemini for text generation. If you want to use Chat-GPT, then replace the '@GeminiClient'
di qualifier with the
@OpenAiClient
qualifier in all places where an instance ofTextGeneratorClient
is injected. - Build the project and run the app on an emulator or physical device.