Introduction
In this article, we will learn how to create our own weather app using Retrofit 2. There are a lot of providers available to provide weather data. In this tutorial we will use the famous provider “OpenWeatherMap” Api to build our own weather app.
Coding Part
I have arranged the article as follows.
- Step 1 - Creating New Project with Empty Activity.
- Step 2 - Setting up the Retrofit HTTP Library and Manifest.
- Step 3 - Getting App ID from Open Weather API.
- Step 4 - Implementation of consumption of Weather API using Retrofit.
Creating New Project with Android Studio
- Open Android Studio and Select Create new project.
- Name the project as per your wish and select your activity template.
- Click “finish” button to create a new project in Android Studio.
Setting up the Retrofit Http Library and Manifest
In this part, we will see how to set up the library for the project.
- Then add the following lines in app level build.gradle file to apply Google services to your project.
- dependencies {
- ...
- implementation 'com.squareup.retrofit2:retrofit:2.0.0'
- implementation 'com.squareup.retrofit2:converter-gson:2.0.0'
- }
- Then click “Sync Now” to set up your project.
- Don't forget to add the following permission in your manifest file
- <uses-permission android:name="android.permission.INTERNET"/>
Getting App Id from Open Weather Map
- Open OpenWeatherMap Site and sign up for free to get your app id.
- You can find or create your app id in API Keys tab of the site after logged in. Find the screenshot for your reference.
Implementation of consumption of Weather API using Retrofit
The following API link is used to get the current weather report respective to the geo-coordinates. The Sample API link is
here.
We will see, how to use the link to access the weather data.
- Create an interface file named as “WeatherService.java” and add the following lines
- public interface WeatherService {
- @GET("data/2.5/weather?")
- Call<WeatherResponse> getCurrentWeatherData(@Query("lat") String lat, @Query("lon") String lon, @Query("APPID") String app_id);
- }
- Create a class file named as “WeatherResponse.java” and add the following lines. We will get the response as json as in the following.
- {
- "coord": {
- "lon": 139,
- "lat": 35
- },
- "sys": {
- "country": "JP",
- "sunrise": 1369769524,
- "sunset": 1369821049
- },
- "weather": [
- {
- "id": 804,
- "main": "clouds",
- "description": "overcast clouds",
- "icon": "04n"
- }
- ],
- "main": {
- "temp": 289.5,
- "humidity": 89,
- "pressure": 1013,
- "temp_min": 287.04,
- "temp_max": 292.04
- },
- "wind": {
- "speed": 7.31,
- "deg": 187.002
- },
- "rain": {
- "3h": 0
- },
- "clouds": {
- "all": 92
- },
- "dt": 1369824698,
- "id": 1851632,
- "name": "Shuzenji",
- "cod": 200
- }
- I have used json to java converter online to generate the Response class and the equivalent java class should be shown below.
- public class WeatherResponse {
-
- @SerializedName("coord")
- public Coord coord;
- @SerializedName("sys")
- public Sys sys;
- @SerializedName("weather")
- public ArrayList<Weather> weather = new ArrayList<Weather>();
- @SerializedName("main")
- public Main main;
- @SerializedName("wind")
- public Wind wind;
- @SerializedName("rain")
- public Rain rain;
- @SerializedName("clouds")
- public Clouds clouds;
- @SerializedName("dt")
- public float dt;
- @SerializedName("id")
- public int id;
- @SerializedName("name")
- public String name;
- @SerializedName("cod")
- public float cod;
- }
-
- class Weather {
- @SerializedName("id")
- public int id;
- @SerializedName("main")
- public String main;
- @SerializedName("description")
- public String description;
- @SerializedName("icon")
- public String icon;
- }
-
- class Clouds {
- @SerializedName("all")
- public float all;
- }
-
- class Rain {
- @SerializedName("3h")
- public float h3;
- }
-
- class Wind {
- @SerializedName("speed")
- public float speed;
- @SerializedName("deg")
- public float deg;
- }
-
- class Main {
- @SerializedName("temp")
- public float temp;
- @SerializedName("humidity")
- public float humidity;
- @SerializedName("pressure")
- public float pressure;
- @SerializedName("temp_min")
- public float temp_min;
- @SerializedName("temp_max")
- public float temp_max;
- }
-
- class Sys {
- @SerializedName("country")
- public String country;
- @SerializedName("sunrise")
- public long sunrise;
- @SerializedName("sunset")
- public long sunset;
- }
-
- class Coord {
- @SerializedName("lon")
- public float lon;
- @SerializedName("lat")
- public float lat;
- }
- The SerializedName annotation is used to parse the server response and their name & type should be the same as the Json Response received from the server.
- Then initialize Retrofit to call the weather service. The following code snippet will help us to call the service.
- void getCurrentData() {
- Retrofit retrofit = new Retrofit.Builder()
- .baseUrl(BaseUrl)
- .addConverterFactory(GsonConverterFactory.create())
- .build();
- WeatherService service = retrofit.create(WeatherService.class);
- Call<WeatherResponse> call = service.getCurrentWeatherData(lat, lon, AppId);
- call.enqueue(new Callback<WeatherResponse>() {
- @Override
- public void onResponse(@NonNull Call<WeatherResponse> call, @NonNull Response<WeatherResponse> response) {
- if (response.code() == 200) {
- WeatherResponse weatherResponse = response.body();
- assert weatherResponse != null;
-
- String stringBuilder = "Country: " +
- weatherResponse.sys.country +
- "\n" +
- "Temperature: " +
- weatherResponse.main.temp +
- "\n" +
- "Temperature(Min): " +
- weatherResponse.main.temp_min +
- "\n" +
- "Temperature(Max): " +
- weatherResponse.main.temp_max +
- "\n" +
- "Humidity: " +
- weatherResponse.main.humidity +
- "\n" +
- "Pressure: " +
- weatherResponse.main.pressure;
-
- weatherData.setText(stringBuilder);
- }
- }
-
- @Override
- public void onFailure(@NonNull Call<WeatherResponse> call, @NonNull Throwable t) {
- weatherData.setText(t.getMessage());
- }
- });
- }
Here we used Json Converter and so the json response automatically converted to the respective and the converter will compare the response tree with the serialized name.
- Our own developed weather app is ready.
Full Code
You can find the full code implementation of the app here.
- public class MainActivity extends AppCompatActivity {
- public static String BaseUrl = "http://api.openweathermap.org/";
- public static String AppId = "2e65127e909e178d0af311a81f39948c";
- public static String lat = "35";
- public static String lon = "139";
- private TextView weatherData;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- weatherData = findViewById(R.id.textView);
-
- Typeface typeface = Typeface.createFromAsset(getAssets(), "Lato-Bold.ttf");
- FontUtils fontUtils = new FontUtils();
- fontUtils.applyFontToView(weatherData, typeface);
-
- findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getCurrentData();
- }
- });
- }
-
- void getCurrentData() {
- Retrofit retrofit = new Retrofit.Builder()
- .baseUrl(BaseUrl)
- .addConverterFactory(GsonConverterFactory.create())
- .build();
- WeatherService service = retrofit.create(WeatherService.class);
- Call<WeatherResponse> call = service.getCurrentWeatherData(lat, lon, AppId);
- call.enqueue(new Callback<WeatherResponse>() {
- @Override
- public void onResponse(@NonNull Call<WeatherResponse> call, @NonNull Response<WeatherResponse> response) {
- if (response.code() == 200) {
- WeatherResponse weatherResponse = response.body();
- assert weatherResponse != null;
-
- String stringBuilder = "Country: " +
- weatherResponse.sys.country +
- "\n" +
- "Temperature: " +
- weatherResponse.main.temp +
- "\n" +
- "Temperature(Min): " +
- weatherResponse.main.temp_min +
- "\n" +
- "Temperature(Max): " +
- weatherResponse.main.temp_max +
- "\n" +
- "Humidity: " +
- weatherResponse.main.humidity +
- "\n" +
- "Pressure: " +
- weatherResponse.main.pressure;
-
- weatherData.setText(stringBuilder);
- }
- }
-
- @Override
- public void onFailure(@NonNull Call<WeatherResponse> call, @NonNull Throwable t) {
- weatherData.setText(t.getMessage());
- }
- });
- }
-
- }
To know more about Retrofit and Open Weather API
- https://openweathermap.org/api
- https://square.github.io/retrofit/
If you have any doubts or need any help, contact me.
Download Code
You can download the full source code of the article in
GitHub. If you like this article, do star the repo in GitHub. Hit like the article.