Java - JSONArray has 10 objects but only display first two - java

I'm new to Android and Java so I'm building a demo app of book listing to learn about parsing JSON data. I use log to check how many books there are on data (which is 10 ) but only get 2 first books on the list displayed when running it on an emulator... Hope anyone can tell me where I should change?
Thanks for any opinion!
E/QueryUtils: length of array: 10
The API link: https://www.googleapis.com/books/v1/volumes?q=search+terms
QueryUtils.java
private static List<BookItem> extractItemFromJson(String bookJSON) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(bookJSON)){
return null;
}
// Create an empty ArrayList that we can start adding books to
List<BookItem> bookItems = new ArrayList<>();
// Try to parse the JSON response string. If there is a problem with the way the JSON is formatted,
// a JSONException exception object will be thrown.
// Catch the exception so the app doesnt crash, and prent the error message to the logs.
try {
JSONObject baseJsonresponse = new JSONObject(bookJSON);
JSONArray bookItemArray = baseJsonresponse.getJSONArray("items");
Log.e("QueryUtils", "length of array: " + bookItemArray.length());
for (int i = 0; i < bookItemArray.length(); i++) {
JSONObject currentBook = bookItemArray.getJSONObject(i);
JSONObject volumeInfo = currentBook.getJSONObject("volumeInfo");
String title = volumeInfo.getString("title");
String subtitle = volumeInfo.getString("subtitle");
String previewLink = volumeInfo.getString("previewLink");
JSONObject imageLinks = volumeInfo.getJSONObject("imageLinks");
String thumbnail = imageLinks.getString("smallThumbnail");
BookItem book = new BookItem(/**author, */title, subtitle, thumbnail, previewLink);
bookItems.add(book);
}
} catch (JSONException e) {
Log.e("QueryUtils", "Problem parsing the earthquake JSON results", e);
}
return bookItems;
}

The third book in your list does not cointain the field imageLinks, and that causes an exception.
You should add a check:
String thumbnail = "";
if (volumeInfo.has("imageLinks")) {
JSONObject imageLinks = volumeInfo.getJSONObject("imageLinks");
thumbnail = imageLinks.getString("smallThumbnail");
}

I suspect it's going to the catch block after parsing the first 2 because an exception happened while parsing, You should fix the exception and also you can catch the exception inside the loop to add the items that could be parsed and don't quit the loop if there is a JSONException.

Related

Comma is causing unwanted string split

