0

I am trying to do a GET method that receives a json with retrofit but it is giving me an error. I do not know if it's because I'm not passing the parameter correctly or the Object class is not well defined.

public class MainActivity extends AppCompatActivity {

    Retrofit retrofit;
    WeatherAPI weatherAPI;
    String locationCurrent = "Barcelona";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        retrofit = new Retrofit.Builder()
                .baseUrl("http://api.apixu.com/v1/")
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        weatherAPI =retrofit.create(WeatherAPI.class);
        weatherGET(locationCurrent);

    }
    void weatherGET(final String  location){
        Call<Object> call = weatherAPI.getWeather(location);
        call.enqueue(new Callback<Object>() {
            @Override
            public void onResponse(Call <Object> call, Response<Object> response) {
                Log.d("%%%%%","Entrada");
                Object dataGETWeather;
                dataGETWeather = response.body();         Log.d("Temp",String.valueOf(dataGETWeather.CurrentObject.getTemp_c()));
            }
            @Override
            public void onFailure(Call<Object> call, Throwable t) {
                Log.d("%%%%%","Salida");

            }
        });
    }
}

Service definition:

public interface WeatherAPI {

    @GET("current.json?key=9aa4f8a0b09c4034b44183812191306&q={location}")
    @Headers("Accept:application/json")
    Call<Object> getWeather(@Query("location") String location);

}

Object to be received:

// The father of the object is this, but it has more subdivisions
public class Object {
    Location LocationObject;
    Current CurrentObject;


    // Getter Methods
    public Location getLocation() {
        return LocationObject;
    }

    public Current getCurrent() {
        return CurrentObject;
    }

    // Setter Methods

    public void setLocation(Location locationObject) {
        this.LocationObject = locationObject;
    }

    public void setCurrent(Current currentObject) {
        this.CurrentObject = currentObject;
    }
}

Log of the exception:

019-06-14 13:36:36.236 14987-14987/com.example.weatherapiE/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.weatherapi, PID: 14987
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.weatherapi/com.example.weatherapi.MainActivity}: java.lang.IllegalArgumentException: URL query string "key=9aa4f8a0b09c4034b44183812191306&q={location}" must not have replace block. For dynamic query parameters use @Query.
    for method WeatherAPI.getWeather
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)   
Zoe
  • 27,060
  • 21
  • 118
  • 148

3 Answers3

0

remove &q={location} from end point url

@GET("current.json?key=9aa4f8a0b09c4034b44183812191306")
Mohammad Sommakia
  • 1,773
  • 3
  • 15
  • 48
0

You should change your WeatherAPI interface like so:

public interface WeatherAPI {
    @GET("current.json?key=9aa4f8a0b09c4034b44183812191306")
    @Headers("Accept:application/json")
    Call<Object> getWeather(@Query("q") String location);
}

Your argument location will be appended to the querystring as "q" (which is what's specified in the @Query annotation).

Xavier Rubio Jansana
  • 6,388
  • 1
  • 27
  • 50
  • I just did what you tell me. But the call goes directly to: public void onFailure (Call call, Throwable t) { Log.d ("%%%%%", "Exit"); } }); – Aitor Ballesteros Jun 14 '19 at 12:38
  • The I would suggest you to add a logger interceptor like so: https://stackoverflow.com/a/33256827/3286819 setting the level to `RestAdapter.LogLevel.FULL`. With this you would be able to see the complete request and response in Logcat and be able to determine the reason of the error. – Xavier Rubio Jansana Jun 14 '19 at 12:41
  • try to log t.getMessage(); – Mohammad Sommakia Jun 14 '19 at 12:42
  • I do not know if I have done correctly what you tell me, but in the logcat it puts this to me: HTTP FAILED: java.net.UnknownServiceException: CLEARTEXT communication to api.apixu.com not allowed by network security policy – Aitor Ballesteros Jun 14 '19 at 13:14
  • Then now your problem is that your API is not secure (not using SSL) and your device is API 23+. Look here for a quick fix: https://stackoverflow.com/a/50834600/3286819 Option 2 is the quickest way to prove this assumption (but I suggest to try to switch your API to HTTPS if possible). – Xavier Rubio Jansana Jun 14 '19 at 13:32
  • Okay, now it makes me the response, but object comes to me empty: java.lang.NullPointerException: Attempt to read from field 'com.example.weatherapi.Current com.example.weatherapi.Object.CurrentObject' on a null object reference – Aitor Ballesteros Jun 14 '19 at 13:54
  • In the / OkHttp: if you see the whole object, I do not understand why it does not go well – Aitor Ballesteros Jun 14 '19 at 14:06
  • You should update your question with the information up to this point and the logs you're getting. – Xavier Rubio Jansana Jun 14 '19 at 14:12
  • I do the debugger and in response.body () it gives me this: Response {protocol = h2, code = 200, message =, url = https: //api.apixu.com/v1/current.json? Key = 9aa4f8a0b09c4034b44183812191306 & q = Glasgow} But then when I equal the answer to the object this one gives me null – Aitor Ballesteros Jun 14 '19 at 15:11
  • BTW it would be wise to rename your class `Object` to something more meaningful (e.g. `WeatherInfoResponse`), as `Object` may conflict with Java's own `Object` https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html (and this could be a quite plausible reason of why parsing is failing). – Xavier Rubio Jansana Jun 14 '19 at 15:23
  • Then, again, could you provide the logs you're getting? Please, update your question or share it somewhere else (e.g. pastebin), if you're still unable to update the question because of your current reputation. – Xavier Rubio Jansana Jun 14 '19 at 15:48
0

Change Your Interface with this

    @GET("current.json")
    @Headers("Accept:application/json")
    Call<Object> getWeather(@Query("key") String key,@Query("location") String location);
Tejas Pandya
  • 3,987
  • 1
  • 26
  • 51