I am trying to make a call to the FlickR API and am having difficulty as the response.body() is returning null.
I am not sure if it relates to my JSON/POJO mapping, but I cannot figure out how to access the response from Retrofit when I make the call to FlickR. I know that my call is being completed successfully as I am actually able to view the JSON through the logging interceptor.
Model:
public class Model {
Photos photos;
int code;
String stat;
String message; // when you text = null
public class Photos {
@SerializedName("page")
@Expose
private int page;
@SerializedName("pages")
@Expose
private int pages;
@SerializedName("perpage")
@Expose
private int perpage;
@SerializedName("total")
@Expose
private String total;
@SerializedName("photo")
@Expose
private List<Photo> photo = new ArrayList<Photo>();
/**
* @return The page
*/
public int getPage() {
return page;
}
/**
* @param page The page
*/
public void setPage(int page) {
this.page = page;
}
/**
* @return The pages
*/
public int getPages() {
return pages;
}
/**
* @param pages The pages
*/
public void setPages(int pages) {
this.pages = pages;
}
/**
* @return The perpage
*/
public int getPerpage() {
return perpage;
}
/**
* @param perpage The perpage
*/
public void setPerpage(int perpage) {
this.perpage = perpage;
}
/**
* @return The total
*/
public String getTotal() {
return total;
}
/**
* @param total The total
*/
public void setTotal(String total) {
this.total = total;
}
/**
* @return The photo
*/
public List<Photo> getPhoto() {
return photo;
}
/**
* @param photo The photo
*/
public void setPhoto(List<Photo> photo) {
this.photo = photo;
}
}
public class Photo {
@SerializedName("id")
@Expose
private String id;
@SerializedName("owner")
@Expose
private String owner;
@SerializedName("secret")
@Expose
private String secret;
@SerializedName("server")
@Expose
private String server;
@SerializedName("farm")
@Expose
private int farm;
@SerializedName("title")
@Expose
private String title;
@SerializedName("ispublic")
@Expose
private int ispublic;
@SerializedName("isfriend")
@Expose
private int isfriend;
@SerializedName("isfamily")
@Expose
private int isfamily;
@SerializedName("url_m")
@Expose
private String urlM;
@SerializedName("height_m")
@Expose
private String heightM;
@SerializedName("width_m")
@Expose
private String widthM;
public Photo(){
}
/**
* @return The id
*/
public String getId() {
return id;
}
/**
* @param id The id
*/
public void setId(String id) {
this.id = id;
}
/**
* @return The owner
*/
public String getOwner() {
return owner;
}
/**
* @param owner The owner
*/
public void setOwner(String owner) {
this.owner = owner;
}
/**
* @return The secret
*/
public String getSecret() {
return secret;
}
/**
* @param secret The secret
*/
public void setSecret(String secret) {
this.secret = secret;
}
/**
* @return The server
*/
public String getServer() {
return server;
}
/**
* @param server The server
*/
public void setServer(String server) {
this.server = server;
}
/**
* @return The farm
*/
public int getFarm() {
return farm;
}
/**
* @param farm The farm
*/
public void setFarm(int farm) {
this.farm = farm;
}
/**
* @return The title
*/
public String getTitle() {
return title;
}
/**
* @param title The title
*/
public void setTitle(String title) {
this.title = title;
}
/**
* @return The ispublic
*/
public int getIspublic() {
return ispublic;
}
/**
* @param ispublic The ispublic
*/
public void setIspublic(int ispublic) {
this.ispublic = ispublic;
}
/**
* @return The isfriend
*/
public int getIsfriend() {
return isfriend;
}
/**
* @param isfriend The isfriend
*/
public void setIsfriend(int isfriend) {
this.isfriend = isfriend;
}
/**
* @return The isfamily
*/
public int getIsfamily() {
return isfamily;
}
/**
* @param isfamily The isfamily
*/
public void setIsfamily(int isfamily) {
this.isfamily = isfamily;
}
/**
* @return The urlM
*/
public String getUrlM() {
return urlM;
}
/**
* @param urlM The url_m
*/
public void setUrlM(String urlM) {
this.urlM = urlM;
}
/**
* @return The heightM
*/
public String getHeightM() {
return heightM;
}
/**
* @param heightM The height_m
*/
public void setHeightM(String heightM) {
this.heightM = heightM;
}
/**
* @return The widthM
*/
public String getWidthM() {
return widthM;
}
/**
* @param widthM The width_m
*/
public void setWidthM(String widthM) {
this.widthM = widthM;
}
}
}
JSON Response:
{
photos: {
page: 1,
pages: 3683,
perpage: 100,
total: "368270",
photo: [
{
id: "29264707352",
owner: "84316756@N02",
secret: "9ed355a86e",
server: "8603",
farm: 9,
title: "Tercer Patio de los Claustros de la Compañía/ Arequipa",
ispublic: 1,
isfriend: 0,
isfamily: 0,
url_m: "https://farm9.staticflickr.com/8603/29264707352_9ed355a86e.jpg",
height_m: "500",
width_m: "333"
},
{
id: "29339070436",
owner: "146617764@N02",
secret: "b52f1e9914",
server: "8509",
farm: 9,
title: "2016-04-17 09.24.07",
ispublic: 1,
isfriend: 0,
isfamily: 0,
url_m: "https://farm9.staticflickr.com/8509/29339070436_b52f1e9914.jpg",
height_m: "281",
width_m: "500"
},
LOGCAT
09-03 15:11:33.037 1846-1846/com.troychuinard.flickr_test E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.troychuinard.flickr_test, PID: 1846
java.lang.NullPointerException: println needs a message
at android.util.Log.println_native(Native Method)
at android.util.Log.v(Log.java:118)
at com.troychuinard.flickr_test.MainActivity$1$1.onResponse(MainActivity.java:72)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:68)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5254)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
09-03 15:14:21.858 1846-1846/com.troychuinard.flickr_test I/Process: Sending signal. PID: 1846 SIG: 9
Line 72
Log.v("RESPONSE_BODY", response.body().getTotal());
Activity
public class MainActivity extends AppCompatActivity {
private EditText mSearchTerm;
private Button mRequestButton;
private Button mSearchButton;
private String mQuery;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSearchTerm = (EditText) findViewById(R.id.ediText_search_term);
mRequestButton = (Button) findViewById(R.id.request_button);
mSearchButton = (Button) findViewById(R.id.search_button_flickr);
mRequestButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mQuery = mSearchTerm.getText().toString();
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.flickr.com/services/rest/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiInterface apiInterface = retrofit.create(ApiInterface.class);
Call<Photos> call = apiInterface.getImages(mQuery);
call.enqueue(new Callback<Photos>() {
@Override
public void onResponse(Call<Photos> call, Response<Photos> response) {
Log.v("RESPONSE_CALLED", "ON_RESPONSE_CALLED");
String didItWork = String.valueOf(response.isSuccessful());
Log.v("SUCCESS?", didItWork);
Log.v("RESPONSE_CODE", String.valueOf(response.code()));
Photos photos = response.body();
Log.v("RESPONSE_BODY", "response:" + photos);
String total = response.body().getTotal();
Log.v("Total", total);
List<Photos.Photo> photoResults = response.body().getPhoto();
for (Photos.Photo photo : photoResults) {
Log.v("PHOTO_URL:", photo.getTitle()
);
}
}
@Override
public void onFailure(Call<Photos> call, Throwable t) {
}
});
}
});
mSearchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent toSearch = new Intent(MainActivity.this, FlickRActivity.class);
startActivity(toSearch);
}
});
}
//Synchronous vs. Asynchronous
public interface ApiInterface {
@GET("?method=flickr.photos.search&api_key=1c448390199c03a6f2d436c40defd90e&format=json&nojsoncallback=1&extras=url_m")
Call<Photos> getImages(@Query("text") String query);
}
}
Request Body@POST("users/new") Call<User> createUser(@Body User user); The object will also be converted using a converter specified on the Retrofit instance. If no converter is added, only RequestBody can be used.
Retrofit is a type-safe REST client for Android, Java and Kotlin developed by Square. The library provides a powerful framework for authenticating and interacting with APIs and sending network requests with OkHttp.
Retrofit is type-safe REST client for Android and Java which aims to make it easier to consume RESTful web services.
Based on my previous answer here your model is not correct your stat: "ok"
at the end of Response is your mistake.
While you create a Photos
Object you need a parent Model to keep both attribute (photos
& stat
)
So your model would be:
public class Model {
Photos photos;
int code;
String stat;
String message; // when you text = null
public class Photos{
int page;
int pages;
int perpage;
int total;
List<Photo> photo;
public class Photo{
String id;
String owner;
String secret;
//rest of things
}
}
}
Also don't forget to change your Call<Photos>
to Call<Model>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With