Sorting JSON data by name issue in Android - android

I am trying to order my JSON data by name, I've found some answers here, but nothing works for my case. I have tried to update my code as you see below. I marked there what I have removed from original code, and what have I added:
#Override
protected Boolean doInBackground(String... args) {
HttpHandler sh = new HttpHandler();
String url = "androidnews.json";
String jsonStr = sh.makeServiceCall(url);
if (jsonStr != null) {
try {
//removed this:
//JSONObject jsonObj = new JSONObject(jsonStr);
//JSONArray actors = jsonObj.getJSONArray("result");
//ADDED:
ArrayList<JSONObject> array = new ArrayList<JSONObject>();
JSONArray actors = new JSONArray("result");
for (int i = 0; i < actors.length(); i++) {
JSONObject c = actors.getJSONObject(i);
//ADDED:
array.add(actors.getJSONObject(i));
Actors actor = new Actors();
actor.setName(c.getString("name"));
actor.setThumb(c.getString("thumb"));
actorsList.add(actor);
}
//ADDED:
Collections.sort(array, new Comparator<JSONObject>() {
#Override
public int compare(JSONObject lhs, JSONObject rhs) {
// TODO Auto-generated method stub
try {
return (lhs.getString("name").toLowerCase().compareTo(rhs.getString("name").toLowerCase()));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return 0;
}
}
});
} catch (final JSONException e) {
Zoznam.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(Zoznam.this.getApplicationContext(),
"Data error " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}); }
return true;
} else {
Zoznam.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(Zoznam.this.getApplicationContext(),
"Chyba internetového pripojenia.",
Toast.LENGTH_LONG).show();
}
});
return false;
}
}
But after I test it, I have this error: Value result of type java.lang.String cannot be converted to JSONArray
My JSON begins with: {"result": [{"name": "Joe","thumb": "image.jpg",...

Instead of sorting your JSONArray try sorting your Arraylist with custom object and use it. you can do something like this
Collections.sort(actorsList, new Comparator<Actors>() {
#Override
public int compare(Actors lhs, Actors rhs) {
return lhs.getName().compareTo(rhs.getName());
}
});

A solution to your current problem:
Im guessing that you are using the org.json library.
Currently you are trying to create a JSONArray from the string "result".
This is how you access an array within the JSON file:
JSONObject obj = new JSONObject(Files.readAllLines(Paths.get("/path/to/your/file.json")));
JSONArray arr = obj.getJSONArray("number");
Source: more helpful examples like the one above
Further information:
As it seems like your not to familiar with the org.json approach I would highly recommend taking a look at gson as it provides an easy way to map JSON entries to objects (or even Arrays of an Object).
See: this and this

Related

How to instantiate a new JSONObject Arraylist which takes the value of the Arraylist returned by a function?

My defined function returns a JSONObejct Arraylist, however, when I instantiate a new Arraylist to the output of the function, it shows an empty Arraylist. How can I fix this issue and why is it showing an empty array list when it is indeed returning an Arraylist in the function?
Here is the code :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activty_departures);
departure_flights = doGetRequest();
}
//my function
private ArrayList<JSONObject> doGetRequest() {
OkHttpClient client = new OkHttpClient();
ArrayList<JSONObject> departureObject = new ArrayList<>();
String url = "http_url";
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()) {
try {
String jsonData = response.body().string();
JSONObject Jobject = new JSONObject(jsonData);
JSONArray jarray = Jobject.getJSONArray("Flights");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
String adft = object.getString("Adft");
if (adft.equals("D")) {
departureObject.add(object);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
return departureObject;
Hitting Api in android not getting immediately return data it depends upon your response.
you are to return the list immediately so you received an empty list if you can work inside the onResponse method then your problem is solved.
Don't use .equals() method on String, but use .contentEquals(). The reason for this is because contentEquals() checks the content of a String and compares it to StringBuffer, StringBuilder and CharSequence aswell and all derived classes of these.
This is why in your case adft.equals("D") could return false even though adft is in the background this:
String adft = "D";
The reason for that is because equals() will only compare String objects, so all other objects are considered not equal and it will return false.
More on that here: https://www.programmersought.com/article/2993983603/
Also, sometimes returned values can store a space we dont need, so insted "D" we have "D " or " D". To solve this just use method .trim()
if(adft.trim().contentEquals("D"))
You're returning the list immediately after enqueue your API. Your ArrayList fill after API request succeeds so you have to create your ArrayList global and fill that after onSuccess. After that create another method to render your data on UI. like mentioned below:
ArrayList<JSONObject> departureObject = new ArrayList<>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activty_departures);
doGetRequest();
}
private void doGetRequest() {
OkHttpClient client = new OkHttpClient();
String url = "http_url";
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()) {
try {
String jsonData = response.body().string();
JSONObject Jobject = new JSONObject(jsonData);
JSONArray jarray = Jobject.getJSONArray("Flights");
for (int i = 0; i < jarray.length(); i++) {
JSONObject object = jarray.getJSONObject(i);
String adft = object.getString("Adft");
if (adft.equals("D")) {
departureObject.add(object);
}
}
reloadData();
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
private void reloadData() {
// here your data is ready
}

How to sort a jsonarray data by Date & Time and put in list view adapter

here my jsonArray data like:
[{"LeadId":4,
"CoreLeadId":0,
"CompanyId":7,
"AccountNo":"5675",
"ScheduleOn":"2015-05-11T00:00:00"},
{"LeadId":7,
"CoreLeadId":2,
"CompanyId":8,
"AccountNo":"sample string 4",
"ScheduleOn":"2015-12-01T15:04:23.217"}]
i want to sort by dateandtime(ScheduleOn) and put into listview. below i side i send snnipt of my code where i set adapter. can we sort into listItemService. Please help me.
JSONArray jsonArray = dpsFunctionFlow.getAllServiceDetail("1");
listItemService = new Gson().fromJson(jsonArray.toString(),
new TypeToken<List<AppointmentInfoDto>>() {
}.getType());
mAdapter = new AdapterAppointment(getActivity(), listItemService);
listView.setAdapter(mAdapter);
You should be able to use Collections.sort(...) passing in a Comparator that will compare 2 AppointmentInfoDto objects.
Collections.sort(listItemService, new Comparator<AppointmentInfoDto>() {
#Override public int compare(AppointmentInfoDto l, AppointmentInfoDto r) {
// Compare l.ScheduleOn and r.ScheduleOn
}
}
/// Sort JSON By any Key for date
public static JSONArray sortJsonArray(JSONArray array,final String key, final boolean isCase) {
List<JSONObject> jsonsList = new ArrayList<JSONObject>();
try {
for (int i = 0; i < array.length(); i++) {
jsonsList.add(array.getJSONObject(i));
}
Collections.sort(jsonsList, new Comparator<JSONObject>() {
#Override
public int compare(JSONObject v_1, JSONObject v_2) {
String CompareString1 = "", CompareString2 = "";
try {
CompareString1 = v_1.getString(key); //Key must be present in JSON
CompareString2 = v_2.getString(key); //Key must be present in JSON
} catch (JSONException ex) {
// Json Excpetion handling
}
return CompareString1.compareTo(CompareString2);
}
});
} catch (JSONException ex) {
// Json Excpetion handling
}
return new JSONArray(jsonsList);
}
// _Sort JSON for any String Key value.........
public static JSONArray sortJsonArray(JSONArray array,final String key, final boolean isCase) {
List<JSONObject> jsonsList = new ArrayList<JSONObject>();
try {
for (int i = 0; i < array.length(); i++) {
jsonsList.add(array.getJSONObject(i));
}
Collections.sort(jsonsList, new Comparator<JSONObject>() {
#Override
public int compare(JSONObject v_1, JSONObject v_2) {
String CompareString1 = "", CompareString2 = "";
try {
CompareString1 = v_1.getString(key); //Key must be present in JSON
CompareString2 = v_2.getString(key); //Key must be present in JSON
} catch (JSONException ex) {
// Json Excpetion handling
}
return isCase ? CompareString1.compareTo(CompareString2) : CompareString1.compareToIgnoreCase(CompareString2);
}
});
} catch (JSONException ex) {
// Json Excpetion handling
}
return new JSONArray(jsonsList);
}

Comparing 2 JSONObjects

My question was like this: https://stackoverflow.com/questions/20919343/php-getting-count-of-how-many-x-and-y-in-a-row-then-getting-other-data-of-x-and
But then i thought about doing the job from Android Part. So i have 2 JSONObjects which generated from php. First object has "value" and "total" arrays. Second one has "name", "surname" and "number" and a few more arrays. Now i need to compare number from second JSONObject and value from first. I tried some loops, but it creates double as expected. Here is my onPostExecute method:
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
pDialog.dismiss();
try {
JSONObject jsonObj = new JSONObject(jsonStr);
JSONObject jsonObj2 = new JSONObject(jsonStr);
// Getting JSON Array node
sonuc = jsonObj.getJSONArray(TAG_BASLIK);
// looping through All Contacts
for (int i = 0; i < sonuc.length(); i++) {
JSONObject c = sonuc.getJSONObject(i);
AdayNumara = c.getString(TAG_OY);
ToplamOy = c.getString(TAG_TOPLAM);
Log.i("Aday Numaraları", AdayNumara);
Log.i("Oy Sayısı", ToplamOy);
pie.addItem(AdayNumara,Float.valueOf(ToplamOy), pRenk.get(i));
adaylar = jsonObj2.getJSONArray(TAG_ADAYLAR);
for(int j=0; j< adaylar.length(); j++){
JSONObject c2 = adaylar.getJSONObject(j);
String no = c2.getString(TAG_NO);
String ad = c2.getString(TAG_AD);
String soyad = c2.getString(TAG_SOYAD);
String resim = c2.getString(TAG_RESIM);
HashMap<String, String> aday = new HashMap<String, String>();
do{
aday.put(TAG_AD, ad);
aday.put(TAG_SOYAD, soyad);
aday.put(TAG_RESIM, resim);
aday.put(TAG_NO, no);
aday.put(TAG_TOPLAM, ToplamOy);
adayList.add(aday);} while(AdayNumara == no);
}
adapter=new LazyAdapter2(SecimSonuclari.this, adayList);
lv.setAdapter(adapter);
}
}catch (JSONException e) {
e.printStackTrace();
}
}
Code is probably has wrong approachs since I'm new to Android.
What I am getting now is for value in listview. There must be 2. The first two has same value like 1 and 1 on their number line. The second couple has the other number, lets say 2.
I found my problem. It appears to using "==" is wrong.
if(AdayNumara.equals(no)){
aday.put(TAG_AD, ad);
aday.put(TAG_SOYAD, soyad);
aday.put(TAG_RESIM, resim);
aday.put(TAG_NO, no);
aday.put(TAG_TOPLAM, ToplamOy);
adayList.add(aday);
}
I know this question in a year old, but anyway...
I needed to compare two JSONObject values without internal JSONObject/JSONArray. Most SO solutions recommend a 3-rd party java library, which would be a bit too heavy.
First of all, the Android's built-in JSONObject does not define hashCode() and equals() in any sensible way. I used a wrapper class with a JSONObject inside.
The below functions are placed in some utility class, it is a trivial exercise to use them to define hashCode() and equals().
public static int jsonHashCode(JSONObject j) {
if (j == null) {
return 0;
}
int res = 0;
for (String s : new AsIterable<String>(j.keys())) {
res += s.hashCode();
}
return res;
}
public static boolean comparesEqual(JSONObject x, JSONObject y, Collection<String>only, Collection<String>except) {
Set<String> keys = keySet(x);
keys.addAll(keySet(y));
if (only != null) {
keys.retainAll(only);
}
if (except != null) {
keys.removeAll(except);
}
for (String s : keys) {
Object a = null, b = null;
try {
a = x.get(s);
} catch (JSONException e) {
}
try {
b = x.get(s);
} catch (JSONException e) {
}
if (a != null) {
if (!a.equals(b)) {
return false;
}
} else if (b != null) {
if (!b.equals(a)) {
return false;
}
}
}
return true;
}
public static Set<String> keySet(JSONObject j) {
Set<String> res = new TreeSet<String>();
for (String s : new AsIterable<String>(j.keys())) {
res.add(s);
}
return res;
}
where AsIterable lets us use the for(:) loop with an iterator and is defined as:
public class AsIterable<T> implements Iterable<T> {
private Iterator<T> iterator;
public AsIterable(Iterator<T> iterator) {
this.iterator = iterator;
}
public Iterator<T> iterator() {
return iterator;
}
}
You are welcome to write and post the recursive version of this code, supporting JSONObject/JSONArray values.
For my use case, I ended up iterating over the keys of the first json object and checked to see if the value matched what was in the second json object.
JSONObject obj = new JSONObject("some json string");
JSONObject comparison = new JSONObject("some other json string with the same data but different key order");
boolean equal = true;
for (Iterator<String> iterator = obj.keys(); iterator.hasNext(); ) {
String curKey = iterator.next();
if(!obj.getString(curKey).equals(comparison.getString(curKey))){
equal = false;
break;
}
}
if(equal){
// do the thing that i want to do if the two objs are equal
}

Parsing JSON in Android Master/Detail Flow

As the title says. I'd like to just use a JSON. Here is my code for what I'm guessing is my main activity. This grabs all the contents and places them in their respectful variables I'm hoping. Placed at the beginning:
public class WordDetailActivity extends FragmentActivity {
// Reading text file from assets folder
StringBuffer sb = new StringBuffer();
BufferedReader br = null; {
try {
br = new BufferedReader(new InputStreamReader(getAssets().open(
"wordlist.txt")));
String temp;
while ((temp = br.readLine()) != null)
sb.append(temp);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close(); // stop reading
} catch (IOException e) {
e.printStackTrace();
}
}
String myjsonstring = sb.toString();
// Try to parse JSON
try {
// Creating JSONObject from String
JSONObject jsonObjMain = new JSONObject(myjsonstring);
// Creating JSONArray from JSONObject
JSONArray jsonArray = jsonObjMain.getJSONArray("employee");
// JSONArray has four JSONObject
for (int i = 0; i < jsonArray.length(); i++) {
// Creating JSONObject from JSONArray
JSONObject jsonObj = jsonArray.getJSONObject(i);
// Getting data from individual JSONObject
int id = jsonObj.getInt("id");
String word = jsonObj.getString("word");
String dictionary = jsonObj.getString("dictionary");
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}}
Now I have another file called WordContent.java that defines these variable again (a non edited version):
public static Map<String, WordItem> ITEM_MAP = new HashMap<String, WordItem>();
static {
// Add 3 sample items.
addItem(new WordItem("1", "This Word", "Blah blah blah"));
}
private static void addItem(WordItem item) {
ITEMS.add(item);
ITEM_MAP.put(item.id, item);
}
/**
* A dummy item representing a piece of content.
*/
public static class WordItem {
public String id;
public String word;
public String dictionary;
public WordItem(String id, String word, String dictionary) {
this.id = id;
this.word = word;
this.dictionary = dictionary;
}
#Override
public String toString() {
return word;
}
}
}
I haven't edited them yet because I have no idea where to go from here. Or rather how to put the contents of my JSON to the WordItem so they show up when I run the program. Another way to look at all of my code that is similar to this is to just create a Master/Detail Flow project in the Eclipse ADT bundle. I hope I'm saying all of this right. Let me know if there are more details I should shed. Very new to Android Dev but any pointer in the right direction is greatly appreciated.
Personally, I would do the JSON parsing in a separate file and probably use an AsyncTask. This is so you can decouple your files/classes as you really do not need an Activity for the parsing.
I tried to reuse as much of your code you posted above. With that being said, something like this should work or put you in the right direction:
public class ParseJsonTask extends AsyncTask<Void, Void, String> {
private Context mCtx;
public ParseJsonTask(Context ctx) {
this.mCtx = ctx;
}
#Override
protected String doInBackground(Void... params) {
// Reading text file from assets folder
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(mCtx.getAssets().open("wordlist.txt")));
String temp;
while ( (temp = br.readLine()) != null )
sb.append(temp);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close(); // stop reading
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.tostring();
}
#Override
protected void onPostExecute(Void jsonString) {
WordContent word = new WordContent(); // We use this oject to add the JSON data to WordItem
// Try to parse JSON
try {
// Creating JSONObject from String
JSONObject jsonObjMain = new JSONObject(jsonString);
// Creating JSONArray from JSONObject
JSONArray jsonArray = jsonObjMain.getJSONArray("employee");
// JSONArray has four JSONObject
for (int i = 0; i < jsonArray.length(); i++) {
// Creating JSONObject from JSONArray
JSONObject jsonObj = jsonArray.getJSONObject(i);
// Getting data from individual JSONObject
int id = jsonObj.getInt("id");
String word = jsonObj.getString("word");
String dictionary = jsonObj.getString("dictionary");
// We can use the three variables above...
word.addItem(new WordItem(id, word, dictionary));
// or we can simply do...
// word.addItem(new WordItem(jsonObj.getInt("id"), jsonObj.getString("word"), jsonObj.getString("dictionary")));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Now whenever you want to parse the JSON file and use the class above you simply do the following:
ParseJsonTask task = new ParseJsonTask(getBaseContext());
task.execute();
Let me know if you have any questions...

storing json parsed values as string in array

I've got a json object, which is being collected into a function as string.
It contains array
{"officer_name":"V. M. ARORA"}{"officer_name":"Dr. C. P.
REDDY"}{"officer_name":"ARTI CHOWDHARY"}{"officer_name":"JAGDISH
SINGH"}
and here is the android code
public void func4(View view)throws Exception
{
AsyncHttpClient client = new AsyncHttpClient();
RequestParams rp = new RequestParams();
rp.put("pLat", "SELECT officer_name FROM iwmp_officer");
client.post("http://10.0.2.2/conc5.php", rp, new AsyncHttpResponseHandler() {
public final void onSuccess(String response) {
// handle your response here
ArrayList<String> User_List = new ArrayList<String>();
try {
/* here I need output in an array,
and only names not the "officer_name" */
} catch (Exception e) {
tx.setText((CharSequence) e);
}
//tx.setText(User_List.get(1));
}
#Override
public void onFailure(Throwable e, String response) {
// something went wrong
tx.setText(response);
}
});
}
The output I've shown above is in String, need to get it in array. Please help!
If the output you got is something like this.
String outputJson=[{"officer_name":"V. M. ARORA"}{"officer_name":"Dr. C. P. REDDY"}{"officer_name":"ARTI CHOWDHARY"}{"officer_name":"JAGDISH SINGH"}]
Then its a JSON Array.
You can parse it as
JsonArray array=new JsonArray(outputJson);
Then loop this json array using
for(JsonObject jsonObj in array){
String officerName=[jsonObj getString("officer_name");
}
You can use something like above The mentioned code is not correct syntactically but yes conceptually correct. You can go ahead with this.
List < String > ls = new ArrayList< String >();
JSONArray array = new JSONArray( response );
for (int i = 0; i < array.length() ; i++ ) {
JSONObject obj = array.getJSONObject(Integer.toString(i));
ls.add(obj.getString("officer_name"));
}
This would work
try {
JSONArray array= new JSONArray(response);
//array = new JSONArray(response);
for (int i = 0; i < array.length(); i++) {
//JSONObject obj = response.getJSONArray(i);
JSONObject jsonLineItem = (JSONObject) array.getJSONObject(i);
String name_fd = jsonLineItem.getString("officer_name");
User_List.add(jsonLineItem.getString("officer_name"));
Log.d("JSONArray", name_fd+" " +name_fd);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
tx.setText( e.toString());
}

Categories

Resources