3

I'm new to developing and I'm trying to develop an android weather application for an assignment I followed this tutorial on youtube to create it everything works fine but I couldn't get the data from the "weather" object on the below API.
OpenWeatherMap API

{
  "coord": {
    "lon": -122.08,
    "lat": 37.39
  },
  "weather": [
    {
      "id": 800,
      "main": "Clear",
      "description": "clear sky",
      "icon": "01d"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 282.55,
    "feels_like": 281.86,
    "temp_min": 280.37,
    "temp_max": 284.26,
    "pressure": 1023,
    "humidity": 100
  },
  "visibility": 16093,
  "wind": {
    "speed": 1.5,
    "deg": 350
  },
  "clouds": {
    "all": 1
  },
  "dt": 1560350645,
  "sys": {
    "type": 1,
    "id": 5122,
    "message": 0.0139,
    "country": "US",
    "sunrise": 1560343627,
    "sunset": 1560396563
  },
  "timezone": -25200,
  "id": 420006353,
  "name": "Mountain View",
  "cod": 200
  }

ApiClient.java

    package com.dhanurjan.weather.Retrofit;

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class ApiClient {


    private static Retrofit retrofit = null;

   public static  Retrofit getClient(){ //creating object

        if (retrofit == null){

            retrofit = new Retrofit.Builder() //Retrofit.Builder class uses the Builder API to allow defining the URL end point for the HTTP operations and finally build a new Retrofit instance.
                    //http://api.openweathermap.org/data/2.5/weather?q=London&APPID=76a35a17f3e1bce771a09f3555b614a8
                    .baseUrl("https://api.openweathermap.org/data/2.5/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();

        }


        return retrofit;

    }
}

ApiInterface.java

    package com.dhanurjan.weather.Retrofit;

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;

public interface ApiInterface {


    @GET("weather?APPID=76a35a17f3e1bce771a09f3555b614a8&units=metric")
    Call<Example> getWeatherData(@Query("q") String name);


}

Example.java

    package com.dhanurjan.weather.Retrofit;

import com.google.gson.annotations.SerializedName;

public class Example {

    @SerializedName("sys")
    private Sys sys;

    @SerializedName("coord")
    private Coord coord;

    @SerializedName("main")
    private Main main;

    @SerializedName("weather")
    private Weather weather;

    public Sys getSys() { return sys; }

    public void setSys(Sys sys) {
        this.sys = sys;
    }

    public Coord getCoord() {
        return coord;
    }

    public void setCoord(Coord coord) {
        this.coord = coord;
    }

    public Main getMain() {
        return main;
    }

    public void setMain(Main main) {
        this.main = main;
    }

    public Weather getWeather() { return weather; }

    public void setWeather(Weather weather) { this.weather = weather; }
}

Weather.java

    package com.dhanurjan.weather.Retrofit;

import com.google.gson.annotations.SerializedName;

public class Weather {

        @SerializedName("main")
        String main;

        @SerializedName("description")
        String description;


        public String getMain() { return main; }

        public void setMain(String main) { this.main = main; }

        public String getDescription() { return description; }

        public void setDescription(String description) { this.description = description; }
}

MainActivity.java

    package com.dhanurjan.weather;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.dhanurjan.weather.Retrofit.ApiClient;
import com.dhanurjan.weather.Retrofit.ApiInterface;
import com.dhanurjan.weather.Retrofit.Example;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class MainActivity extends AppCompatActivity {

    Button searchBtn;
    TextView tempText , feelText , humidityText, lon, lat, country, sunrise, sunset, descText;
    EditText cityName;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        searchBtn = findViewById(R.id.searchBtn);
        tempText = findViewById(R.id.tempText);
        feelText = findViewById(R.id.feelText);
        humidityText = findViewById(R.id.humidityText);
        country = findViewById(R.id.country);
        sunrise = findViewById(R.id.sunrise);
        sunset = findViewById(R.id.sunset);
        lon = findViewById(R.id.lonText);
        lat = findViewById(R.id.latText);
        cityName = findViewById(R.id.cityName);
        descText = findViewById(R.id.descText);


        searchBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                getWeatherData(cityName.getText().toString().trim());

            }
        });
    }

    private void getWeatherData(String name){

        ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);

        Call<Example> call = apiInterface.getWeatherData(name);

        call.enqueue(new Callback<Example>() {
            @Override
            public void onResponse(Call<Example> call, Response<Example> response) {

                tempText.setText("Temperature :"+" "+response.body().getMain().getTemp()+" ℃");
                feelText.setText("Feels Like :"+" "+response.body().getMain().getFeels_like()+" ℃");
                lon.setText("Longitude :"+" "+response.body().getCoord().getLon()+" °E");
                lat.setText("Latitude :"+" "+response.body().getCoord().getLat()+" °N");
                humidityText.setText("Humidity :"+" "+response.body().getMain().getHumidity()+" %");
                country.setText("country :"+" "+response.body().getSys().getCountry());
                sunrise.setText("sunrise :"+" "+response.body().getSys().getSunrise()+" AM");
                sunset.setText("sunset :"+" "+response.body().getSys().getSunset()+" PM");
                descText.setText("descText :"+" "+response.body().getWeather().getDescription());


            }

            @Override
            public void onFailure(Call<Example> call, Throwable t) {

            }
        });

    }
}



                                    
Dhanurjan
  • 81
  • 2
  • 8
  • Please attach the correct ApiClient class – Rohan Sharma Nov 25 '20 at 13:14
  • Hi Dhanurjan. I made some fixes below. I cannot see your model classes such as Sys, Cord, Main and Weather. But make sure each of the fields has the correct type because GSON will stop parsing the response if it encounters any incorrect types. If in doubt, just make the type a String for now. – Elletlar Nov 25 '20 at 15:53

1 Answers1

3

The main issue with the code is:

@SerializedName("weather")
private Weather weather;

The corresponding JSON is:

"weather": [
    {
        "id": 800,
        "main": "Clear",
        "description": "clear sky",
        "icon": "01d"
    }]

While it only has 1 item, it is actually a JSON array of Weather objects due to the "[" and "]"

The Retrofit annotation needs to be changed to:

@SerializedName("weather")
private List<Weather> weatherList;

And the getters and setters need to be changed to:

public List<Weather> getWeatherList() { return weatherList; }

public void setWeatherList(List<Weather> weatherList) { this.weatherList = weatherList; }

The code that displays info about the weather needs to be updated to:

response.body().getWeatherList().get(0).getDescription();

This will get the first Weather object or crash if there are none.

But I have your code running in my project so please let me know if you run into any more issues.

Lastly, for anyone is looking for a simpler API to learn Retrofit: https://dog.ceo/api/breeds/image/random

This is a GET that returns only 2 fields.

Elletlar
  • 3,136
  • 7
  • 32
  • 38
  • Thank you Elletlar. I have changed my code and tested it and everything working well. You have helped me to complete my assignment thank you so much again. – Dhanurjan Nov 25 '20 at 15:59