I am parsing the JSON array successfully. But I have a String which has numbers. So I want to sort all the data according to the numbers. I had been checked so many examples but I couldn't implement them in my code.So please help me.
Here is my code. here the "count" is the, string threw which I want to sort the data.
a.java
#Override
protected Void doInBackground(Void... params) {
ServiceHandler serviceHandler = new ServiceHandler();
String jsonStr = serviceHandler.makeServiceCall(
JSONUrl.categoriesUrl, ServiceHandler.GET);
Log.d("Response Categories:", ">" + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
categoriesJSONArray = jsonObj
.getJSONArray(JSONUrl.TAG_DATA);
for (int i = 0; i < categoriesJSONArray.length(); i++) {
JSONObject c = categoriesJSONArray.getJSONObject(i);
GridViewItem gridCategoriesItem = new GridViewItem();
gridCategoriesItem.setSlug(c
.getString(JSONUrl.TAG_CATEGORIES_SLUG));
gridCategoriesItem.setImage(c
.getString(JSONUrl.TAG_CATEGORIES_IMAGE));
gridCategoriesItem.setCount(c
.getString(JSONUrl.TAG_CATEGORIES_COUNT));
mGridArrayCategories.add(gridCategoriesItem);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.d("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
GridViewItem.java
public class GridViewItem {
String image;
String slug;
String count;
String name;
public GridViewItem() {
super();
}
public GridViewItem(String image, String slug, String count,
String name) {
super();
this.image = image;
this.slug = slug;
this.count = count;
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getSlug() {
return slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Instead of using bubble sort which is o(n2).
You can use the native sort from the Collection class
example:
Collections.sort(mGridArrayCategories, new Comparator<GridViewItem>() {
public int compare(GridViewItem s, GridViewItem s2) {
return Integer.parseInt(s2.getCount()) - Integer.parseInt(s.getCount()); //this will sort your arrayList in decending order
}
});
You need to parse your string to int so it will be sorted according to the count
You can use Collection.sort().
for sorting any kind of ArrayLsit Object.
Collections.sort(listOfStringArrays,new Comparator<String[]>() {
public int compare(String[] strings, String[] otherStrings) {
return strings[1].compareTo(otherStrings[1]);
}
});
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
I am trying to call login API using Retrofit2.
But in onResponse i alwasy get null as response.
Login API endpoint
#FormUrlEncoded
#POST("/api/login/{mobile}")
Call<ResObj> userLogin( #Field("phoneNumber") String mobile );
And the API implementation
private void doLogin(final String mobile){
Call<ResObj> call = userService.login(mobile);
call.enqueue(new Callback<ResObj>() {
#Override
public void onResponse(Call<ResObj> call, Response<ResObj> response) {
ResObj resObj = response.body(); // here i am getting null response.body()
if(resObj.getMessage().equals("true")){
Intent intent = new Intent(Login.this, ListActivity.class);
intent.putExtra("mobile", mobile);
startActivity(intent);
} else{
Toast.makeText(Login.this, "Phone Number is incorrect!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<ResObj> call, Throwable t) {
Toast.makeText(Login.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
ResObj class:
public class ResObj {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
I just want to know what causes the error and what are possible solutions.
UPDATE
POSTMAN
You are getting null response in your login API. It may be due to many reasons. You can check your API is working as expected or not using POSTMAN.
And inside your code, you can prevent this type of exception by checking OBJECT is null or not. like the following.
#Override
public void onResponse(Call<ResObj> call, Response<ResObj> response) {
ResObj resObj = response.body();
if(resObj != null){ // checking object is not null
if(resObj.getStatus()){
Intent intent = new Intent(Login.this, ListActivity.class);
intent.putExtra("mobile", mobile);
startActivity(intent);
} else{
Toast.makeText(Login.this, "Phone Number is incorrect!", Toast.LENGTH_SHORT).show();
}
}else{
// handle null response here.
}
}
Update:
According to your Response JSON, Your Model(ResObj) class should be like the following.
public class ResObj
{
private String date;
private String address;
private String accountName;
private String contactPerson;
private String timeOut;
private String problem;
private String srNo;
private String fieldEngineer;
private String joNo;
private String irNo;
private String designation;
private String email;
private String timeIn;
private String productType;
private boolean status;
private String contactNo;
public String getDate ()
{
return date;
}
public void setDate (String date)
{
this.date = date;
}
public String getAddress ()
{
return address;
}
public void setAddress (String address)
{
this.address = address;
}
public String getAccountName ()
{
return accountName;
}
public void setAccountName (String accountName)
{
this.accountName = accountName;
}
public String getContactPerson ()
{
return contactPerson;
}
public void setContactPerson (String contactPerson)
{
this.contactPerson = contactPerson;
}
public String getTimeOut ()
{
return timeOut;
}
public void setTimeOut (String timeOut)
{
this.timeOut = timeOut;
}
public String getProblem ()
{
return problem;
}
public void setProblem (String problem)
{
this.problem = problem;
}
public String getSrNo ()
{
return srNo;
}
public void setSrNo (String srNo)
{
this.srNo = srNo;
}
public String getFieldEngineer ()
{
return fieldEngineer;
}
public void setFieldEngineer (String fieldEngineer)
{
this.fieldEngineer = fieldEngineer;
}
public String getJoNo ()
{
return joNo;
}
public void setJoNo (String joNo)
{
this.joNo = joNo;
}
public String getIrNo ()
{
return irNo;
}
public void setIrNo (String irNo)
{
this.irNo = irNo;
}
public String getDesignation ()
{
return designation;
}
public void setDesignation (String designation)
{
this.designation = designation;
}
public String getEmail ()
{
return email;
}
public void setEmail (String email)
{
this.email = email;
}
public String getTimeIn ()
{
return timeIn;
}
public void setTimeIn (String timeIn)
{
this.timeIn = timeIn;
}
public String getProductType ()
{
return productType;
}
public void setProductType (String productType)
{
this.productType = productType;
}
public boolean getStatus ()
{
return status;
}
public void setStatus (boolean status)
{
this.status = status;
}
public String getContactNo ()
{
return contactNo;
}
public void setContactNo (String contactNo)
{
this.contactNo = contactNo;
}
}
You are passing parameter as raw data(according to your screen-shot). So your API endpoint would be like below.
#Headers("Content-Type: application/json")
#POST("/api/login")
Call<ResObj> userLogin(#Body JsonObject jsonObject);
And call your API like this
private void doLogin(final String mobile){
try {
JsonObject paramObject = new JsonObject();
paramObject.addProperty("mobile", mobile);
} catch (JSONException e) {
e.printStackTrace();
}
Call<ResObj> call = userService.login(paramObject);
call.enqueue(new Callback<ResObj>() {
//your rest of code
});
}
UPDATE-2:
To send object from one Activity to another using intent you have to make your model class Percelable. like this
// implements Parcelable
public class ResObj implements Parcelable {
// ...........your previous code here
// just simply add the following methods
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(date);
dest.writeString(address);
dest.writeString(accountName);
dest.writeString(contactPerson);
dest.writeString(timeOut);
dest.writeString(problem);
dest.writeString(srNo);
dest.writeString(fieldEngineer);
dest.writeString(joNo);
dest.writeString(irNo);
dest.writeString(designation);
dest.writeString(email);
dest.writeString(timeIn);
dest.writeString(productType);
dest.writeByte((byte) (status ? 1 : 0));
dest.writeString(contactNo);
}
public static final Parcelable.Creator<ResObj> CREATOR
= new Parcelable.Creator<ResObj>() {
public ResObj createFromParcel(Parcel in) {
return new ResObj(in);
}
public ResObj[] newArray(int size) {
return new ResObj[size];
}
};
protected ResObj(Parcel in) {
date = in.readString();
address = in.readString();
accountName = in.readString();
contactPerson = in.readString();
timeOut = in.readString();
problem = in.readString();
srNo = in.readString();
fieldEngineer = in.readString();
joNo = in.readString();
irNo = in.readString();
designation = in.readString();
email = in.readString();
timeIn = in.readString();
productType = in.readString();
status = in.readByte() != 0;
contactNo = in.readString();
}
}
Now pass your object via intent like the following.
if(resObj != null){
if(resObj.getStatus()){
Intent intent = new Intent(Login.this, ListActivity.class);
intent.putExtra("your_key", resObj); // pass resObj and use same key to get data
startActivity(intent);
} else{
Toast.makeText(Login.this, "Phone Number is incorrect!", Toast.LENGTH_SHORT).show();
}
}
Get data from your ListActivity like this
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
final ResObj yourObject = getIntent().getParcelableExtra("your_key"); // make sure you use same key like data.
// Now you can use your data like that
yourEditText.setText(yourObject.getEmail());
}
I'm doing a Movie Project, I want to use parsing JSON to listview, I'm using loopj library, I already implement the code, but it does not work, the listview is still empty, I don't know where the error this is my code, I will show the item class first,
public class MovieItem {
private int id;
private String title;
private String description;
private String rate;
public MovieItem(JSONObject object){
try {
String title = object.getJSONArray("results").getJSONObject(0).getString("title");
String description = object.getJSONArray("results").getJSONObject(0).getString("overview");
double movieRatet = object.getJSONArray("results").getJSONObject(0).getDouble("vote_average");
String movieRate = new DecimalFormat("#.#").format(movieRatet);
this.title = title;
this.description = description;
this.rate = movieRate;
}
catch (Exception e){
e.printStackTrace();
}
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getRate() {
return rate;
}
public void setRate(String rate) {
this.rate = rate;
}
}
next, the loader is
public ArrayList<MovieItem> loadInBackground() {
Log.d("LOAD BG","1");
SyncHttpClient client = new SyncHttpClient();
final ArrayList<MovieItem> movieItemses = new ArrayList<>();
final String url = "https://api.themoviedb.org/3/search/movie?api_key="+API_KEY+"&language=en-US&query=annabelle";
client.get(url, new AsyncHttpResponseHandler() {
#Override
public void onStart() {
super.onStart();
setUseSynchronousMode(true);
}
#Override
public void onSuccess(int statusCode, Header[] headers,
byte[] responseBody) {
try {
String result = new String(responseBody);
JSONObject responseObject = new JSONObject(result);
JSONArray list = responseObject.getJSONArray("list");
for (int i = 0 ; i < list.length() ; i++){
JSONObject movie = list.getJSONObject(i);
MovieItem movieItems = new MovieItem(movie);
movieItemses.add(movieItems);
}
Log.d("REQUEST SUCCESS","1");
}catch (Exception e){
e.printStackTrace();
Log.d("REQUEST FAILED","1");
}
}
#Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
}
});
for (int i = 0 ; i< movieItemses.size() ; i++){
Log.d("Title",movieItemses.get(i).getTitle());
}
Log.d("BEFORE RETURN","1");
return movieItemses;
}
protected void onReleaseResources(ArrayList<MovieItem> data) {
//nothing to do.
}
pls someone help me, I already fix this problem, but nothing different
FYI I'm using API from themoviedb
I'm using volley and gson libs in my Android app which main purpose is to call to the server API and retrieve some data.
Everything works well, expect for nested JSON object data. I can't retrieve information (lat, lng) which are inside position object.
It throws an error:
Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 99 path $.position and points out to deliveryResponse method.
Example of my JSON:
[{"number":18,"name":"John","address":"John Street.","position":{"lat":12.68300406,"lng":45.28001237},"status":"OPEN"},{"number":18,"name":"John","address":"John Street.","position":{"lat":12.68300406,"lng":45.28001237},"status":"OPEN",}]
deliveryResponse method:
#Override
protected void deliverResponse(JSONArray jsonArray) {
if (mListener != null && jsonArray != null) {
List<T> responseArray = new ArrayList<T>();
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject entry = jsonArray.getJSONObject(i);
T parsedResponse = new Gson().fromJson(entry.toString(), mClass);
if (parsedResponse != null) {
responseArray.add(parsedResponse);
}
} catch (JSONException e) {
Log.d(TAG, "Error parsing JSON Object: " + e.getMessage());
mListener.onResponse(jsonArray);
}
}
mListener.onGsonResponse(responseArray);
}
}
Object class:
public class Object {
private int number;
private String name;
private String address;
private List<PositionObj> position;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<PositionObj> getPosition() {
return position;
}
public void setPosition(List<PositionObj> position) {
this.position = position;
}
PositionObj class:
public class PositionObj {
private int lat;
private int lng;
public int getLat() {
return lat;
}
public void setLat(int lat) {
this.lat = lat;
}
public int getLng() {
return lng;
}
public void setLng(int lng) {
this.lng = lng;
}
What do you sugggest?
In your JSON, position is an object and not an array. So, in your class Object(weird name), change private List<PositionObj> position; by private PositionObj position;.
I am trying to save an enum 'Status' into a custom class that implements parcelable. I have found online how I can save Strings, ints or enums in one class that implements parcelable, but not how I can save these three things all at once. I am sorry if the solution is obvious, but I just can't figure it out.
Here is what my enum looks like:
public enum Status {
INITIALIZED, UPDATED, DELETED
}
And this is what I have so far:
public class Recipe implements Parcelable{
private String id;//this should be an int, same problem
private String recipeName;
private String recipePreperation;
private Status status;
private final static int MAX_PREVIEW = 50;
public Recipe(int parId, String parRecipeName, String parRecipePreperation) {
this.id = "" + parId;
this.recipeName = parRecipeName;
this.recipePreperation = parRecipePreperation;
this.status = Status.INITIALIZED;
}
public Recipe(Parcel in){
String[] data = new String[4];
in.readStringArray(data);
this.id = data [0];
this.recipeName = data[1];
this.recipePreperation = data[2];
this.status = data[3];//what I intend to do, I know this is wrong
}
public int GetId() {
return Integer.parseInt(id);
}
public String GetRecipeName() {
return this.recipeName;
}
public void SetRecipeName(String parRecipeName) {
this.recipeName = parRecipeName;
}
public String GetRecipePreperation() {
return this.recipePreperation;
}
public void SetRecipePreperation(String parRecipePreperation) {
this.recipePreperation = parRecipePreperation;
}
public Status GetStatus() {
return this.status;
}
public void SetStatus(Status parStatus) {
this.status = parStatus;
}
public String toString() {
String recipe = this.recipeName + "\n" + this.recipePreperation;
String returnString;
int maxLength = MAX_PREVIEW;
if (recipe.length() > maxLength) {
returnString = recipe.substring(0, maxLength - 3) + "...";
} else {
returnString = recipe;
}
return returnString;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int arg1) {
dest.writeStringArray(new String [] {
this.id,
this.recipeName,
this.recipePreperation,
this.status//what I intend to do, I know this is wrong
});
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Recipe createFromParcel(Parcel in) {
return new Recipe(in);
}
public Recipe[] newArray(int size) {
return new Recipe[size];
}
};
}
How do I save an int, an array of strings and an enum into a class that implements the parcelable, so it can writeToParcel()?
There's no need to read and write to/from string array. Just write each string and finally the status as Serializable. This is how I fix it.
public Recipe(Parcel in){
this.id = in.readString();
this.recipeName = in.readString();
this.recipePreperation = in.readString();
this.status = (Status) in.readSerializable();
}
public void writeToParcel(Parcel dest, int arg1) {
dest.writeString(this.id);
dest.writeString(this.recipeName);
dest.writeString(this.recipePreperation);
dest.writeSerializable(this.status);
}
As a follow on from my last question: Passing Arraylist between activities? Using Parcelable
I'm now attempting to pass my ArrayList via Parcelable. However, when it's gotten from the other activity it returns null. I can't seem to figure out why. I've got the following...
ResultsList.java
public class ResultsList extends ArrayList<SearchList> implements Parcelable {
/**
*
*/
private static final long serialVersionUID = -78190146280643L;
public ResultsList(){
}
public ResultsList(Parcel in){
readFromParcel(in);
}
#SuppressWarnings({ "rawtypes" })
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public ResultsList createFromParcel(Parcel in) {
return new ResultsList(in);
}
public Object[] newArray(int arg0) {
return null;
}
};
private void readFromParcel(Parcel in) {
this.clear();
//First we have to read the list size
int size = in.readInt();
//Reading remember that we wrote first the Name and later the Phone Number.
//Order is fundamental
for (int i = 0; i < size; i++) {
String title = in.readString();
String Des = in.readString();
String message = in.readString();
SearchList c = new SearchList(title,Des,link);
this.add(c);
}
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
int size = this.size();
//We have to write the list size, we need him recreating the list
dest.writeInt(size);
//We decided arbitrarily to write first the Name and later the Phone Number.
for (int i = 0; i < size; i++) {
SearchList c = this.get(i);
dest.writeString(c.gettitle());
dest.writeString(c.getDescription());
dest.writeString(c.getmessage());
}
}
}
SearchList.java
public class SearchList {
private String title;
private String description;
private String message;
public SearchList(String name, String phone, String mail) {
super();
this.title = name;
this.description = phone;
this.message = mail;
}
public String gettitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getmessage() {
return message;
}
public void setmessage(String link) {
this.message = message;
}
}
listOfResults is declared as ResultsList listOfResults = new ResultsList(); and filled earlier in the code It's then sent with...
Intent intent = new Intent(this ,newthing.class);
Bundle b = new Bundle();
b.putParcelable("results", listOfResults);
startActivityForResult(intent,0);
Receiving...
Bundle extras = getIntent().getExtras();
ResultsList results = extras.getParcelable("results");
I'd like to point out I'm testing this null thing by checking the size() of the Arraylist going into the Bundle and then it coming out. It goes in fine and comes out null.
Didn't attach bundle to intent! (doh!) was pointed out by a kind gent on IRC! #android-dev