Trying to parse a JSON result from Rotten Tomatoes API - android
I'm succeeding in getting the movie's title and year, but somehow not the synopsis. as far as I understand the object's shape they should be reachable in the same way:
JSONObject resultOBJ = new JSONObject(result);
Log.v("hhhh",resultOBJ.toString());
JSONArray movArr = resultOBJ.getJSONArray("movies");
JSONObject movOBJ =movArr.getJSONObject(0);
String title = movOBJ.getString("title");
String synop = movOBJ.getString("synopsis");
nameView.setText(title);
synopView.setText(synop);
the object I receive looks like this (sans formatting):
{
"total": 1,
"movies": [
{
"critics_consensus": "Deftly blending comedy, ...",
"id": "770672122",
"mpaa_rating": "G",
"ratings": {
"audience_rating": "Upright",
"audience_score": 87,
"critics_rating": "Certified Fresh",
"critics_score": 99
},
"release_dates": {
"dvd": "2010-11-02",
"theater": "2010-06-18"
},
"runtime": 103,
"title": "Toy Story 3",
"year": 2010,
"synopsis": "Pixar returns to their first success with ...
et cetra...
I took your example (copy/paste), closed some gates for Json ond got proper result:
public static void main(String[] args) throws JSONException {
String result = "{" +
" \"total\": 1," +
" \"movies\": [" +
" {" +
" \"id\": \"770672122\"," +
" \"title\": \"Toy Story 3\"," +
" \"year\": 2010," +
" \"mpaa_rating\": \"G\"," +
" \"runtime\": 103," +
" \"critics_consensus\": \"Deftly blending comedy,adventure, and honest emotion, Toy Story 3 is a rare second sequel that really works.\"," +
" \"release_dates\": {" +
" \"theater\": \"2010-06-18\"," +
" \"dvd\": \"2010-11-02\"" +
" }," +
" \"ratings\": {" +
" \"critics_rating\": \"Certified Fresh\"," +
" \"critics_score\": 99," +
" \"audience_rating\": \"Upright\"," +
" \"audience_score\": 87" +
" }," +
" \"synopsis\": \"Pixar returns to their first success with Toy Story 3. The movie begins with Andy leaving for college and donating his beloved toys -- including Woody (Tom Hanks) and Buzz (Tim Allen) -- to a daycare. While the crew meets new friends, including Ken (Michael Keaton), they soon grow to hate their new surroundings and plan an escape. The film was directed by Lee Unkrich from a script co-authored by Little Miss Sunshine scribe Michael Arndt. ~ Perry Seibert, Rovi\"" +
" }" +
" ]" +
"}";
JSONObject resultOBJ = new JSONObject(result);
JSONArray movArr = resultOBJ.getJSONArray("movies");
JSONObject movOBJ =movArr.getJSONObject(0);
String title = movOBJ.getString("title");
String synop = movOBJ.getString("synopsis");
System.out.println(synop);
}
Output:
Pixar returns to their first success with Toy Story 3. The movie begins with Andy leaving for college and donating his beloved toys -- including Woody (Tom Hanks) and Buzz (Tim Allen) -- to a daycare. While the crew meets new friends, including Ken (Michael Keaton), they soon grow to hate their new surroundings and plan an escape. The film was directed by Lee Unkrich from a script co-authored by Little Miss Sunshine scribe Michael Arndt. ~ Perry Seibert, Rovi
Related
Android SpannableStringBuilder for multiple Patterns
I have different screens for different entities which are Products, Rooms, Posts, and, Users. All of them have distinct ID which I use to open the particular screen to try to load the data from the ID parameter passed on the relevant screen/activity via the APIs. The mechanism I thought for Products,Rooms,and Posts in particular are that on Notifications Screen and alike, I want to send coded or tagged string; like below for Products for example: You have bid on <p244 24LED Lampshade /> And to match the above I have a regular expression: <p([0-9]*)\s(.*?)\/>(\s|$) Here's a sample string: String dummyText = "Hi #dan we product test <p1337 product />" + "\n how about <r123 Room name/> is a nice room" + "\n what <t234 this post details more about it/> but you should " + "\n #poprocks woah one #sad"; It seems to work fine with single use of the product/post/room, but it messes up with more instances of the coded/tagged string. But like I stated, with multiple instances like the following test: String dummyText = "Hi #dan we product test <p1337 product /> and were more happy with <p53 car/> " + "\n eh <r123 Room name/> is a nice room and <r233 dans house/> sucked while <r123 fun time/> was ok " + // "\n what <t234 this post details more about it/> but you should " + "\n <t234 view this as well/>" + "\n #poprocks woah one #sad"; It messes up: Here's my entire code process: String dummyText = "Hi #dan we product test <p1337 product /> and were more happy with <p53 car/> " + "\n eh <r123 Room name/> is a nice room and <r233 dans house/> sucked while <r123 fun time/> was ok " + // "\n what <t234 this post details more about it/> but you should " + "\n <t234 view this as well/>" + "\n #poprocks woah one #sad"; List<Pattern> patternsList = new ArrayList<>(); patternsList.add(Pattern.compile(REGEX_NOTI_ROOMS)); //0 patternsList.add(Pattern.compile(REGEX_NOTI_PRODUCTS)); //1 patternsList.add(Pattern.compile(REGEX_NOTI_TWEETS)); //2 patternsList.add(Pattern.compile(REGEX_NOTI_MENTION)); //3 patternsList.add(Pattern.compile(REGEX_ARABIC_N_NUM_HASHTAG)); //4 holder.row_noti_messageTV.setText(makeSpannable(dummyText, patternsList)); holder.row_noti_messageTV.setMovementMethod(new PkMovementMethod()); Where the relevant regex are: public static final String REGEX_NOTI_ROOMS ="<r([0-9]*)\\s(.*?)\\/>(\\s|$)"; public static final String REGEX_NOTI_PRODUCTS ="<p([0-9]*)\\s(.*?)\\/>(\\s|$)"; public static final String REGEX_NOTI_TWEETS ="<t([0-9]*)\\s(.*?)\\/>(\\s|$)"; public static final String REGEX_ARABIC_N_NUM_HASHTAG ="#(\\w*[0-9a-zA-Zء-ي٠-٩]+\\w*[0-9a-zA-Zء-ي٠-٩])"; public static final String REGEX_NOTI_MENTION ="(?:^|\\s|$|[.])#[\\p{L}0-9_]*"; And my makeSpannable method is: public SpannableStringBuilder makeSpannable(String rawText, List<Pattern> listofPatterns) { // StringBuffer sb = new StringBuffer(); SpannableStringBuilder spannable = new SpannableStringBuilder(rawText); for(int i=0; i<listofPatterns.size(); i++) { Matcher matcher = null; if(i==0) //init only matcher = listofPatterns.get(i).matcher(rawText); else matcher = listofPatterns.get(i).matcher(spannable); while (matcher.find()) { showLogMessage("jsonParse", "hit on iteration" + i + " group == " + matcher.group()); if(i==3 || i == 4) { try { String abbr = matcher.group(); showLogMessage("jsonParse", "loop[3 | 4 are normal] == " + i + " group(0) == " + abbr); int start = matcher.start(); int end = matcher.end(); NotificationSpan ourSpan = new NotificationSpan(Color.BLUE, Color.RED, Color.TRANSPARENT, new IdTitleStore(abbr, abbr, abbr), NotificationAdapter.this); spannable.setSpan(ourSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } catch (Exception e) { e.printStackTrace(); } } else if(i<=2) { try { String orgGroup = matcher.group(); // get the match String abbr = matcher.group(2); showLogMessage("jsonParse", "loop == " + i + " group2 == " + abbr); int startPoint = matcher.start(); int endPoint = matcher.end(); NotificationSpan ourSpan = new NotificationSpan(Color.RED, Color.BLUE, Color.TRANSPARENT, new IdTitleStore(matcher.group(1), abbr, orgGroup), NotificationAdapter.this); Spannable spanText = new SpannableString(abbr); spanText.setSpan( ourSpan, 0, abbr.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ); spannable.replace(startPoint, endPoint, spanText); } catch (Exception e) { e.printStackTrace(); } } } } return spannable; } Note: NotificationSpan is a custom span I use to store the group(1) as it has the ID and from group(0) I can deduce on click whether it may be a Post, Product, or a Room entity to open it. Any feedback shall be appreciated, even if it can point me towards the right direction. Like if my approach in itself is fundamentally wrong or something, please do let me know. EDIT: Someone pointed out at comments to remove the redundant (\s|$) from the Regular Expressions, and it did seemingly nothing Logs for the dummyString I tested: String dummyText = "Hi #dan we product test <p1337 product /> and were more happy with <p53 car/> " + "\n eh <r123 Room name/> is a nice room and <r233 dans house/> sucked while <r123 fun time/> was ok " + "\n what <t233 this post details more about it/> but you should " + "\n <t234 view this as well/>" + "\n #poprocks woah one #sad"; E/jsonParse: hit on iteration0 group(0) == <r123 Room name/> E/jsonParse: hit on iteration0 group(0) == <r233 dans house/> E/jsonParse: hit on iteration0 group(0) == <r123 fun time/> E/jsonParse: hit on iteration1 group(0) == <p1337 product /> E/jsonParse: hit on iteration1 group(0) == <p53 car/> E/jsonParse: hit on iteration2 group(0) == <t234 view this as well/> E/jsonParse: hit on iteration3 group(0) == #dan E/jsonParse: hit on iteration4 group(0) == #poprocks E/jsonParse: hit on iteration4 group(0) == #sad It is also weird that the first instance is not detected by the matcher at all. i.e "\n what <t234 this post details more about it/> but you should " It may entirely be possible that something is wrong with the logic itself of the Multiple Patterns being matched inside loops, but I really can't seem to figure it out. Appreciate the comment though! EDIT EDIT*: I think I finally understand what the problem was/is. Adding dot after the replace method it gave me two suggestions, notify() and notifyAll(), which got me wondering this is indeed multi-thread based operation (sort of obvious to others but yeah!). So the multiple loop was in fact the issue. Since replacing a call updates the span itself, the inner loop (while mathcer.find()) did not have the latest span on the matcher, it had different/previous one, which would've worked fine if there were only one instance found, but since in case of multiple the start and end were way off and hence some unintended stuff was happening. Followings the updated code, I did keep the (\s|$) just in case a Product/Post/Room is the end of the string so it does match and not remain blank. public SpannableStringBuilder makeSpannable(String rawText, List<Pattern> listofPatterns) { SpannableStringBuilder spannable = new SpannableStringBuilder(rawText); Matcher matcher = null; for(int i=0; i<listofPatterns.size(); i++) { matcher = listofPatterns.get(i).matcher(spannable.toString()); while (matcher.find()) { showLogMessage("jsonParse", "hit on iteration" + i + " group == " + matcher.group()); if(i<=2) { try { String orgGroup = matcher.group(); // get the match String abbr = matcher.group(2); showLogMessage("jsonParse", "span txt of iteration " + i + " going to be group2 == " + abbr); int startPoint = matcher.start(); int endPoint = matcher.end(); NotificationSpan ourSpan = new NotificationSpan(Color.RED, Color.BLUE, Color.TRANSPARENT, new IdTitleStore(matcher.group(1), abbr, orgGroup), NotificationAdapter.this); Spannable spanText = new SpannableString(abbr); spanText.setSpan( ourSpan, 0, abbr.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE ); spannable.replace(startPoint, endPoint-1, spanText); matcher = listofPatterns.get(i).matcher(spannable); } catch (Exception e) { e.printStackTrace(); } } else { try { String abbr = matcher.group(); showLogMessage("jsonParse", "span txt of iteration " + i + " going to be group(0) == " + abbr); int start = matcher.start(); int end = matcher.end(); NotificationSpan ourSpan = new NotificationSpan(Color.BLUE, Color.RED, Color.TRANSPARENT, new IdTitleStore(abbr, abbr, abbr), NotificationAdapter.this); spannable.setSpan(ourSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } catch (Exception e) { e.printStackTrace(); } } } } return spannable; } Additional note: I think it'd be better if I explain why I've divided the loop into two parts to begin-with as well. The reason is simple, first 3 of my REGEX I 100% know for sure have group(2) elements, which I have implemented the click ID mechanism of. The last two are normal hashtag and mention ones which don't have group(2). Here's the final working look, hope I don't face any performance issues:
Why am I getting "java.lang.String cannot be converted to JSONObject" error?
I getting "Value SAMPLE_JSON_RESPONSE of type java.lang.String cannot be converted to JSONObject" error. I think I have to format the 'SAMPLE_JSON_RESPONSE', if so please tell me how do I do that ? private static final String SAMPLE_JSON_RESPONSE = "{\"type\":\"FeatureCollection\",\"metadata\":{\"generated\":1462295443000,\"url\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2016-01-01&endtime=2016-01-31&minmag=6&limit=10\",\"title\":\"USGS Earthquakes\",\"status\":200,\"api\":\"1.5.2\",\"limit\":10,\"offset\":1,\"count\":10},\"features\":[{\"type\":\"Feature\",\"properties\":{\"mag\":7.2,\"place\":\"88km N of Yelizovo, Russia\",\"time\":1454124312220,\"updated\":1460674294040,\"tz\":720,\"url\":\"http://Earthquake.usgs.gov/earthquakes/eventpage/us20004vvx\",\"detail\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us20004vvx&format=geojson\",\"felt\":2,\"cdi\":3.4,\"mmi\":5.82,\"alert\":\"green\",\"status\":\"reviewed\",\"tsunami\":1,\"sig\":798,\"net\":\"us\",\"code\":\"20004vvx\",\"ids\":\",at00o1qxho,pt16030050,us20004vvx,gcmt20160130032510,\",\"sources\":\",at,pt,us,gcmt,\",\"types\":\",cap,dyfi,finite-fault,general-link,general-text,geoserve,impact-link,impact-text,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,\",\"nst\":null,\"dmin\":0.958,\"rms\":1.19,\"gap\":17,\"magType\":\"mww\",\"type\":\"Earthquake\",\"title\":\"M 7.2 - 88km N of Yelizovo, Russia\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[158.5463,53.9776,177]},\"id\":\"us20004vvx\"},\n" + "{\"type\":\"Feature\",\"properties\":{\"mag\":6.1,\"place\":\"94km SSE of Taron, Papua New Guinea\",\"time\":1453777820750,\"updated\":1460156775040,\"tz\":600,\"url\":\"http://Earthquake.usgs.gov/earthquakes/eventpage/us20004uks\",\"detail\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us20004uks&format=geojson\",\"felt\":null,\"cdi\":null,\"mmi\":4.1,\"alert\":\"green\",\"status\":\"reviewed\",\"tsunami\":1,\"sig\":572,\"net\":\"us\",\"code\":\"20004uks\",\"ids\":\",us20004uks,gcmt20160126031023,\",\"sources\":\",us,gcmt,\",\"types\":\",cap,geoserve,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,\",\"nst\":null,\"dmin\":1.537,\"rms\":0.74,\"gap\":25,\"magType\":\"mww\",\"type\":\"Earthquake\",\"title\":\"M 6.1 - 94km SSE of Taron, Papua New Guinea\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[153.2454,-5.2952,26]},\"id\":\"us20004uks\"},\n" + "{\"type\":\"Feature\",\"properties\":{\"mag\":6.3,\"place\":\"50km NNE of Al Hoceima, Morocco\",\"time\":1453695722730,\"updated\":1460156773040,\"tz\":0,\"url\":\"http://Earthquake.usgs.gov/earthquakes/eventpage/us10004gy9\",\"detail\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us10004gy9&format=geojson\",\"felt\":117,\"cdi\":7.2,\"mmi\":5.28,\"alert\":\"green\",\"status\":\"reviewed\",\"tsunami\":0,\"sig\":695,\"net\":\"us\",\"code\":\"10004gy9\",\"ids\":\",us10004gy9,gcmt20160125042203,\",\"sources\":\",us,gcmt,\",\"types\":\",cap,dyfi,geoserve,impact-text,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,\",\"nst\":null,\"dmin\":2.201,\"rms\":0.92,\"gap\":20,\"magType\":\"mww\",\"type\":\"Earthquake\",\"title\":\"M 6.3 - 50km NNE of Al Hoceima, Morocco\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[-3.6818,35.6493,12]},\"id\":\"us10004gy9\"},\n" + "{\"type\":\"Feature\",\"properties\":{\"mag\":7.1,\"place\":\"86km E of Old Iliamna, Alaska\",\"time\":1453631430230,\"updated\":1460156770040,\"tz\":-540,\"url\":\"http://Earthquake.usgs.gov/earthquakes/eventpage/us10004gqp\",\"detail\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us10004gqp&format=geojson\",\"felt\":1816,\"cdi\":7.2,\"mmi\":6.6,\"alert\":\"green\",\"status\":\"reviewed\",\"tsunami\":1,\"sig\":1496,\"net\":\"us\",\"code\":\"10004gqp\",\"ids\":\",at00o1gd6r,us10004gqp,ak12496371,gcmt20160124103030,\",\"sources\":\",at,us,ak,gcmt,\",\"types\":\",cap,dyfi,finite-fault,general-link,general-text,geoserve,impact-link,impact-text,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,trump-origin,\",\"nst\":null,\"dmin\":0.72,\"rms\":2.11,\"gap\":19,\"magType\":\"mww\",\"type\":\"Earthquake\",\"title\":\"M 7.1 - 86km E of Old Iliamna, Alaska\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[-153.4051,59.6363,129]},\"id\":\"us10004gqp\"},\n" + "{\"type\":\"Feature\",\"properties\":{\"mag\":6.6,\"place\":\"215km SW of Tomatlan, Mexico\",\"time\":1453399617650,\"updated\":1459963829040,\"tz\":-420,\"url\":\"http://Earthquake.usgs.gov/earthquakes/eventpage/us10004g4l\",\"detail\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us10004g4l&format=geojson\",\"felt\":11,\"cdi\":2.7,\"mmi\":3.92,\"alert\":\"green\",\"status\":\"reviewed\",\"tsunami\":1,\"sig\":673,\"net\":\"us\",\"code\":\"10004g4l\",\"ids\":\",at00o1bebo,pt16021050,us10004g4l,gcmt20160121180659,\",\"sources\":\",at,pt,us,gcmt,\",\"types\":\",cap,dyfi,geoserve,impact-link,impact-text,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,\",\"nst\":null,\"dmin\":2.413,\"rms\":0.98,\"gap\":74,\"magType\":\"mww\",\"type\":\"Earthquake\",\"title\":\"M 6.6 - 215km SW of Tomatlan, Mexico\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[-106.9337,18.8239,10]},\"id\":\"us10004g4l\"},\n" + "{\"type\":\"Feature\",\"properties\":{\"mag\":6.7,\"place\":\"52km SE of Shizunai, Japan\",\"time\":1452741933640,\"updated\":1459304879040,\"tz\":540,\"url\":\"http://Earthquake.usgs.gov/earthquakes/eventpage/us10004ebx\",\"detail\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us10004ebx&format=geojson\",\"felt\":51,\"cdi\":5.8,\"mmi\":6.45,\"alert\":\"green\",\"status\":\"reviewed\",\"tsunami\":1,\"sig\":720,\"net\":\"us\",\"code\":\"10004ebx\",\"ids\":\",us10004ebx,pt16014050,at00o0xauk,gcmt20160114032534,\",\"sources\":\",us,pt,at,gcmt,\",\"types\":\",associate,cap,dyfi,geoserve,impact-link,impact-text,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,\",\"nst\":null,\"dmin\":0.281,\"rms\":0.98,\"gap\":22,\"magType\":\"mww\",\"type\":\"Earthquake\",\"title\":\"M 6.7 - 52km SE of Shizunai, Japan\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[142.781,41.9723,46]},\"id\":\"us10004ebx\"},\n" + "{\"type\":\"Feature\",\"properties\":{\"mag\":6.1,\"place\":\"12km WNW of Charagua, Bolivia\",\"time\":1452741928270,\"updated\":1459304879040,\"tz\":-240,\"url\":\"http://Earthquake.usgs.gov/earthquakes/eventpage/us10004ebw\",\"detail\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us10004ebw&format=geojson\",\"felt\":3,\"cdi\":2.2,\"mmi\":2.21,\"alert\":\"green\",\"status\":\"reviewed\",\"tsunami\":0,\"sig\":573,\"net\":\"us\",\"code\":\"10004ebw\",\"ids\":\",us10004ebw,gcmt20160114032528,\",\"sources\":\",us,gcmt,\",\"types\":\",cap,dyfi,geoserve,impact-text,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,\",\"nst\":null,\"dmin\":5.492,\"rms\":1.04,\"gap\":16,\"magType\":\"mww\",\"type\":\"Earthquake\",\"title\":\"M 6.1 - 12km WNW of Charagua, Bolivia\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[-63.3288,-19.7597,582.56]},\"id\":\"us10004ebw\"},\n" + "{\"type\":\"Feature\",\"properties\":{\"mag\":6.2,\"place\":\"74km NW of Rumoi, Japan\",\"time\":1452532083920,\"updated\":1459304875040,\"tz\":540,\"url\":\"http://Earthquake.usgs.gov/earthquakes/eventpage/us10004djn\",\"detail\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us10004djn&format=geojson\",\"felt\":8,\"cdi\":3.4,\"mmi\":3.74,\"alert\":\"green\",\"status\":\"reviewed\",\"tsunami\":0,\"sig\":594,\"net\":\"us\",\"code\":\"10004djn\",\"ids\":\",us10004djn,gcmt20160111170803,\",\"sources\":\",us,gcmt,\",\"types\":\",cap,dyfi,geoserve,impact-text,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,\",\"nst\":null,\"dmin\":1.139,\"rms\":0.96,\"gap\":33,\"magType\":\"mww\",\"type\":\"Earthquake\",\"title\":\"M 6.2 - 74km NW of Rumoi, Japan\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[141.0867,44.4761,238.81]},\"id\":\"us10004djn\"},\n" + "{\"type\":\"Feature\",\"properties\":{\"mag\":6.5,\"place\":\"227km SE of Sarangani, Philippines\",\"time\":1452530285900,\"updated\":1459304874040,\"tz\":480,\"url\":\"http://Earthquake.usgs.gov/earthquakes/eventpage/us10004dj5\",\"detail\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us10004dj5&format=geojson\",\"felt\":1,\"cdi\":2.7,\"mmi\":7.5,\"alert\":\"green\",\"status\":\"reviewed\",\"tsunami\":1,\"sig\":650,\"net\":\"us\",\"code\":\"10004dj5\",\"ids\":\",at00o0srjp,pt16011050,us10004dj5,gcmt20160111163807,\",\"sources\":\",at,pt,us,gcmt,\",\"types\":\",cap,dyfi,geoserve,impact-link,impact-text,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,\",\"nst\":null,\"dmin\":3.144,\"rms\":0.72,\"gap\":22,\"magType\":\"mww\",\"type\":\"Earthquake\",\"title\":\"M 6.5 - 227km SE of Sarangani, Philippines\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[126.8621,3.8965,13]},\"id\":\"us10004dj5\"},\n" + "{\"type\":\"Feature\",\"properties\":{\"mag\":6,\"place\":\"Pacific-Antarctic Ridge\",\"time\":1451986454620,\"updated\":1459202978040,\"tz\":-540,\"url\":\"http://Earthquake.usgs.gov/earthquakes/eventpage/us10004bgk\",\"detail\":\"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us10004bgk&format=geojson\",\"felt\":0,\"cdi\":1,\"mmi\":0,\"alert\":\"green\",\"status\":\"reviewed\",\"tsunami\":0,\"sig\":554,\"net\":\"us\",\"code\":\"10004bgk\",\"ids\":\",us10004bgk,gcmt20160105093415,\",\"sources\":\",us,gcmt,\",\"types\":\",cap,dyfi,geoserve,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,\",\"nst\":null,\"dmin\":30.75,\"rms\":0.67,\"gap\":71,\"magType\":\"mww\",\"type\":\"Earthquake\",\"title\":\"M 6.0 - Pacific-Antarctic Ridge\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[-136.2603,-54.2906,10]},\"id\":\"us10004bgk\"}],\"bbox\":[-153.4051,-54.2906,10,158.5463,59.6363,582.56]}"; private QueryUtils() { public static ArrayList<Earthquake> extractEarthquakes() { ArrayList<Earthquake> earthquakes = new ArrayList<>(); try { JSONObject baseJsonResponse = new JSONObject(SAMPLE_JSON_RESPONSE); JSONArray earthquakeArray = baseJsonResponse.getJSONArray("features"); for (int i = 0; i < earthquakeArray.length(); i++) { JSONObject currentEarthquake = earthquakeArray.getJSONObject(i); JSONObject properties = currentEarthquake.getJSONObject("properties"); String magnitude = properties.getString("mag"); String location = properties.getString("place"); String time = properties.getString("time"); Earthquake earthquake = new Earthquake(magnitude, location, time); earthquakes.add(earthquake); } } catch (JSONException e) { Log.e("QueryUtils", "Problem parsing the Earthquake JSON results", e); } return earthquakes; }
In order to create a JSON object from a string is has to be properly escaped and it currently isn't There is a lot of JSON in your post so I've taken the first line of the JSON to use as an example (this would be the first features object). I then unescaped the JSON and then validated the json. There are many tools to do this, but I used https://www.freeformatter.com/json-escape.html for formatting and https://jsonlint.com/ for validating the JSON. I found a few issues with the JSON object (around the new line \n escaping). I've been able to then escape the JSON by pasting it into Android Studio as shown below and the JSON now parses the string into a JSONObject. I suggest you do the same and go line by line until you have validated all of the JSON and then paste the valid JSON between the quotation marks private static final String SAMPLE_JSON_RESPONSE = ""; Android Studio (and hopefully other IDEs should then escape the JSON correctly, or you'll have to use a JSON escaping utility) private static final String SAMPLE_JSON_RESPONSE = "{\n" + "\t\"type\": \"FeatureCollection\",\n" + "\t\"metadata\": {\n" + "\t\t\"generated\": 1462295443000,\n" + "\t\t\"url\": \"http://Earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2016-01-01&endtime=2016-01-31&minmag=6&limit=10\",\n" + "\t\t\"title\": \"USGS Earthquakes\",\n" + "\t\t\"status\": 200,\n" + "\t\t\"api\": \"1.5.2\",\n" + "\t\t\"limit\": 10,\n" + "\t\t\"offset\": 1,\n" + "\t\t\"count\": 10\n" + "\t},\n" + "\t\"features\": [{\n" + "\t\t\"type\": \"Feature\",\n" + "\t\t\"properties\": {\n" + "\t\t\t\"mag\": 7.2,\n" + "\t\t\t\"place\": \"88km N of Yelizovo, Russia\",\n" + "\t\t\t\"time\": 1454124312220,\n" + "\t\t\t\"updated\": 1460674294040,\n" + "\t\t\t\"tz\": 720,\n" + "\t\t\t\"url\": \"http://Earthquake.usgs.gov/earthquakes/eventpage/us20004vvx\",\n" + "\t\t\t\"detail\": \"http://Earthquake.usgs.gov/fdsnws/event/1/query?eventid=us20004vvx&format=geojson\",\n" + "\t\t\t\"felt\": 2,\n" + "\t\t\t\"cdi\": 3.4,\n" + "\t\t\t\"mmi\": 5.82,\n" + "\t\t\t\"alert\": \"green\",\n" + "\t\t\t\"status\": \"reviewed\",\n" + "\t\t\t\"tsunami\": 1,\n" + "\t\t\t\"sig\": 798,\n" + "\t\t\t\"net\": \"us\",\n" + "\t\t\t\"code\": \"20004vvx\",\n" + "\t\t\t\"ids\": \",at00o1qxho,pt16030050,us20004vvx,gcmt20160130032510,\",\n" + "\t\t\t\"sources\": \",at,pt,us,gcmt,\",\n" + "\t\t\t\"types\": \",cap,dyfi,finite-fault,general-link,general-text,geoserve,impact-link,impact-text,losspager,moment-tensor,nearby-cities,origin,phase-data,shakemap,tectonic-summary,\",\n" + "\t\t\t\"nst\": null,\n" + "\t\t\t\"dmin\": 0.958,\n" + "\t\t\t\"rms\": 1.19,\n" + "\t\t\t\"gap\": 17,\n" + "\t\t\t\"magType\": \"mww\",\n" + "\t\t\t\"type\": \"Earthquake\",\n" + "\t\t\t\"title\": \"M 7.2 - 88km N of Yelizovo, Russia\"\n" + "\t\t},\n" + "\t\t\"geometry\": {\n" + "\t\t\t\"type\": \"Point\",\n" + "\t\t\t\"coordinates\": [158.5463, 53.9776, 177]\n" + "\t\t},\n" + "\t\t\"id\": \"us20004vvx\"\n" + "\t}]\n" + "}"; JSONObject baseJsonResponse = new JSONObject(SAMPLE_JSON_RESPONSE);
Android - Cannot read JSON string with Whitespace
I have a problem reading string from JSONArray. the try-catch surrounding the code fire an error for element not found. I suspect it is related with the whitespace that is the character at the end of each key of the rows. JSONArray dettaglio = result.getJSONArray("dettaglioAttivita"); for(int i = 0; i <dettaglio.length(); i++){ JSONObject row = dettaglio.getJSONObject(i); String durata = row.getString("Durata "); Toast.makeText(getApplicationContext(), durata.toString(), Toast.LENGTH_LONG).show(); } JSON RESPONSE: Note that key string of JSONObject have a whitespace at the end. "dettaglioAttivita": [ { "Unità Dididattica ": " FISICA - MODULO A - [UD-1] ", "Tipo Attività ": " LEZ", "Tipo Formaz. ": " Base", "Settore ": " FIS/01 - FISICA SPERIMENTALE", "CFU ": " 6", "Durata ": " 48" }, { "Unità Dididattica ": " FISICA - MODULO B - [UD-2] ", "Tipo Attività ": " LEZ", "Tipo Formaz. ": " Base", "Settore ": " FIS/01 - FISICA SPERIMENTALE", "CFU ": " 6", "Durata ": " 48" } ], the exception is: org.json.JSONException: no value for Durata
Just tested in kotlin and for me it`s working with spaces: import org.json.JSONObject fun main(args : Array<String>) { val json = """ { "dettaglioAttivita": [ { "UnitàDididattica ":"FISICA - MODULO A - [UD-1]", "TipoAttività ":"LEZ", "TipoFormaz. ":"Base", "Settore ": "FIS/01 - FISICA SPERIMENTALE", "CFU":" 6", "Durata ":" 48" }, { "UnitàDididattica ":"FISICA - MODULO B - [UD-2]", "TipoAttivit à":"LEZ", "TipoFormaz ":"Base", "Settore ":"FIS/01 - FISICA SPERIMENTALE", "CFU ":"6", "Durata ":" 48" } ] } """ println(json) try { val jsonObject = JSONObject(json) val dettaglio = jsonObject.getJSONArray("dettaglioAttivita") for (i in 0 until dettaglio.length()) { val row = dettaglio.getJSONObject(i) println("ROW: $row") val durata = row.getString("Durata ") println("DURATA: $durata") } }catch (e : Throwable){ println(e.toString()) } } Printed out in for: ROW: {"Durata ":" 48","UnitàDididattica ":"FISICA - MODULO A - [UD-1]","TipoFormaz. ":"Base","CFU":" 6","TipoAttività ":"LEZ","Settore ":"FIS/01 - FISICA SPERIMENTALE"} DURATA: 48 ROW: {"Durata ":" 48","CFU ":"6","UnitàDididattica ":"FISICA - MODULO B - [UD-2]","TipoFormaz ":"Base","TipoAttivit à":"LEZ","Settore ":"FIS/01 - FISICA SPERIMENTALE"} DURATA: 48
How to parse following JSOn DATA
[ { "ORDERID": [ "Epp144534354354", "Epp14453sdfgsfd", "Epp14487484", "Epp144454464646" ], "ADDRESS": " MUMBAI", "FOLLOW_UPDATE": "25/5/2017", "SIGN_IMAGE": "sign.png", "DATE_TIME": "2017-05-02 17:52:09.0", "EMAIL": "abhi#abhi.con", "IMAGE_1": "image1.jpg", "COMMENT": "gshshshsh", "IMAGE_3": "image3.jpg", "NAME": "abhi", "MOBILE": "22416545", "IMAGE_2": "image2.jpg" } ] I want to parse above json data then how to parse the json in android how to parse code in java
You can try this.Here is JSON parsing in android. String response=" [\n" + "{ \"ORDERID\": [ \"Epp144534354354\", \"Epp14453sdfgsfd\", \"Epp14487484\", \"Epp144454464646\"],\n" + "\n" + "\"ADDRESS\": \" 26, Wakad Road Samarth Colony, Omkar Society, Pimple Nilakh Pimpri-Chinchwad, Maharashtra 411027\",\n" + "\n" + "\"FOLLOW_UPDATE\": \"25/5/2017\",\n" + "\n" + "\"SIGN_IMAGE\": \"http://192.168.0.108:8084/MarketingApplicationImages/IMAGES//sign.png\",\n" + "\n" + "\"DATE_TIME\": \"2017-05-02 17:52:09.0\",\n" + "\n" + "\"EMAIL\": \"abhi#abhi.con\",\n" + "\n" + "\"IMAGE_1\": \"http://192.168.0.108:8084/MarketingApplicationImages/IMAGES//image1.jpg\",\n" + "\n" + "\"COMMENT\": \"gshshshsh\",\n" + "\n" + "\"IMAGE_3\": \"http://192.168.0.108:8084/MarketingApplicationImages/IMAGES//image3.jpg\",\n" + "\n" + "\"NAME\": \"abhi\",\n" + "\n" + "\"MOBILE\": \"8149608493\",\n" + "\n" + "\"IMAGE_2\": \"http://192.168.0.108:8084/MarketingApplicationImages/IMAGES//image2.jpg\"\n" + " }]"; try { JSONArray jArray=new JSONArray(response); for (int i = 0; i <jArray.length() ; i++) { JSONObject jonj=jArray.getJSONObject(i); JSONArray orderArray=jonj.getJSONArray("ORDERID"); for (int j = 0; j <orderArray.length(); j++) { Log.e("array value"," ..... "+orderArray.getString(i)); } Log.e("address"," ..... "+jonj.getString("ADDRESS")); Log.e("FOLLOW_UPDATE"," ..... "+jonj.getString("FOLLOW_UPDATE")); Log.e("SIGN_IMAGE"," ..... "+jonj.getString("SIGN_IMAGE")); } } catch (JSONException e) { e.printStackTrace(); }
To parse json please follow this basic rules which will help you in long run. First check if json is valid or not, paste your json response and click validate json. To view json content in proper format to understand better use paste your data in text section and switch to view section to view it. Then use GSON library to parse the data(refer any online tutorial) You would require pojo's for GSON use paste json response in the text box section which is located on the left hand side and then on the right hand side set source type as JSON annotation type as GSON and click on the preview at the bottom of the page, copy it and use it.
Json to POJO mapping in Android
What are good practice for handling json over a Rest Framework in Android. For instance, if I get a certain json result as follow (or any other, I'm just giving something more complex): {"lifts": [{ "id":26, "time":"2012-11-21T12:00:00Z", "capacity":4, "price":10, "from": { "description":null, "city": { "name":"Montreal" } }, "to":{ "description":"24 rue de la ville", "city":{ "name":"Sherbrooke" } }, "driver":{ "first_name": "Benjamin", "image":"https://graph.facebook.com/693607843/picture?type=large" } } ]} 1) Should I handle the result manually and get each value to populate my ui... (Not really) 2) Should I create a POJO for each object (to handle the mapping, with JSONObject). In my example, I will have to create a lift object that handle all the parameters and even create more POJO, to use for instance image and probably locations. (so basically, I constantly need to check my api rest framework to see how my object are done on server side, I'm duplicating my models from server to the android client). 3) Is there any framework to handle the mapping (serialize and deserialization). I'm currently using option number 2, but was wondering if there was something better out there. It's working for me so far, for receiving and sending.
I like to create a response object per api endpoint where i map the response of the call. For the given example and using GSON, the response object would be something like the following public class Test { static String jsonString = "{\"lifts\":" + " [{" + " \"id\":26," + " \"time\":\"2012-11-21T12:00:00Z\"," + " \"capacity\":4," + " \"price\":10," + " \"from\": { " + " \"description\":null," + " \"city\": {" + " \"name\":\"Montreal\"" + " }" + " }," + " \"to\":{" + " \"description\":\"24 rue de la ville\"," + " \"city\":{" + " \"name\":\"Sherbrooke\"" + " }" + " }," + " \"driver\":{" + " \"first_name\": \"Benjamin\"," + " \"image\":\"https://graph.facebook.com/693607843/picture? type=large\"" + " }" + " }" + " ]}"; public static void main( String[] args ) { Gson gson = new Gson(); Response response = gson.fromJson( jsonString, Response.class ); System.out.println( gson.toJson( response ) ); } public class Response { #SerializedName("lifts") List<Lift> lifts; } class Lift { #SerializedName("id") int id; #SerializedName("time") String time; #SerializedName("capacity") int capacity; #SerializedName("price") float price; #SerializedName("from") Address from; #SerializedName("to") Address to; #SerializedName("driver") Driver driver; } class Address { #SerializedName("description") String description; #SerializedName("city") City city; } class City { #SerializedName("name") String name; } class Driver { #SerializedName("first_name") String firstName; #SerializedName("image") String image; } }