Retrofit 2 - response body gives null value - android

I want to retrieve data from a web service to textview. Web service works well. I'm using retrofit for network. But I'm getting null in prmoDetails here response.body. I have checked and tried all past solutions as well. But still it's not working. Please help me to solve this.
POJO class
public class PromoDetails {
private String PromoId;
private String PromoName;
private String Category;
private String PromoImg;
private String promoDetails;
private String promoValidty;
public PromoDetails(String PromoId, String PromoName, String Category , String PromoImg , String promoDetails , String promoValidity) {
this.PromoId = PromoId;
this.PromoName = PromoName;
this.Category = Category;
this.PromoImg = PromoImg;
this.promoDetails = promoDetails;
this.promoValidty = promoValidity;
}
public String getPromoId() {
return PromoId;
}
public void setPromoId(String promoId) {
PromoId = promoId;
}
public String getPromoName() {
return PromoName;
}
public void setPromoName(String promoName) {
PromoName = promoName;
}
public String getCategory() {
return Category;
}
public void setCategory(String category) {
Category = category;
}
public String getPromoImg() {
return PromoImg;
}
public void setPromoImg(String promoImg) {
PromoImg = promoImg;
}
public String getPromoDetails() {
return promoDetails;
}
public void setPromoDetails(String promoDetails) {
this.promoDetails = promoDetails;
}
public String getPromoValidty() {
return promoValidty;
}
public void setPromoValidty(String promoValidty) {
this.promoValidty = promoValidty;
}}
Api Interface
public interface ApiInterface {
#POST("ap/promotions.php")
Call<List<PromoDetails>> getPromotions();}
MainActivity
public class MainActivity extends AppCompatActivity {
private ApiInterface apiInterface;
private List<PromoDetails> promoDetails;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getPromotionUpdate();
}
private void getPromotionUpdate() {
apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
Call<List<PromoDetails>> call = apiInterface.getPromotions();
call.enqueue(new Callback<List<PromoDetails>>() {
#Override
public void onResponse(Call<List<PromoDetails>> call, Response<List<PromoDetails>> response) {
promoDetails = response.body();
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView prDescription = (TextView)findViewById(R.id.TextView1) ;
prDescription.setText(promoDetails.get(0).getPromoId());
}
});
}
#Override
public void onFailure(Call<List<PromoDetails>> call, Throwable t) {
}
});
}}
My web service like this
[{"promoId":"7","companyName":"Pizza Hut","pName":"Connecting Dots TEDXCOLOMBO 2017","category":"EVENTS","pImg":"https:\/\/androidsra.000webhostapp.com\/img_ap\/tedx.png"},{"promoId":"6","companyName":"Subway","pName":"BUY any SUB & get another SUB FREE!","category":"FOODS & DRINKS","pImg":"https:\/\/androidsra.000webhostapp.com\/img_ap\/subway.png"},{"promoId":"5","companyName":"KFC ","pName":"40% off at Queens Hotel - Kandy for HSBC Credit cards.","category":"BANKS & CARDS","pImg":"https:\/\/androidsra.000webhostapp.com\/img_ap\/queens.png"},{"promoId":"4","companyName":"Pizza Hut","pName":"New sets of Furniture with special discounts.","category":"HOME & KITCHEN","pImg":"https:\/\/androidsra.000webhostapp.com\/img_ap\/singerfur_promo.png"},{"promoId":"3","companyName":"Browns Tours","pName":"Exclusive Offer !! Fly to Melbourne with Srilankan Airlines from Browns Tours","category":"TRAVEL","pImg":"https:\/\/androidsra.000webhostapp.com\/img_ap\/melbourne_promo.png"},{"promoId":"2","companyName":"KFC ","pName":"Hot Drumlets with 2L Pepsi for just Rs.1100\/- only","category":"FOODS & DRINKS","pImg":"https:\/\/androidsra.000webhostapp.com\/img_ap\/kfc_promo.png"},{"promoId":"1","companyName":"Pizza Hut","pName":"50% Off for Medium Pizzas.","category":"FOODS & DRINKS","pImg":"https:\/\/androidsra.000webhostapp.com\/img_ap\/pizza_promo.png"}]

I think it's because your pojo class variables doesn't match with your response variables. Either use #SerializedName annotation or basically change your pojo definitions as exactly as in your response. For example:
#SerializedName("promoId")
private String PromoId;
#SerializedName("pName")
private String PromoName;
or
private String promoId;
private String pName;