I have an array of data sent from my database - Once received, I save it in shared preferences - here is my getter:
public List getAnswerStringEdit() {
return answer_edit;
}
I save it as so:
editor.putString(Constants.ANSWER_EDIT,resp.getAnswer().getAnswerStringEdit().toString().trim());
Then retrieve it here:
String answerString = pref.getString(Constants.ANSWER_EDIT, "").trim();
answerString = answerString.substring(1, answerString.length() - 1).trim();
String[] array = answerString.split(",");
Finally, I access the array as so:
et_answer1_edit.append(array[0]);
My problem is this - Say I add a questions which has a comma in the middle of it, like -
Question 1- "Why is this broke, I don't know?"
Currently, when I retrieve my question, the string is getting split, even though there are quotation marks around the whole question/answer- So in the example above, in position 0 in the array, I should have:
"Why is this broke, I don't know?"
However, instead I am getting in position 0:
Why is this broke - then position 1 as: I don't know
I know this sounds daft because clearly, I am calling for the split to happen on the comma, but I expect that at the end of the whole string object, not in the middle of it.
The retrieved JSON is as follows:
{
"result": "success",
"message": "Answer Has Been Selected",
"answer": {
"answer_edit": ["Why is this broke, I don't know?", "What is your favorite song, because I want to know"]
}
}
Any help/advice that can help me to understand what is causing this, would be really appreciated.
Dont split the string using ',' use this
JSONObject jsonObject = new JSONObject(answerString );
JSONArray jsonArray = jsonObject.getJSONObject("answer").getJSONArray("answer_edit");
Log.e("Json Array elements are","First Element : "+jsonArray.get(0)+"\nSecond Element : "+jsonArray.get(1));
String QuestionString1 = jsonArray.get(0).toString();
String QuestionString2 = jsonArray.get(1).toString();
try this one
JSONObject jsonObject = new JSONObject("your json response");
try
{
JSONObject answer= jsonObject.getJSONObject("answer");
JSONArray jsonArrayAnswerEdit = answer.getJSONArray("answer_edit");
Log.e("=>", "" + jsonArrayAnswerEdit);
for (int i = 0; i < jsonArrayAnswerEdit.length(); i++){
String que= jsonArrayAnswerEdit.getString(i);
Log.e("json", i + "=" + que);
}
} catch (JSONException e) {
e.printStackTrace();
}
Try this
JSONObject jsonObject = new JSONObject("your json response");
try
{
JSONObject data = jsonObject.getJSONObject("answer");
JSONArray jsonArray = data.getJSONArray("answer_edit");
Log.e("=>", "" + jsonArray);
for (int i = 0; i < jsonArray.length(); i++)
{
String value = jsonArray.getString(i);
String[] parts = value.split(Pattern.quote(","));
for (int j=0; j<parts.length; j++)
{
Log.e("Answer String ", "=" + parts[j]);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
OUTPUT
E/=>: ["Why is this broke, I don't know?","What is your favorite song, because I want to know"]
E/Answer String: =Why is this broke
E/Answer String: = I don't know?
E/Answer String: =What is your favorite song
E/Answer String: = because I want to know
After reading all the suggest answers, figured out a simple solution:
First I stored my answers sent from my external database as so -
final String jsonAnswers = gson.toJson (resp.getAnswer().getAnswerStringEdit());
Then saved in shared pref -
editor.putString(Constants.ANSWER_EDIT,jsonAnswers);
Next to read the answer back out:
String answerString = pref.getString(Constants.ANSWER_EDIT, "").trim();
final String[] array = gson.fromJson (answerString, String[].class);
Finally, I could set my Edittext with data from the array:
et_answer1_edit.append(array[0].trim());
et_answer2_edit.append(array[1].trim());

return null while parsing json in loop - android

trying to parse "publisher" key from json object it is returning error but if I parse only "title" key it works fine
public ArrayList<BookData> parseJSON(String jsonString){
try{
JSONObject obj = new JSONObject(jsonString);
JSONArray jsonArray = obj.getJSONArray("items");
for(int i=0;i<10;i++){
JSONObject object = jsonArray.getJSONObject(i);
JSONObject volumeInfo = object.getJSONObject("volumeInfo");
//this title works fine
String title = volumeInfo.getString("title");
//this publisher is throwing null pointer exception
String publisher = volumeInfo.getString("publisher");
//Log.v("testing title", publisher);
list.add(new BookData(title, "publisher"));
}
return list;
}catch (Exception e){e.printStackTrace();}
return null;
}
JSON is here:
"volumeInfo":{
"title":"Organic Chemistry",
"authors":[
"Jonathan Clayden",
"Nick Greeves",
"Stuart Warren"
],
"publisher":"Oxford University Press"
}
list.add(new BookData(title, "publisher")); replace this with below given code.
list.add(new BookData(title, publisher));
put a null checker for publisher may be you are getting NullpointerException,hope it ll help you
From the documentation of getString you can see that:
throws NullPointerException - if the specified name doesn't have any mapping
So if the titleworks fine, that means the publisher is not there in your JSON. Check your Json String again.
Hope this helps.
You have publisher in quotes when you add it to the array: list.add(new BookData(title, "publisher")) this passes in a string literal, you want to pass in the variable publisher. So simply replace "publisher" in that line with publisher.

Modifying/Updating values inside a jsonArray?

What I want to do is at a particular index position change/replace a value inside a json array.After going through the documentation at http://www.json.org/javadoc/org/json/JSONArray.html I found out that jsonArray does not have a getIndex() method.In this situation how do I update my json array at a given index position.
This is the method that creates a json array in my android code.
private void createJsonArray() {
billType = (invEstSwitch.isChecked() ? textViewEstimate : textViewInvoice)
.getText().toString();
String invNumber = textViewInvNo.getText().toString();
String bcode = barCode.getText().toString();
String description = itemDesc.getText().toString();
String wt = weightLine.getText().toString();
String rateAmt = rateAmount.getText().toString();
String making = makingAmount.getText().toString();
String netr = netRate.getText().toString();
String iTotal = itemtotal.getText().toString();
String vatAmt = textViewVat.getText().toString();
String sumAmt = textViewSum.getText().toString();
String crtDate = textViewCurrentDate.getText().toString();
try {
jsonObject.put("custInfo", custSelected.toString());
jsonObject.put("invoiceNo", invNumber);
jsonObject.put("barcode", bcode);
jsonObject.put("description", description);
jsonObject.put("weight", wt);
jsonObject.put("rate", rateAmt);
jsonObject.put("makingAmt", making);
jsonObject.put("net_rate", netr);
jsonObject.put("itemTotal", iTotal);
jsonObject.put("vat", vatAmt);
jsonObject.put("sum_total", sumAmt);
jsonObject.put("bill_type", billType);
jsonObject.put("date", crtDate);
} catch (JSONException e) {
e.printStackTrace();
}
try {
itemSelectedJson.put(index, jsonObject);
index++;
} catch (JSONException e) {
e.printStackTrace();
}
}
And this is the code that I use to update my json array which contains a json object.
try {
itemSelectedJson.getJSONObject(i).put("net_rate",netChange);
Log.d("NETRATE_TW",itemSelectedJson.toString());
} catch (JSONException e) {
e.printStackTrace();
}
Now the problem with this code is it updates the jsonArray everytime a new item is added to the code.So the first object values are the same as the last object.
Also note that I am using this code inside a text watcher.So the afterTextchanged() method looks like this.
#Override
public void afterTextChanged(Editable s) {
String netChange = netRate.getText().toString();
final int row_id = (int) newRow.getTag();
if ((row_id<0) || (row_id> itemSelectedJson.length())){
return;
}
try {
itemSelectedJson.getJSONObject(row_id-1).put("net_rate",netChange);
Log.d("NETRATE_TW",itemSelectedJson.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
};
This is the snapshot of what my database looks like.
A jSONObject(which is a collection of name,value pairs) can be converted into a JSONArray which is an ordered array of the "values" in the JSONObject.
This can be done using the .toJSONArray() method.
When you need to replace/update the JSONArray, you may use the method
.put(int index, java.util.Map value)
Unlike how you are doing at present, i.e getting the object and setting a new key and value.
http://www.json.org/javadoc/org/json/JSONArray.html#put(int, java.util.Map)
As I understood, your problem is in creating multiple JSONObjects in your JSONArray with the same values, and that's because you can't get the index of a created JSONObject inside your JSONArray, and to overcome this problem, you can easily create a compound JSONObject that contains your JSONObjects instead of a JSONArray contains JSONObjects, and the object name will be anything unique in your JSONObject data, and when you make any changes or add any item it will either be added as a new object if it doesn't exist or it will overwrite the existing object if it added before, for example let's suppose that barcode value is unique in your data, so the code will be like the following:
// declaring itemSelectedJson as JSONObject
JSONObject itemSelectedJson = new JSONObject();
.
.
.
// when wanting to add a new item
itemSelectedJson.put(jsonObject.getString("barcode"), jsonObject);
and to retrieve the data you simple iterate through this JSONObject:
Iterator<?> keys = itemSelectedJson.keys();
JSONObject single_item;
while(keys.hasNext()) {
String key = (String)keys.next();
single_item = itemSelectedJson.getJSONObject(key);
// do what do you want here
}

java.lang.String cannot be converted to JSONObject where value already converted to JSONObject

It is a question that has been asked many times but i didn't find any solution from the answers that they gave.
Basically im using the GSON to create instances of classes to JSON in order to serialize them and store it into the cloud save.
Here is the code
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
User user = dbmanager.getUser();
String user_json = gson.toJson(user);
saved_data.put("user", user_json);
The dbmanager.getUser(); is an Sql query that collects the user from the android database and return it as an instance of the User class.
Then i'm using the load method to load the data
public void converLoadData(String data) throws ParseException
{
if (data == null || data.trim().equals("")) return;
try {
User user = new User();
data = data.replace("\\\\", "\\");
JSONObject obj = new JSONObject(data);
System.out.println("data: " + obj.toString());
JSONObject user_object = obj.getJSONObject("user");
System.out.println("user " + user_object.toString());
String last_sync = obj.getString("last_sync");
java.util.Date db_sync = dbmanager.getLastSync(user.getID());
}
catch (JSONException ex) {
ex.printStackTrace();
Log.e(TAG, "Save data has a syntax error: " + data, ex);
}
catch (NumberFormatException ex) {
ex.printStackTrace();
throw new RuntimeException("Save data has an invalid number in it: " + data, ex);
}
}
The return of the println of data is this one
data: {"current":"{\"title\":\"Puzzle
2\",\"fnMoves\":[],\"solution_path\":\"puzzles\/2\/CKqbKz5f\/7b1886a261b0400768e75dea91948576.json\",\"puzzlecolors\":[0,0,0],\"puzzle_path\":\"puzzles\/2\/CKqbKz5f\/41a0b30fdfdf6685dd50c6019391cc00.tmx\",\"level_id\":2,\"locked\":false,\"level\":2,\"puzzle_site_id\":2,\"id\":2,\"score\":20,\"fnkeys\":1,\"solved\":false,\"difficulty\":1.0}","solved":"[{\"id\":1,\"puzzle_id\":1,\"puzzle_tries\":10,\"user_id\":1}]","user":"{\"personphoto\":\"https:\/\/lh4.googleusercontent.com\/-5XfDNwK1PwI\/AAAAAAAAAAI\/AAAAAAAAPs8\/C0onA9lyKvY\/photo.jpg?sz=50\",\"google_id\":\"fdgsdfgfgfgsdgsdf\",\"personname\":\"Test
Test\",\"last_sync\":\"2014-08-18
22:12:12\",\"lifes\":3,\"highscore\":13,\"ID\":1}","last_sync":"2014-08-18
22:12:12"}
and here is the error. This error has to do with the data value because i have back slash? i'm passing the data (which is string) into a JSON object and then i'm trying to collect the user element. using this JSONObject user_object = obj.getJSONObject("user"); and this is where i\m having the error. Anyone who can help me please? thank you
org.json.JSONException: Value {"personphoto":"https://lh4.googleusercontent.com/-5XfDNwK1PwI/AAAAAAAAAAI/AAAAAAAAPs8/C0onA9lyKvY/photo.jpg?sz=50","google_id":"104757400111626678244","personname":"George Panayi","last_sync":"2014-08-18 22:12:12","lifes":3,"highscore":13,"ID":1} at user of type java.lang.String cannot be converted to JSONObject
Solution: I'm using "remove" method to remove extra backslashes and quotes which cause bad format of the JSON Object
data = data.replace("\\", "");
data = data.replace("\"{", "{");
data = data.replace("}\"", "}");
data = data.replace("\"[", "[");
data = data.replace("]\"", "]");
I was able to get it working by cleaning up the JSON object a bit. I think it's just a bad formatting error.
First, the escape slashes, they need to be uniform or removed. I removed the ones escaping the double quotes, but left them in everywhere else.
Then I removed the double quotes around the nested objects and arrays. "{...}" to {...} and "[...]" to [...]
Seems to be all that was necessary.
{"current":{"puzzle_path":"puzzles\/2\/CKqbKz5f\/41a0b30fdfdf6685dd50c6019391cc00.tmx","solved":false,"score":20,"difficulty":1,"level_id":2,"id":2,"fnkeys":1,"title":"Puzzle\n2","level":2,"solution_path":"puzzles\/2\/CKqbKz5f\/7b1886a261b0400768e75dea91948576.json","puzzlecolors":[0,0,0],"puzzle_site_id":2,"locked":false,"fnMoves":[]},"user":{"ID":1,"lifes":3,"google_id":"fdgsdfgfgfgsdgsdf","highscore":13,"last_sync":"2014-08-18\n22:12:12","personname":"Test\nTest","personphoto":"https:\/\/lh4.googleusercontent.com\/-5XfDNwK1PwI\/AAAAAAAAAAI\/AAAAAAAAPs8\/C0onA9lyKvY\/photo.jpg?sz=50"},"solved":[{"puzzle_id":1,"id":1,"user_id":1,"puzzle_tries":10}],"last_sync":"2014-08-18\n22:12:12"}

What should I do to solve this error?

I was using JSONParser to obtain results of a search, for that I followed this tutorial: http://www.androidhive.info/2012/01/android-json-parsing-tutorial/
The thing is that, the API I am using gives the results like this:
{"response":[50036,{"aid":88131498,"owner_id":61775052,"artist":"Terror Squad","title":"Lean Back (OST Need For Speed Underground 2)","duration":249,"url":"http:\/\/cs4408.vkontakte.ru\/u59557424\/audio\/7f70f58bb9b8.mp3","lyrics_id":"3620730"},{"aid":106963458,"owner_id":-24764574,"artist":"«Dr. Dre ft Eminem, Skylar Grey (Assault Terror)","title":"I Need A Doctor (ASSAULT TERROR DUBSTEP REMIX)»","duration":240,"url":"http:\/\/cs5101.vkontakte.ru\/u79237547\/audio\/12cd12c7f8c2.mp3","lyrics_id":"10876670"}]}
My problem comes when I have to parse the first integer (here it is 50036) which is the number of results found.
I don't know how to read that integer.
This is my code:
private void instance(String artisttrack){
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
String jsonurl = new String( "https://api.vk.com/method/audio.search?access_token=ACC_TOKEN&api_id=ID&sig=SIG&v=2.0&q=" + artistname + artisttrack + "&count=5");
JSONObject json = jParser.getJSONFromUrl(jsonurl);
try {
// Getting Array of Contacts
response = json.getJSONArray(TAG_RESPONSE);
// looping through All Contacts
for(int i = 0; i < response.length(); i++){
JSONObject c = response.getJSONObject(i);
// Storing each json item in variable
//int results = Integer.parseInt(c.getString(TAG_RESULTS));
String aid = c.getString(TAG_AID);
String owner_id = c.getString(TAG_OWNER_ID);
String artist = c.getString(TAG_ARTIST);
String title = c.getString(TAG_TITLE);
String duration = c.getString(TAG_DURATION);
// Phone number is agin JSON Object
//JSONObject phone = c.getJSONObject(TAG_PHONE);
String url = c.getString(TAG_URL);
String lyrics_id = c.getString(TAG_LYRICS_ID);
Log.e("áaaaaaaaaaaaaaa", url);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
The JSONParser.java is like written in the tutorial.
And here 2 lines of the logcat error:
W/System.err(10350): org.json.JSONException: Value 50036 at 0 of type java.lang.Integer cannot be converted to JSONObject
W/System.err(10350): at org.json.JSON.typeMismatch(JSON.java:100)
Your JSON sample is a poor way to organize the results: mixing the number in with the result objects. Is the number supposed to indicate the number of objects in the array or something else?
If you can assume that this number will always be the first element, and according to this then it's supposed to work this way, you can try to read the first value of the array outside the loop:
response = json.getJSONArray(TAG_RESPONSE);
// from your example, num will be 50036:
num = response.getInt(0);
for (int i = 1; i < response.length(); i++){
JSONObject c = response.getJSONObject(i);
Note that the example in the linked documentation has this number as a string:
{"response":
["5",
{"aid":"60830458","owner_id":"6492","artist":"Noname","title":"Bosco",
"duration":"195","url":"http:\/\/cs40.vkontakte.ru\/u06492\/audio\/2ce49d2b88.mp3"},
{"aid":"59317035","owner_id":"6492","artist":"Mestre Barrao","title":"Sinhazinha",
"duration":"234","url":"http:\/\/cs510.vkontakte.ru\/u2082836\/audio\/
d100f76cb84e.mp3"}]}
But JSONArray.getInt() will parse the String as an int for you.
And notice that some of the values in the objects in your array are also numbers, you may want to read those as int also:
int aid = c.getInt(TAG_AID);
int owner_id = c.getInt(TAG_OWNER_ID);
int duration = c.getInt(TAG_DURATION);
A lot of the values you are trying to parse in are not String objects, specifically "aid", "owner_id", and "duration". Use the correct method to retrieve values. For example:
int aid = c.getInt(TAG_AID);
int owner_id = c.getInt(TAG_OWNER_ID);
String artist = c.getString(TAG_ARTIST);
String title = c.getString(TAG_TITLE);
int duration = c.getInt(TAG_DURATION);
edit: Another error that I missed is you start your array with 50036. This is not a JSONObject and cannot be parsed as so. You can add a conditional statement to check if it's array index 0 to parse the int using getInt(), and then parse as JSONObjects for the rest of the array values.
Try changing
response = json.getJSONArray(TAG_RESPONSE);
into
response = (JSONObject)json.getJSONArray(TAG_RESPONSE);
I dont have any experience with JSONObject, but works often with type mismatches.
Try putting 50036 in quotes like this "50036" .

Categories