Build an Android Weather App with OpenWeather
A weather app may appear straightforward, but local conditions shape its design. Sydney often brings humid coastal weather, Melbourne can shift rapidly between sunshine and wind, and Brisbane regularly encounters summer storms. Australian users also expect temperatures in Celsius, wind speeds in kilometres per hour, and forecasts that align with daylight-saving changes.
This tutorial focuses on building a weather app with OpenWeather API, combining current conditions, hourly data and a multi-day outlook in an Android interface. The app will query weather information by city name or coordinates, convert JSON responses into Kotlin objects and display them through adaptive layouts.
The implementation covers API-key handling, Retrofit networking, data models, location access, caching and error recovery. It also includes testing guidance and release considerations for the Australian Android market, where reliable performance and clear weather warnings are especially valuable.
Compare the weather data sources
OpenWeather provides several endpoints suited to different screens. Select endpoints according to the information each screen needs rather than requesting every available forecast product in one response.
| Requirement | Suitable endpoint | Main response fields | Practical use |
|---|---|---|---|
| Current conditions | Current Weather | temperature, feels-like value, humidity, wind, rain, sunrise and sunset | Main weather card |
| Multi-day outlook | Five Day / Three Hour Forecast | forecast list, condition, temperature, wind and precipitation probability | Daily forecast list |
| Detailed hourly data | One Call | current, minutely, hourly, daily and alert data | Advanced weather features |
Current Weather and the Five Day endpoint are sufficient for most beginner projects. One Call can support hourly graphs, severe-weather alerts and minutely precipitation forecasts, although access may depend on the account plan.
Each request can include a city name with the q parameter or latitude and longitude with lat and lon. Coordinates are usually preferable for automatic local forecasts because they avoid ambiguity between places with similar names. The units=metric setting returns Celsius temperatures, while wind speed still needs conversion from metres per second to kilometres per hour.
Configure the Android project
Create a Kotlin project in Android Studio and add Retrofit with a JSON converter such as Moshi or Gson. Include the INTERNET permission in the manifest, then organise the code into presentation, networking, model and repository layers. Practical examples from Android Open Tutorials can help with the Android-specific setup, including activities, adapters and SharedPreferences.
Store the OpenWeather API key outside source control. A common approach is to place it in local.properties, read that file during the Gradle build and expose the value through BuildConfig. Also restrict the key to the required API services and monitor usage. An embedded key can be extracted from an APK, so a backend proxy is safer for a high-traffic production application.
Test the configuration early with a simple city request. An HTTP 401 response usually indicates an invalid key, while a 401 caused by activation settings may require waiting for the new key to propagate. Run the initial request on both an emulator and a physical device, and confirm that HTTPS networking works under the device’s connection restrictions.
Parse OpenWeather JSON safely
Create Kotlin data classes that mirror only the properties the app uses. Model optional values as nullable and give them sensible interface defaults. A compact current-weather model might include the city name, main measurements, wind details and a list of weather conditions.
data class CurrentWeather(
val name: String?,
val main: MainWeather?,
val wind: Wind?,
val weather: List<WeatherCondition>?
)
Use the timezone offset returned by the service when formatting dates. The dt value represents a UTC timestamp, while the timezone field supplies the city’s offset. This matters across Australia, where UTC offsets vary and daylight-saving schedules differ between states. Applying the phone’s own timezone could therefore display the wrong forecast hour.
Convert metric wind values by multiplying metres per second by 3.6. Round values only for display so calculations retain their original precision. OpenWeather supplies convenient timestamps for sunrise and sunset, which can add useful context to the current screen. For official warnings and emergency guidance, the app should also direct users to the Bureau of Meteorology, Australia’s government weather authority.
Create current and forecast screens
The main screen can show the selected city, current temperature, condition icon, apparent temperature, humidity, wind speed and the latest observation time. Provide a loading indicator while the request runs, followed by a clear error state if the city cannot be found or the network is unavailable.
Display the Five Day forecast in a RecyclerView, or a ListView for a simpler implementation. Group the three-hour forecast entries by local date and calculate each day’s minimum and maximum temperature. Show precipitation probability where available and distinguish forecasts for morning, afternoon, evening and overnight rather than presenting each three-hour slot as a full day.
Keep the interface legible across screen sizes and support dark mode through Android theme resources. Weather icons require meaningful content descriptions, while temperature and warning information should never depend on colour alone. Search controls should accept Australian city names such as Adelaide, Hobart or Canberra while preserving the user’s selected location between launches.
Add location, caching and error recovery
Use the fused location provider when the user chooses an automatic local forecast. Request location permission at the point it is needed, explain the purpose first and provide a city-search alternative for people who decline. Coarse location is often sufficient for a neighbourhood forecast, reducing both privacy intrusion and battery consumption.
Place recent responses in SharedPreferences for a small sample or use Room when storing multiple cities and forecast histories. Every cached result should include its retrieval timestamp. When the device loses connectivity, display the cached forecast with an age indicator instead of leaving the screen blank; this is particularly helpful in regional areas where mobile coverage can be inconsistent.
Handle timeouts, malformed responses, HTTP errors and disconnected devices separately. Retrofit’s suspend functions make this manageable with structured concurrency and try blocks around repository calls. A retry action should be visible only when repeating the request is reasonable, and repeated failures should return the user to a usable cached state or city selection screen.
Test and release the app
Write unit tests around JSON parsing, null handling, wind conversion and date grouping. Test daylight-saving boundaries, forecast entries near midnight and cities located in different Australian time zones. Instrumentation tests can verify that loading, error and successful-data states appear correctly, while rotation tests ensure location and city selections survive configuration changes.
Before publishing, scan the release bundle for exposed credentials and apply broader security guidance to the devices and networks expected to use the application. Remove verbose API-key logs, disable debugging in release builds and avoid collecting location information unless the selected feature requires it.
For Google Play distribution in Australia, generate an Android App Bundle and provide a privacy policy plus an accurate data-safety declaration. Display the required OpenWeather attribution, confirm API-plan quotas and review subscription requirements before launch. With a modular repository, cached observations, accessible layouts and resilient network states, the resulting weather app can remain dependable through changing forecasts and intermittent connections.