As you are not passing any data to getPromotions i presume its a get Method. make following changes in code
public interface ApiInterface {
change --------> #GET("ap/promotions.php")
Call<List<PromoDetails>> getPromotions();}
and change your pojo class to following
public class Example {
#SerializedName("promoId")
#Expose
private String promoId;
#SerializedName("companyName")
#Expose
private String companyName;
#SerializedName("pName")
#Expose
private String pName;
#SerializedName("category")
#Expose
private String category;
#SerializedName("pImg")
#Expose
private String pImg;
public String getPromoId() {
return promoId;
}
public void setPromoId(String promoId) {
this.promoId = promoId;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getPName() {
return pName;
}
public void setPName(String pName) {
this.pName = pName;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getPImg() {
return pImg;
}
public void setPImg(String pImg) {
this.pImg = pImg;
}
}

why your post method don't have any passing parameters???
Check method, is it GET or POST?
If it is GET,
then change it to #GET("ap/promotions.php") , other code will be same.

check response.isSuccessful() before getting the body, if it is false get response.errorBody() and that will show you the cause of error

Related

How to send ArrayList<Object> to other Fragment/Activity without init (start) the next Activity?

I have an ArrayList and I need to send it to another fragment. I tried to use Parcelable, but to send the data I need the "startIntent" method which starts the fragment. I don't want the fragment to be started.
I need send data array list object to another fragment without going to this other fragment. I only need to send the data. The user is free to chose when to change between activities/fragments. And the data sent earlier should already be there.
Example using Parcelable:
Class that must be to sent:
import android.os.Parcel;
import android.os.Parcelable;
public class Doenca implements Parcelable {
private String nome;
private String causa;
private String efeito;
private String cuidados;
private String prevencao;
private String categoria;
public Doenca(String nome, String causa, String efeito, String cuidados, String prevencao, String categoria) {
this.nome = nome;
this.causa = causa;
this.efeito = efeito;
this.cuidados = cuidados;
this.prevencao = prevencao;
this.categoria = categoria;
}
protected Doenca(Parcel in) {
nome = in.readString();
causa = in.readString();
efeito = in.readString();
cuidados = in.readString();
prevencao = in.readString();
categoria = in.readString();
}
public static final Creator<Doenca> CREATOR = new Creator<Doenca>() {
#Override
public Doenca createFromParcel(Parcel in) {
return new Doenca(in);
}
#Override
public Doenca[] newArray(int size) {
return new Doenca[size];
}
};
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCausa() {
return causa;
}
public void setCausa(String causa) {
this.causa = causa;
}
public String getEfeito() {
return efeito;
}
public void setEfeito(String efeito) {
this.efeito = efeito;
}
public String getCuidados() {
return cuidados;
}
public void setCuidados(String cuidados) {
this.cuidados = cuidados;
}
public String getPrevencao() {
return prevencao;
}
public void setPrevencao(String prevencao) {
this.prevencao = prevencao;
}
public String getCategoria() {
return categoria;
}
public void setCategoria(String categoria) {
this.categoria = categoria;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(nome);
dest.writeString(causa);
dest.writeString(efeito);
dest.writeString(cuidados);
dest.writeString(prevencao);
dest.writeString(categoria);
}
}
import android.os.Parcel;
import android.os.Parcelable;
public class Doenca implements Parcelable {
private String nome;
private String causa;
private String efeito;
private String cuidados;
private String prevencao;
private String categoria;
public Doenca(String nome, String causa, String efeito, String cuidados, String prevencao, String categoria) {
this.nome = nome;
this.causa = causa;
this.efeito = efeito;
this.cuidados = cuidados;
this.prevencao = prevencao;
this.categoria = categoria;
}
protected Doenca(Parcel in) {
nome = in.readString();
causa = in.readString();
efeito = in.readString();
cuidados = in.readString();
prevencao = in.readString();
categoria = in.readString();
}
public static final Creator<Doenca> CREATOR = new Creator<Doenca>() {
#Override
public Doenca createFromParcel(Parcel in) {
return new Doenca(in);
}
#Override
public Doenca[] newArray(int size) {
return new Doenca[size];
}
};
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCausa() {
return causa;
}
public void setCausa(String causa) {
this.causa = causa;
}
public String getEfeito() {
return efeito;
}
public void setEfeito(String efeito) {
this.efeito = efeito;
}
public String getCuidados() {
return cuidados;
}
public void setCuidados(String cuidados) {
this.cuidados = cuidados;
}
public String getPrevencao() {
return prevencao;
}
public void setPrevencao(String prevencao) {
this.prevencao = prevencao;
}
public String getCategoria() {
return categoria;
}
public void setCategoria(String categoria) {
this.categoria = categoria;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(nome);
dest.writeString(causa);
dest.writeString(efeito);
dest.writeString(cuidados);
dest.writeString(prevencao);
dest.writeString(categoria);
}
}
There are multiple ways with different complexity for the implementation.
Use a database to store what you need there
Store the data in the host activity containing the tabs. As soon as you switch the fragment, all you need to do is read the data from the place where you have stored it.
Use LiveData. LiveData would be my personal preference. There you can easily store any data you need and the second fragment simply observes the livedata and can easily react to changes. So you could even switch in both directions as often as you want to.
Try Using EventBus.
To use EventBus, you need to first add it to in the app module build.gradle file
implementation 'org.greenrobot:eventbus:3.1.1'
and then sync your project.
An Event Subscriber
A subscriber simply subscribes to an event by registering in the event bus and can also unregister that event. To be a subscriber, you have to do three main things:
Register the subscriber in the event bus with register(). This informs the event bus that you want to begin receiving events. In an activity, this is in the onStart() method, while in a fragment put this in the onAttact(Activity activity) method.
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
Unregister the subscriber, which means tell the event bus to stop sending me events. In an activity, this is in the onStop() method, while in a fragment put this in the onDetach() method.
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
Implement the onEvent() to indicate the type of event you want to receive and action to take when you receive the event. Notice the #Subscribe annotation at the top of this method.
#Subscribe
public void onEvent(MessageEvent event) {
Toast.makeText(this, "Hey, my message" + event.getMessage(),
Toast.LENGTH_SHORT).show();.
}
Defining Event Messages
The events in greenrobot EventBus are just objects that you define. You can have different event classes if you want. They do not inherit any base class or interface—they're just POJO (Plain Old Java Objects).
public class MessageEvent {
public final List<SomeItem> items;
public MessageEvent(List<SomeItem> items) {
this.items= items;
}
}
Post Event
EventBus.getDefault().post(new MessageEvent("Hey event subscriber!"));

Trying to add relations in Backendless. No error but total count of relations added is always 0

Hi guys I am trying to save objects with relations in Backendless via API. I have two classes namely Task and Reminder. A task can be associated with many reminders hence I want a 1:N relationship between the Task table and Reminder table in Backendless. My Task class is as follows:
public class Task {
public Date created;
public Date updated;
private List<Reminder> reminders = null;
private String ownerId;
#PrimaryKey
#NonNull
private String objectId;
#NonNull
private String taskTitle;
#NonNull
private Date deadline;
#NonNull
private int isCompleted = 0;
#NonNull
private int isExpired = 0;
public String getOwnerId() {
return ownerId;
}
public void setOwnerId(String ownerId) {
this.ownerId = ownerId;
}
#NonNull
public String getObjectId() {
return objectId;
}
public void setObjectId(#NonNull String objectId) {
this.objectId = objectId;
}
public List<Reminder> getReminders() {
return reminders;
}
public void setReminders(List<Reminder> reminders) {
this.reminders = reminders;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getUpdated() {
return updated;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
#NonNull
public int getIsCompleted() {
return isCompleted;
}
public void setIsCompleted(#NonNull int isCompleted) {
this.isCompleted = isCompleted;
}
#NonNull
public int getIsExpired() {
return isExpired;
}
public void setIsExpired(#NonNull int isExpired) {
this.isExpired = isExpired;
}
public String getTaskTitle() {
return taskTitle;
}
public void setTaskTitle(String taskTitle) {
this.taskTitle = taskTitle;
}
public Date getDeadline() {
return deadline;
}
public void setDeadline(Date deadline) {
this.deadline = deadline;
}
}
Reminder Class:
public class Reminder {
private String title;
private Date time;
private String objectId;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public String getObjectId() {
return objectId;
}
public void setObjectId(String objectId) {
this.objectId = objectId;
}
}
I am saving the objects and setting up the relation as below:
public void saveTaskToServer(final Task task) {
List<Reminder> remindersList = new ArrayList<>();
remindersList = task.getReminders();
final List<Reminder> savedReminders = new ArrayList<>();
if(remindersList!=null && remindersList.size()!=0) {
for
(Reminder reminder : remindersList) {
reminder.setTitle(task.getTaskTitle());
Backendless.Persistence.save(reminder, new AsyncCallback<Reminder>() {
#Override
public void handleResponse(Reminder response) {
savedReminders.add(response);
}
#Override
public void handleFault(BackendlessFault fault) {
Log.i("error saving remidners", fault.toString());
}
});
}
}
Backendless.Persistence.save(task, new AsyncCallback<Task>() {
#Override
public void handleResponse(Task response) {
newTask = response;
Log.i("id is ", newTask.getObjectId());
insertTask(response);
snackbarMessage.postValue("Task Created Successfully.");
}
#Override
public void handleFault(BackendlessFault fault) {
Log.i("error", fault.getMessage());
}
});
Backendless.Persistence.of(Task.class).addRelation(task, "reminders", savedReminders, new AsyncCallback<Integer>() {
#Override
public void handleResponse(Integer response) {
Log.i("response", "added" + response);
newTask.setReminders(savedReminders);
}
#Override
public void handleFault(BackendlessFault fault) {
Log.i("response", "error" + fault.toString());
}
});
}
I have tried saving the relation using the tablename:Class:n instead of the parentColumnName. Also tried saving the objectids of the reminders instead of the reminder objects themselves.The task and reminder objects get saved properly in the backendless console in their respective tables but the reminder column in the Task table still remains empty and no relations get added. Relations count in the backendless call in Android Studio also returns 0. Any advice is really appreciated. I have been following this example.
My relations were not getting saved because I was using the async callbacks in backendless!! I dont know why I didnt see that before. Since the save calls were being made before the async callbacks could finish I was ending up with null values. Fixed it by making the calls synchronous and wrapping them in an async task.

Combining 2 RealmList object in realm android

How to use realm relationships using 2 RealmList, here the example.
Class Menu
public class Menu extends RealmObject {
#SerializedName("name")
private String name;
#SerializedName("module")
private String module;
#SerializedName("controller")
private String controller;
#SerializedName("parent_module")
private String parentModule;
#SerializedName("status")
private Boolean status;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getModule() {
return module;
}
public void setModule(String module) {
this.module = module;
}
public String getController() {
return controller;
}
public void setController(String controller) {
this.controller = controller;
}
public String getParentModule() {
return parentModule;
}
public void setParentModule(String parentModule) {
this.parentModule = parentModule;
}
public Boolean getStatus() {
return status;
}
public void setStatus(Boolean status) {
this.status = status;
}
}
Class Privilege
public class Privilege extends RealmObject {
private String module;
public String getModule() {
return module;
}
public void setModule(String module) {
this.module = module;
}
}
and i'm using this method to save them.
#Override
public void saveMenuPrivilege(RealmList<Menu> menu, RealmList<Privilege> privileges) {
}
now what makes me confuse is, there is a condition where if the module in class Menu has the same module in class Privilege, then set the active field for that module in class Menu to be "true". How to do that? or i'm doing it wrong using the code above?
Thanks in advance
All ready have the answer, just testing all by myself. :D

How to retrieve web service values through Retrofit to text view?

I'm developing an app and in first activity it has card view layout. I'm retrieving data from a webservice and relevant data are showed in card view. It's working well. Now when a user clicks a particular card view I need to go for another activity. I'm getting relevant ID for that card view and passing it to the second activity. In second activity I need to show the content according to that unique Id. But I'm not getting any thing. This is what I tried.
Pojo class
public class PromoDetails {
String PromoId;
String PromoName;
String PromoImg;
String promoDetails;
String promoValidty;
public PromoDetails(String PromoId, String PromoName, String PromoImg , String promoDetails , String promoValidity) {
this.PromoId = PromoId;
this.PromoName = PromoName;
this.PromoImg = PromoImg;
this.promoDetails = promoDetails;
this.promoValidty = promoValidity;
}
public String getPromoId() {
return PromoId;
}
public void setPromoId(String promoId) {
PromoId = promoId;
}
public String getPromoName() {
return PromoName;
}
public void setPromoName(String promoName) {
PromoName = promoName;
}
public String getPromoImg() {
return PromoImg;
}
public void setPromoImg(String promoImg) {
PromoImg = promoImg;
}
public String getPromoDetails() {
return promoDetails;
}
public void setPromoDetails(String promoDetails) {
this.promoDetails = promoDetails;
}
public String getPromoValidty() {
return promoValidty;
}
public void setPromoValidty(String promoValidty) {
this.promoValidty = promoValidty;
}}
ApiInterface
public interface ApiInterface {
#POST("ap/promotions.php")
Call<List<Promotions>> getPromotions();
#GET("test.php/promotions/{PromoId}")
Call<List<PromoDetails>> getPromotDetails(#Path("PromoId") String PromoId) ;}
New Activity class
public class PromotionsInside extends Activity {
private ApiInterface apiInterface;
private List<PromoDetails> promoDetails;
TextView prDescription;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.promo_inside);
Bundle extras = getIntent().getExtras();
String promoId = "";
if (extras != null) {
promoId = extras.getString("PROMO_ID");
getPromotionUpdate(promoId);
}
}
private void getPromotionUpdate(String myPromoId) {
apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
Call<List<PromoDetails>> call = apiInterface.getPromotDetails(myPromoId);
call.enqueue(new Callback<List<PromoDetails>>() {
#Override
public void onResponse(Call<List<PromoDetails>> call, Response<List<PromoDetails>> response) {
promoDetails = response.body();
runOnUiThread(new Runnable() {
#Override
public void run() {
prDescription = (TextView)findViewById(R.id.promoDescriptionsss) ;
prDescription.setText(promoDetails.get(0).getPromoName());
}
});
}
#Override
public void onFailure(Call<List<PromoDetails>> call, Throwable t) {
}
});
}}
I have similar case. Try to use this to start second activity:
Intent intent = new Intent(this, PromotionsInside.class);
//Make sure that you put String id in intent
intent.putExtra("PROMO_ID", id);
startActivity(intent);
And this in second activity:
if (getIntent().hasExtra("PROMO_ID")) {
String id = getIntent().getStringExtra("PROMO_ID", null);
//next steps that you need
}
Hope it will help you

How to add data to list and use its data on next page and show in listview

I have 2 class one is login_class second is student_class which is showing details of student.
What i have to do is when i login. In response i get the students details like
student_name,student_srno,student_father_name,student_mother_name etc.
This is my bean(Getter Setter) class
package com.smartschoolapp;
public class Bean {
String username, password, srno, studentname, classname, sec, contact,
father_name, mother_name, dob;
public Bean(String username,String password,String srno,String studentname,String classname,String sec,String contact,String father_name,String mother_name,String dob) {
this.username=username;
this.password= password;
this.srno=srno;
this.studentname=studentname;
this.classname=classname;
this.sec=sec;
this.contact=contact;
this.father_name=father_name;
this.mother_name=mother_name;
this.dob =dob;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSrno() {
return srno;
}
public void setSrno(String srno) {
this.srno = srno;
}
public String getStudentname() {
return studentname;
}
public void setStudentname(String studentname) {
this.studentname = studentname;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public String getSec() {
return sec;
}
public void setSec(String sec) {
this.sec = sec;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public String getFather_name() {
return father_name;
}
public void setFather_name(String father_name) {
this.father_name = father_name;
}
public String getMother_name() {
return mother_name;
}
public void setMother_name(String mother_name) {
this.mother_name = mother_name;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public Bean() {
}
}
And this is my login_class where i add data of the student in list.
class login_class extends activity{
Bean beanobj;
List student_detail_list;
.....
{
String name = getting data from response;
......... so on
beanobj = new Bean();
beanobj.studentname(name);
beanobj.student_parent_name(parentname);
.............so on
}
order_list.add(beanobj); // the details to list
}
Now the next activity student_class where i want to show the student in listview
public class student_class extends Activity {
ListView student_listview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.student_list);
student_listview = (ListView) findViewById(R.id.student_listview);
}
}
*==>> in login_class i have created List student_detail_list how can i get it in my student_class class and retrieve data .
Thanks
There are a lot a ways to do that. 1.Recommended Solution : How to pass an object from one activity to another on Android you can serialize your objects and put it into the intent. This is the recommended solution but there are some problems here. If your data contains a lot of memory, it might crash your application in runtime.
2. You can save your array into the file, send file path to other activity as with URL. In the second activity read the file and create the array in second activity as well.
3. My favourite solution is create a singleton class for student array, reach the class in any activity you want. But you should be careful because singleton pattern has some issues by design also it will stay in memory all the time
Realize the "class Bean implements Parcelable". When go to "student_class" from "login_class", just put the "student bean data" inside the Intent. After going to student_class, you can get the "student bean data" from the intent, here the sample code:
Intent intent = new Intent(login_class.this, student_class.class)
intent.putParcelableArrayListExtra("content", student_detail_list);
startActivity(intent);
In "student_class":
student_detail_list = getIntent().getParcelableArrayListExtra("content");

Categories

Resources