Related
I've been trying to parse the objects from this object that is inside an array inside another array. I made two loops because there are multiple objects that i'm trying to make a list from.
This is what the json looks like
{
"type": "FeatureCollection",
"metadata": {
"generated": 1522105396000,
"url": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/4.5_day.geojson",
"title": "USGS Magnitude 4.5+ Earthquakes, Past Day",
"status": 200,
"api": "1.5.8",
"count": 7
},
"features": [{
"type": "Feature",
"properties": {
"mag": 4.7,
"place": "106km SW of Hihifo, Tonga",
"time": 1522100348420,
"updated": 1522102052040,
"tz": -720,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us1000d9c6",
"detail": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/us1000d9c6.geojson",
"felt": null,
"cdi": null,
"mmi": null,
"alert": null,
"status": "reviewed",
"tsunami": 0,
"sig": 340,
"net": "us",
"code": "1000d9c6",
"ids": ",us1000d9c6,",
"sources": ",us,",
"types": ",geoserve,origin,phase-data,",
"nst": null,
"dmin": 3.738,
"rms": 0.85,
"gap": 66,
"magType": "mb",
"type": "earthquake",
"title": "M 4.7 - 106km SW of Hihifo, Tonga"
},
"geometry": {
"type": "Point",
"coordinates": [-174.4796, -16.604, 175.39]
},
"id": "us1000d9c6"
},
{
"type": "Feature",
"properties": {
"mag": 4.8,
"place": "West Chile Rise",
"time": 1522025174820,
"updated": 1522026587040,
"tz": -360,
"url": "https://earthquake.usgs.gov/earthquakes/eventpage/us1000d90k",
"detail": "https://earthquake.usgs.gov/earthquakes/feed/v1.0/detail/us1000d90k.geojson",
"felt": null,
"cdi": null,
"mmi": null,
"alert": null,
"status": "reviewed",
"tsunami": 0,
"sig": 354,
"net": "us",
"code": "1000d90k",
"ids": ",us1000d90k,",
"sources": ",us,",
"types": ",geoserve,origin,phase-data,",
"nst": null,
"dmin": 9.665,
"rms": 0.87,
"gap": 192,
"magType": "mb",
"type": "earthquake",
"title": "M 4.8 - West Chile Rise"
},
"geometry": {
"type": "Point",
"coordinates": [-86.6644, -41.0452, 10]
},
"id": "us1000d90k"
}
],
"bbox": [-178.6721, -56.8886, 10, 151.396, 56.3364, 541.02]
}
I just need the place, magnitude and time from both arrays but i can't seem to pick the right array to get the object from. ex:(features.properties.place)
List<String> allPlaces = new ArrayList<>();
JSONArray JA = new JSONArray(data);
JSONArray features = JA.getJSONArray(2);
// JSONArray properties = features.getJSONArray(1);
for (int i = 0; i < features.length(); i++){
JSONArray properties = (JSONArray) features.get(i);
for (int j = 0; j < properties.length(); j++){
JSONObject JO = (JSONObject) features.get(i);
String place = JO.getString("place");
singlePlace = "place: " + place;
dataPlace = "" + singlePlace;
allPlaces.add(place);
}
edit1: to be clear, i am able to get information from the first array, so the value of type, but not anything inside of features,
A problem is that you are parsing the properties as a JSONArray but in fact it's a JSONObject. So, you should try this loop to parse needed data:
JSONObject root = new JSONObject(data); //Where `data` is your raw json string
JSONArray features = root.getJSONArray("features");
for (int i = 0; i < features.length(); i++) {
JSONObject properties = features.getJSONObject(i).getJSONObject("properties");
double mag = properties.getDouble("mag");
String place = properties.getString("place");
long time = properties.getLong("time");
}
I'm working on an Android admissions app and I'm trying to do a Khan connection into my app through the API with a basic search functionality where a user can enter a keyword and the app shows a list of topics / videos / exercises that match search criteria but I'm finding it almost impossible as API doesn't provide an official "Search by keyword" method, and as any who works with Khan may know its impossible to download the full topic tree as it ends in a 70mb file.
It's been many days of hard research and struggling my head but still wasn't able to find any documentation (if any) on how to deal with this so I thougth on asking for help. Does anyone have any idea on how to deal with this or anyone who successfully done it who can give me some hints on which direction to take?
I know you can do http://www.khanacademy.org/api/v1/topictree?kind=topic (for example) but even with this filter the json results are huge (more than 10mb stream of data).
This is the way I stream the json:
private static String connect2Url(String urlString){
URL url;
HttpURLConnection urlConnection = null;
InputStream inStream = null;
StringBuilder response = new StringBuilder();
try {
url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoInput(true);
urlConnection.connect();
inStream = urlConnection.getInputStream();
BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));
String temp = "";
while ((temp = bReader.readLine()) != null) {
response.append(temp);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inStream != null) {
try {
inStream.close();
} catch (IOException ignored) {
}
}
if (urlConnection != null) {
urlConnection.disconnect();
}
}
return response.toString();
}
And then I create the JSONObject with this result.
For the moment I'm passing "http://www.khanacademy.org/api/v1/topic/%s" as url but with this you can only locate topic by id (topic slug) but cannot make a free search.
Ok, I hope anyone can help, and thanks in advance.
Edit:
As per AlphaQ suggestion I'm already investigating about GSON and Jackson and of course agree with him my parsing function is not efficient for big json streaming but anyway I'm running into two problems, the first is the json structure returned by Khan Academy is quite complex to create a class of it (I think) and the second is even if I can make a more efficient parsing the more I'm being able to filter Khan Academy json response from server is resulting in 14mb of data (the full tree is 70mb) and I guess this is still too much for a mobile app regardless on how optimized my function is, because it will have to download 14mb anyway and Khan Academy API doesn't provide a "search by keyword" method.
Give me your opinion, don't you think 14mb is still too much json data to stream for a mobile app?
This is a very little extract from the json response as an example:
{
"icon_src": "",
"twitter_url": "",
"domain_slug": null,
"relative_url": "/",
"creation_date": "2016-12-14T00:46:38Z",
"web_url": "",
"ka_url": "https://www.khanacademy.org/",
"translated_standalone_title": "Khan Academy",
"has_user_authored_content_types": true,
"translated_title": "Khan Academy",
"gplus_url": "",
"children": [{
"icon_src": "",
"twitter_url": "",
"domain_slug": "new-and-noteworthy",
"relative_url": "/new-and-noteworthy",
"creation_date": "2016-09-13T20:35:19Z",
"web_url": "",
"ka_url": "https://www.khanacademy.org/new-and-noteworthy",
"translated_standalone_title": "New and noteworthy",
"has_user_authored_content_types": false,
"translated_title": "New and noteworthy",
"gplus_url": "",
"children": [],
"hide": false,
"node_slug": "new-and-noteworthy",
"title": "New and noteworthy",
"child_data": [{
"kind": "Video",
"id": "1101921746"
}, {
"kind": "Video",
"id": "796509722"
}, {
"kind": "Video",
"id": "796388970"
}, {
"kind": "Video",
"id": "753767269"
}, {
"kind": "Video",
"id": "225139731"
}, {
"kind": "Video",
"id": "225139729"
}, {
"kind": "Video",
"id": "988721865"
}, {
"kind": "Video",
"id": "884313452"
}, {
"kind": "Video",
"id": "671536496"
}, {
"kind": "Video",
"id": "887553535"
}, {
"kind": "Video",
"id": "1049279550"
}, {
"kind": "Video",
"id": "796535894"
}, {
"kind": "Video",
"id": "796307891"
}, {
"kind": "Video",
"id": "1094139389"
}, {
"kind": "Video",
"id": "796502981"
}, {
"kind": "Video",
"id": "796434657"
}, {
"kind": "Video",
"id": "871510490"
}, {
"kind": "Video",
"id": "884392300"
}, {
"kind": "Video",
"id": "x77e83a17"
}, {
"kind": "Video",
"id": "884395195"
}, {
"kind": "Video",
"id": "1077533640"
}, {
"kind": "Video",
"id": "1094227108"
}, {
"kind": "Video",
"id": "1094119956"
}, {
"kind": "Video",
"id": "1112847811"
}, {
"kind": "Video",
"id": "1114711148"
}, {
"kind": "Video",
"id": "1081957510"
}, {
"kind": "Video",
"id": "1095856196"
}, {
"kind": "Video",
"id": "1090948774"
}, {
"kind": "Video",
"id": "1013985489"
}, {
"kind": "Video",
"id": "xca214ba1"
}
],
"user_authored_content_types_info": [],
"id": "x29232c6b",
"user_authored_content_types": [],
"translated_description": "",
"alternate_slugs": [],
"standalone_title": "New and noteworthy",
"logo_image_url": "",
"in_knowledge_map": false,
"description": "",
"tags": [],
"deleted": false,
"listed_locales": [],
"facebook_url": "",
"render_type": "UncuratedTutorial",
"background_image_url": "",
"background_image_caption": "",
"has_peer_reviewed_projects": false,
"topic_page_url": "/new-and-noteworthy",
"extended_slug": "new-and-noteworthy",
"deleted_mod_time": "2013-07-13T00:03:09Z",
"kind": "Topic",
"curation": {},
"slug": "new-and-noteworthy",
"do_not_publish": false,
"sha": "a6c251bd225b9d23e1a98f1a7fce3ccd0c8cb4fa",
"branding_image_url": "",
"current_revision_key": "a6c251bd225b9d23e1a98f1a7fce3ccd0c8cb4fa",
"content_id": "x29232c6b",
"content_kind": "Topic",
"curriculum_key": ""
}, {
"icon_src": "",
"twitter_url": "",
"domain_slug": "math",
"relative_url": "/math",
"creation_date": "2017-05-08T20:15:34Z",
"web_url": "",
"ka_url": "https://www.khanacademy.org/math",
"translated_standalone_title": "Math",
"has_user_authored_content_types": false,
"translated_title": "Math",
"gplus_url": "",
"children": [{
"icon_src": "",
"twitter_url": "",
"domain_slug": "math",
"relative_url": "/math/k-8-grades",
"creation_date": "2017-03-17T23:26:26Z",
"web_url": "",
"ka_url": "https://www.khanacademy.org/math/k-8-grades",
"translated_standalone_title": "K-8th grades",
"has_user_authored_content_types": false,
"translated_title": "K-8th grades",
"gplus_url": "",
"children": [],
"hide": false,
"node_slug": "k-8-grades",
"title": "K-8th grades",
"child_data": [],
"user_authored_content_types_info": [],
"id": "xf3cb93f0",
"user_authored_content_types": [],
"translated_description": "",
"alternate_slugs": [],
"standalone_title": "K-8th grades",
"logo_image_url": "",
"in_knowledge_map": false,
"description": "",
"tags": [],
"deleted": false,
"listed_locales": ["fr", "en", "pt", "de", "tr", "pl", "nb", "es"],
"facebook_url": "",
"render_type": "Subject",
"background_image_url": "",
"background_image_caption": "",
"has_peer_reviewed_projects": false,
"topic_page_url": "/math/k-8-grades",
"extended_slug": "math/k-8-grades",
"deleted_mod_time": null,
"kind": "Topic",
"curation": {
"modules": [{
"content": ["Video:xd2b0fcb4", "Article:x175a9d66", "Video:x102d9798", "Exercise:2015", "Exercise:3022"],
"referrer": "k_8_grades_staff_picks",
"kind": "ContentCarousel",
"title": "Staff picks"
}, {
"topic": "Topic:xd0ae8a03",
"kind": "SubjectIntro"
}
],
"whitelist": ["Topic:xfe881476a971a3cb", "Topic:xb5feb28c", "Topic:xcef32ab6", "Topic:xef8f4cb4", "Topic:x3184e0ec", "Topic:xc7f617f2", "Topic:x5ec3eb59", "Topic:xb830458a", "Topic:x0267d782", "Topic:x6b17ba59", "Topic:x7c7044d7", "Topic:xa617314f", "Topic:x8708676b", "Topic:x7ed4701d", "Topic:x6ee1f3c2", "Topic:x0f2eb71b", "Topic:xa18e5391"],
"hide_community_questions": true
},
Edit 2:
I was reading all GSON documentation AlphaQ suggested me and checking out some examples but my json response is a little bit complex and I can't figure out how to define mapping class(es).
Below is the url from where I am getting the json.
Any help on how to define correctly mapping class(es) will be much appreciated.
http://www.khanacademy.org/api/v1/topictree
(this is without any filtering but I could add ?kind=topic to see a full list of topics, but no more filters are allowed)
The above is a 70mb stream so I don't think it will be possible even with GSON but for me would be anough if I can do this
http://www.khanacademy.org/api/v1/topic/math
to retrieve all math topics from this huge file.
As you see the json is too big and complex so I am not being able to figure out how to create mapping classes for this. I only need url, title and description of topics located under "children" nodes.
I will recommend you use GSON or Jackson like I said in comments.
You can use the hybrid streaming approach in Jackson to efficiently parse only the required data from the stream.
Here's an example of using GSON.
Here's a piece of info of what the guys at Google are saying:
Deserialized strings of over 25MB without any problems
More information here.
You can use http://json2csharp.com/ to create mapping classes for the json. If you have Visual Studio you can also copy the json and "Paste special" to create classes automatically in Visual studio.
I have to parse the Json below. I know how to obtain Json from a JsonArray when it has a key. How do I do this when I don't have any key?
[
{
"kind": "track",
"id": 253792869,
"created_at": "2016/03/21 15:20:47 +0000",
"user_id": 167064157,
"duration": 9457,
"commentable": true,
"state": "finished",
"original_content_size": 375488,
"last_modified": "2016/03/21 15:20:48 +0000",
"sharing": "public",
"tag_list": "commercial",
"permalink": "2016-03-08_lbs_bigfm_spot_3",
"streamable": true,
"embeddable_by": "all",
"downloadable": false,
"purchase_url": null,
"label_id": null,
"purchase_title": null,
"genre": "",
"title": "2016-03-08_LBS_BigFM_SPOT_3",
"description": "",
"label_name": null,
"release": null,
"track_type": null,
"key_signature": null,
"isrc": null,
"video_url": null,
"bpm": null,
"release_year": null,
"release_month": null,
"release_day": null,
"original_format": "mp3",
"license": "all-rights-reserved",
"uri": "https://api.soundcloud.com/tracks/253792869",
"user": {
"id": 167064157,
"kind": "user",
"permalink": "user690075536",
"username": "user690075536",
"last_modified": "2016/02/26 08:19:23 +0000",
"uri": "https://api.soundcloud.com/users/167064157",
"permalink_url": "http://soundcloud.com/user690075536",
"avatar_url": "https://i1.sndcdn.com/avatars-000159639971-j1awdb-large.jpg"
},
"permalink_url": "http://soundcloud.com/user690075536/2016-03-08_lbs_bigfm_spot_3",
"artwork_url": "https://i1.sndcdn.com/artworks-000152760877-s9mcat-large.jpg",
"waveform_url": "https://w1.sndcdn.com/8Ijd5YlUn9iW_m.png",
"stream_url": "https://api.soundcloud.com/tracks/253792869/stream",
"playback_count": 0,
"download_count": 0,
"favoritings_count": 0,
"comment_count": 0,
"attachments_uri": "https://api.soundcloud.com/tracks/253792869/attachments"
}
]
Valid JSON:
{
"abc":[
{
"name":"Ram"
},
{
"name":"Shyam"
},
{
"name":"Mohan"
},
{
"name":"Pankaj"
},
{
"name":"Komal"
}
]
}
try
{
JSONArray jsonArray = new JSONArray(jsonStrFromSoundCloud);
for (int i = 0; i < jsonArray.length(); i++) {
//loop in array
}
} catch (JSONException e) {
e.printStackTrace();
}
I got my answer, I bind this array inside a json object. then fetch it.
similar like this.
"{\"data\":"+ jsonArray+"}";
I tried to solve similar issue by creating a json array.
[{ "name":"dave",
"age":23
},
{
"name" : "dexter"
"age" : 24
}]
Here is my POJO
public class MyPojo {
private String name;
private int age;
// Getter & Setters
}
And this is all you need to do to parse the JSON to List object.
Type listType = new TypeToken<ArrayList<MyPojo>>(){}.getType();
List<MyPojo> jsonObject = new Gson().fromJson(response, listType);
Hope this helps. :)
EDIT
Don't forget to Import : import java.lang.reflect.Type;
I am trying to access value of 'cod' from the json string :
{"coord":{"lon":73.86,"lat":18.52},"sys":{"message":0.0293,"country":"IN","sunrise":1428972502,"sunset":1429017681},"weather":[{"id":801,"main":"Clouds","description":"few clouds","icon":"02d"}],"base":"stations","main":{"temp":304.301,"temp_min":304.301,"temp_max":304.301,"pressure":951.61,"sea_level":1021.56,"grnd_level":951.61,"humidity":36},"wind":{"speed":2.06,"deg":302.501},
"clouds":{"all":24},"dt":1428996633,"id":1259229,"name":"Pune","cod":200}
But I am not able to get this value from my code. the code I am using to access this value from json string is as:
try{
JSONObject jsObject=(new JSONObject(JsonString)).getJSONObject("coord");
if( jsObject.getInt("cod")==200) {
i.putExtra("jsn", JsonString);
i.putExtra("city", etCity.getText().toString());
startActivity(i);
}
In the if condition, you are trying to access the key "cod" in the array {"lon":73.86,"lat":18.52}. It will throw a JSONException.
Try this :
try{
JSONObject jsonmain = new JSONOBject(JsonString);
if(jsonmain.getInt("cod") == 200) {
i.putExtra("jsn", JsonString);
i.putExtra("city", etCity.getText().toString());
startActivity(i);
}
Your json is:
{
"coord": {
"lon": 73.86,
"lat": 18.52
},
"sys": {
"message": 0.0293,
"country": "IN",
"sunrise": 1428972502,
"sunset": 1429017681
},
"weather": [
{
"id": 801,
"main": "Clouds",
"description": "few clouds",
"icon": "02d"
}
],
"base": "stations",
"main": {
"temp": 304.301,
"temp_min": 304.301,
"temp_max": 304.301,
"pressure": 951.61,
"sea_level": 1021.56,
"grnd_level": 951.61,
"humidity": 36
},
"wind": {
"speed": 2.06,
"deg": 302.501
},
"clouds": {
"all": 24
},
"dt": 1428996633,
"id": 1259229,
"name": "Pune",
"cod": 200
}
The key "cod" is not nested inside "coord".
Try:
new JSONObject(JsonString)).getInt("cod");
Actually you are trying wrong JSON Object.
String cod=(new JSONObject(JsonString)).getJSONObject("code").toString();
//you may need to try catch block
if( Integer.parseint(cod)==200) {
.... Your logic
}
For example : if the given below is json of the person's profile on facebook got thorugh facebook sdk login through android app , How we will get the School Name fron the education Field in th json data in android . Please Help
Data :
{
"id": "1464730016",
"name": "Ravi Tamada",
"first_name": "Ravi",
"last_name": "Tamada",
"link": "https://www.facebook.com/ravi8x",
"username": "ravi8x",
"birthday": "12/22/1988",
"hometown": {
"id": "112158005464147",
"name": "Baruva"
},
"location": {
"id": "102186159822587",
"name": "Chennai, Tamil Nadu"
},
"bio": "Author: www.androidhive.info\r\nCo-author: www.9lessons.info",
"work": [
{
"employer": {
"id": "179366562092719",
"name": "ByteAlly"
},
"location": {
"id": "102186159822587",
"name": "Chennai, Tamil Nadu"
},
"position": {
"id": "124917314217511",
"name": "Product Head"
}
]
}
],
"favorite_athletes": [
{
"id": "18620649907",
"name": "Virat Kohli"
}
],
"education": [
{
"school": {
"id": "131587206873093",
"name": "Raghu Engineering College (REC)"
},
"degree": {
"id": "140065339390579",
"name": "B.Tech"
},
"year": {
"id": "142963519060927",
"name": "2010"
},
"type": "Graduate School",
"classes": [
{
"id": "192259410803415",
"name": "2010",
"with": [
{
"id": "584960408",
"name": "Santosh Patnaik"
}
],
"from": {
"id": "584960408",
"name": "Santosh Patnaik"
}
}
]
}
],
"gender": "male",
"relationship_status": "Single",
"website": "www.androidhive.info\nwww.9lessons.info\nwww.twitter.com/ravitamada\nwww.about.me/rv",
"timezone": 5.5,
"locale": "en_US",
"languages": [
{
"id": "106059522759137",
"name": "English"
},
{
"id": "107617475934611",
"name": "Telugu"
},
{
"id": "112969428713061",
"name": "Hindi"
},
{
"id": "343306413260",
"name": "Tamil"
}
],
"verified": true,
"updated_time": "2012-03-02T17:04:18+0000"
}
JSONObject jsonResult = new JSONObject(jsonUser);
JSONArray data = jsonResult.getJSONArray("education");
if(data != null)
{
for(int i = 0 ; i < data.length() ; i++)
{
JSONObject c = data.getJSONObject(i);
String type = c.getString("type");
if(type.equalsIgnoreCase("college"))
{
JSONObject school = c.getJSONObject("school");
String id2 = school.getString("id");
String name2 = school.getString("name");
JSONObject year = c.getJSONObject("year");
String id_y = school.getString("id");
String name_y = school.getString("name");
}
}
}
Supposing that you've this json into a jsonObject that you retrieve as response, this is the way:
// Get jsonArray 'education' from main jsonObject
JSONArray jsonArrayEducation = jsonObject.getJSONArray("education");
JSONObject jsonSchool = jsonArrayEducation.getJSONObject("school");
Note that if you are interested only at the name, you can group the two lines above into
JSONObject jsonSchool = jsonObject.getJSONArray("education").getJSONObject("school");
// get school name
String schoolName = jsonSchool.getString("name");