Android JSON Nested Arrays - android

I've tried to imitate the chosen answers in this sort of problem but I'm unsure why I'm failing to retrieving the URLs of the "attachments" in this.
What I'm after is a way to get every "post" and then grab every "attachment" image URL to save as a string. I've tried doing this on my emulator but it just stalls and runs forever. For certain reasons I am unable to use my real phone as a debugger too or else I would post a logcat.
One thing I am certain is that everything, minus the attachments, is coming in correctly. I've managed to get the posts downloading but cannot get anything thats nested. I'm newer to JSON so any help is very appreciated.
My Async:
// you can make this class as another java file so it will be separated from your main activity.
// https://www.codeofaninja.com/2013/11/android-json-parsing-tutorial.html
public class AsyncTaskParseJson extends AsyncTask<String, String, String> {
private ArrayList<RssFeedItem> tempArray = new ArrayList<RssFeedItem>();
final String TAG = "AsyncTaskParseJson";
private ProgressDialog progress;
// set your json string url here
String yourJsonStringUrl = "http://www.prindlepost.org/?json=tag_slug=java";
// contacts JSONArray
JSONArray dataJsonArr = null;
JSONArray imageURLArr = null;
#Override
protected void onPreExecute() {
progress = new ProgressDialog(getActivity());
progress.setTitle("Downloading Prindle's Posts");
progress.setMessage("This should just take a moment.");
progress.show();
}
#Override
protected String doInBackground(String... arg0)
{
try
{
// instantiate our json parser
JsonParser jParser = new JsonParser();
// get json string from url
JSONObject json = jParser.getJSONFromUrl(yourJsonStringUrl);
// get the array of users
dataJsonArr = json.getJSONArray("posts");
// loop through all users
for (int i = 0; i < dataJsonArr.length(); i++)
{
JSONObject c = dataJsonArr.getJSONObject(i);
// Storing each json item in variable
String id = c.getString("id");
String type = c.getString("type");
String slug = c.getString("slug");
String title = c.getString("title");
String content = c.getString("content");
String author = c.getString("author");
//http://stackoverflow.com/questions/19748829/android-get-json-array-nested-in-array
JSONObject attachments = c.getJSONObject("attachments");
Log.d("attachment",""+attachments.getString("url"));
// show the values in our logcat
Log.e(TAG, "id: " + id
+ ", type: " + type
+ ", slug: " + slug
+ ", title: " + title
+ ", author: " + author
+ ", content: " + content + "\n\n");
tempArray.add(new RssFeedItem(title, content, "", 0, new Date(), author));
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
The JSON: http://www.prindlepost.org/?json=tag_slug=java
{
status: "ok",
count: 10,
count_total: 334,
pages: 34,
posts: [
{
id: 4230,
type: "post",
slug: "crowdsourcing-justice",
url: "http://www.prindlepost.org/2015/06/crowdsourcing-justice/",
status: "publish",
title: "Crowdsourcing Justice",
title_plain: "Crowdsourcing Justice",
content: "<p>The video begins abruptly. Likely recorded on a phone, the footage is shaky and blurry, yet the subject is sickeningly unmistakeable: a crying infant being repeatedly and violently dunked into a bucket of water. First it is held by the arms, then upside down by one leg, then grasped by the face as an unidentified woman pulls it through the water. Near the end of the video, the infant falls silent, the only remaining audio the splashing of water and murmured conversation as the child is dunked again and again.</p> <div class="more-link-wrap wpb_button"> Read more</div> ",
excerpt: "<p>Facebook’s decision not to censor a video of child abuse poses questions of censorship, activism and online justice. </p> ",
date: "2015-06-09 14:00:19",
modified: "2015-06-10 09:53:36",
categories: [
{
id: 433,
slug: "crime-and-law",
title: "Crime and Law",
description: "",
parent: 63,
post_count: 14
},
{
id: 38,
slug: "ethics-news",
title: "Ethics News",
description: "",
parent: 0,
post_count: 153
},
{
id: 63,
slug: "society-ethics-news",
title: "Society",
description: "",
parent: 38,
post_count: 187
}
],
tags: [
{
id: 180,
slug: "abuse",
title: "abuse",
description: "",
post_count: 2
},
{
id: 481,
slug: "child-abuse",
title: "child abuse",
description: "",
post_count: 1
},
{
id: 482,
slug: "doxxing",
title: "doxxing",
description: "",
post_count: 1
},
{
id: 57,
slug: "facebook",
title: "Facebook",
description: "",
post_count: 4
},
{
id: 470,
slug: "internet",
title: "internet",
description: "",
post_count: 2
},
{
id: 130,
slug: "justice",
title: "justice",
description: "",
post_count: 2
},
{
id: 59,
slug: "social-media",
title: "social media",
description: "",
post_count: 4
}
],
author: {
id: 43,
slug: "connergordon_2016",
name: "Conner Gordon",
first_name: "Conner",
last_name: "Gordon",
nickname: "connergordon_2016",
url: "http://connergordon.tumblr.com",
description: "Conner is a web and social media intern at the Prindle Institute. A Political Science and English double major from Carmel, Indiana, Conner's ethical interests lie in memory studies, conflict analysis and the ethics of representation. He also has interests in literature, art and photography."
},
comments: [ ],
attachments: [
{
id: 4233,
url: "http://www.prindlepost.org/wp-content/uploads/2015/06/Screen-Shot-2015-06-09-at-11.48.59-AM.png",
slug: "screen-shot-2015-06-09-at-11-48-59-am",
title: "",
description: "",
caption: "Image credit: Screenshot from Youtube",
parent: 4230,
mime_type: "image/png",
images: [ ]
},
{
id: 4235,
url: "http://www.prindlepost.org/wp-content/uploads/2015/06/Screen-Shot-2015-06-09-at-11.48.59-AM1.png",
slug: "screen-shot-2015-06-09-at-11-48-59-am-2",
title: "",
description: "",
caption: "Image/Youtube",
parent: 4230,
mime_type: "image/png",
images: [ ]
}
],

I had the same problem. After a few days melting my brain, I tried using Google's GSON. It does all the parsing and thinking for you, and returns a nice little object with all the information from the JSON.
Here's the project link: https://github.com/google/gson
To use it, you have to instantiate a new Gson parser, like so
Gson gson = new Gson();
YourObject object = gson.fromJson(jsonString, YourObject.class);
And the YourObject class should look something like this:
public class YourObject{
int status;
int count;
String count_total;
...
Post[] posts;
}
Now you create a Post class with the fields predicted in your JSON:
public class Post{
int id;
String type;
String slug;
...
Category[] categories;
}
I think you can get an idea on how to set up your POJO's. Keep in mind that, if you are getting an array of objects as your base object in JSON, be sure to use YourObject[] instead of YourObject when calling gson.fromJson
Just a heads-up: If any of the Json elements have a null or an empty value, even though they are primarily an int in your YourObject class, it is best to declare them as String to avoid java.lang.NumberFormatException.

You can use the method getJSONArray()

Related

Parsing API data which contain object (Klaxon) (Kotlin)

I have API response which contain object (graphic)
[
{
"code": 200,
"status": "OK",
"FirstDay": "2019-11-18",
"LastDay": "2019-11-24",
"graphic": {
"2019-11-23": [
{
"godzinaStart": "08:30",
"godzinaStop": "10:00",
"przedmiot": "Matematyka dyskretna",
"sala": "32AK8",
"nauczyciel": "xxx",
"grupy": "1K131; 1K132; 1K133; 1K134; 1K135; 2K131",
"typ": "wykład"
},
],
"2019-11-24": [
{
"godzinaStart": "08:30",
"godzinaStop": "10:00",
"przedmiot": "Podstawy informatyki",
"sala": "308K",
"nauczyciel": "xxx",
"grupy": "1K131",
"typ": "laboratorium"
},
]
}
}
]
I have to parse this JSON to object in Kotlin. So i made class with parameters
class GraphicAPIResponse(
var code: Int,
var status: String,
var errorMessage: String = "",
var FirstDay: String = "",
var LastDay: String = "",
var graphic: JsonObject? = null OR var graphic: JsonArray<Any>? = null (I tried both)
)
I'm parsing data by this function
val responeAPI = Klaxon().parseArray<GraphicAPIResponse>(response)
When graphic is JsonObiect type appliaction throw error
I/System.out: ERROR -> Unable to instantiate JsonObject with parameters []
When graphic is JsonArray<Any> type, here's error
I/System.out: ERROR -> Unable to instantiate GraphicAPIResponse with parameters [LastDay: 2019-11-24, code: 200, status: OK, graphic: java.lang.Object#aef265a, FirstDay: 2019-11-18]
I'm trying to resolve the problem from 2 hours. Can someone help me please? :(
#EDIT
Thank You #Alexey Romanov
That help
Define a type for the nested object:
class Lesson(val godzinaStart: String, val godzinaStop: String, ...)
and use it in GraphicAPIResponse:
class GraphicAPIResponse(
var code: Int,
var status: String,
var errorMessage: String = "",
var FirstDay: String = "",
var LastDay: String = "",
var graphic: Map<String, Lesson> = mapOf()
)
(though honestly, I'd expect JsonObject to work as well)

Expected BEGIN_ARRAY but was STRING but JSON is correct

I have searched the other related questions but am not able to find my answers.
This is my JSON: named appointments.json
[
{
"title": "Primary Care",
"text": "Schedule a Primary Care appointment online.",
"image": "http://i.imgur.com/DvpvklR.png"
},
{
"title": "Primary Care",
"text": "Schedule a Primary Care appointment online.",
"image": "http://i.imgur.com/DvpvklR.png"
},
{
"title": "Primary Care",
"text": "Schedule a Primary Care appointment online.",
"image": "http://i.imgur.com/DvpvklR.png"
},
{
"title": "Primary Care",
"text": "Schedule a Primary Care appointment online.",
"image": "http://i.imgur.com/DvpvklR.png"
}
]
Here is the list object class:
#Parcelize
data class AppointmentsListItem(
#Expose
#SerializedName("title")
val title: String = "",
#Expose
#SerializedName("text")
val text: String = "",
#Expose
#SerializedName("image")
val image: String = "") : IAppointmentsListItem
Here is where my error occurs:
val gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation()
.create()
private val listType = object : TypeToken<List<AppointmentsListItem>>() {}.type
val apiList: List<AppointmentsListItem> = gson.fromJson("appointments.json", listType)
Where the heck is the STRING coming from?? My Json response is an array of these ListItems, I'm starting the response with a [] so why is it reading a string?
Where the heck is the STRING coming from?
"appointments.json" is a string. Moreover, "appointments.json" is not a valid JSON string, as it starts with a, not [ or {.
My guess is that appointments.json is supposed to be a filename. However, Gson does not know that, and a bare filename is useless regardless. You need to provide Gson with an InputStream or Reader on the JSON itself, whether that comes from, such as:
FileReader (where you provide a File that points to wherever appointments.json resides)
InputStream from ContentResolver and openInputStream()
InputStream from AssetManager and open()

Android - YouTube API get videoId from video list

I want to get videoId in (items:[ id:{ ) but it shows org.json.JSONException: No value for videoId.
Is there any wrong code here?
items: [
{
kind: "youtube#searchResult",
etag: ""etag"",
id: {
kind: "youtube#video",
videoId: "nsVttBhYM2E"
},
snippet: {
publishedAt: "publishedAt",
channelId: "channelId",
title: "title",
description: description",
thumbnails: {
default: {
url: "thumbnail url",
width: 120,
height: 90
},
medium: {
url: "thumbnail url",
width: 320,
height: 180
},
high: {
url: "thumbnail url",
width: 480,
height: 360
}
},
channelTitle: "channelTitle",
liveBroadcastContent: "none"
}
},
This is part of source code get video id from video list
JSONArray items = jsonObject.getJSONArray("items");
for (int i = 0; i < items.length(); i++)
{
JSONObject json_data = items.getJSONObject(i);
strVideoID = json_data.getJSONObject("id").getString("videoId");
}
It's too late to answer, but it may help someone in future.
First check if "kind" equals to "youtube#video", then try to get the "id" string. Both the key are in the "id" JSONObject.
As the response may also contain some playlists, instead of "videoId" there may be "playlistId".

How to parse JsonObject to List<MyClass> using gson

I need a list of objects and I'm having problems to get it. I'm pretty new using this so someone who can help me?
I'm using volley to get a jsonObject and then I need convert it(I saw the best wa to do this is with gson). Below you can see how looks an example of my json.
{
network: {
company: "JCDecaux",
href: "/v2/networks/dublinbikes",
id: "dublinbikes",
location: {
city: "Dublin",
country: "IE",
latitude: 53.3498053,
longitude: -6.2603097
},
name: "dublinbikes",
stations: [
{
empty_slots: 37,
extra: {
address: "Fitzwilliam Square East",
bonus: false,
connected: "1",
last_update: "1434047944",
open: true,
slots: 40,
ticket: true,
uid: 89
},
free_bikes: 3,
id: "153ff4dfb7bd8912ef91c10849129c2e",
latitude: 53.335211,
longitude: -6.2509,
name: "Fitzwilliam Square East",
timestamp: "2015-06-11T18:41:31.11Z"
},
{
empty_slots: 0,
extra: {
address: "Portobello Harbour",
bonus: false,
connected: "1",
last_update: "1434047764",
open: true,
slots: 30,
ticket: false,
uid: 34
},
free_bikes: 30,
id: "3c0cfd547a142bb651280991a412bcbe",
latitude: 53.330362,
longitude: -6.265163,
name: "Portobello Harbour",
timestamp: "2015-06-11T18:41:31.15Z"
},
... ect
Station class
public class Station {
public Station(){}
public String StationName;
public String Distance;
public String Slots;
public String Bikes;
public String LastUpdate;
//Getters and Setters ...
}
Below you can see what I have done so far..
//stations
JSONObject jsonNetwork = new JSONObject(response.getString("network"));
Type listType = new TypeToken<ArrayList<Station>>() {
}.getType();
List<Station> yourClassList = new Gson().fromJson(jsonNetwork, listType);
But I don't know how to parse all this and avoid the data I dont need and also the function Gson().fromJson needs and JsonArray and what I have is a JsonObject
Thanks for your time!
If all that you are looking for are the stations then I think you should do the following:
//stations
JSONObject jsonNetwork = new JSONObject(response.getString("network"));
JSONArray stationsArray = jsonNetwork.getJSONArray("stations");
Now, you should pass this stationsArray variable to the fromJson method. Also, the variable names of your Station class should be equal to the key names that you want to extract from your json. There is a good example in the following link:
http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/
Use below code
Gson gson = new Gson();
YourClass obj = gson.fromJson(jsonObject.toString(), YourClass.class);

parse/serialize complex json object with GSON

This json object can be very very large sometimes, I would like to parse it with GSON but I do not quite get how the format of my java objects should be to parse them.
What would really help me are some very contextual examples, given this object, how would I form my java model objects to hold the data in a gson.fromJSON method? My current objects get filled with "null"
I explain the simplicity of the object at the bottom
{
response: {
user_is_following: 0,
name: "Tennesee",
submitted_requests: 429,
completed_requests: 34,
request_types: {
c_id: 1064,
request_types: [
{
objectKey: {
id: 15699,
name: "Complaint",
has_custom_fields: 0,
disable_title: 0,
disable_description: 0,
force_private: 0,
image: null
}
},
{
objectKey: {
id: 15700,
name: "Compliment",
has_custom_fields: 0,
category_id: 605,
disable_title: 0,
disable_description: 0,
force_private: 0,
image: null
}
},
{
objectKey: {
id: 17574,
name: "Custom Fields, all of them",
has_custom_fields: 1,
disable_title: 0,
disable_description: 0,
force_private: 0,
image: null,
custom_fields: [
{
custom_field: {
id: "1663",
name: "I'm a text input",
description: "I'm a text input description",
type: "text",
required: 1,
is_public: 1,
options: [
]
}
},
{
custom_field: {
id: "1664",
name: "I'm a text input display only",
description: "I'm a text input display only description",
type: "display",
required: 0,
is_public: 0,
options: [
]
}
},
{
custom_field: {
id: "1665",
name: "I'm a checkbox",
description: "I'm a checkbox description",
type: "checkbox",
required: 0,
is_public: 1,
options: [
]
}
},
{
custom_field: {
id: "1666",
name: "I'm a single select",
description: "I'm a single select description",
type: "singleselect",
required: 1,
is_public: 0,
options: [
{
option: {
id: "3751",
name: "A 123 !###",
description: "A 123 !### description"
}
},
{
option: {
id: "3752",
name: "B ",
description: "B description"
}
},
{
option: {
id: "3753",
name: "C",
description: "C description"
}
},
{
option: {
id: "3754",
name: " D",
description: "D description"
}
}
]
}
},
}
],
s_types: [
],
categories: [
{
category: {
id: 618,
client: 1064,
name: "Abc",
gov_creator: 1841,
description: "",
parent: 607,
date_created: 1368137256,
image: null
}
},
{
category: {
id: 602,
client: 1064,
name: "Animal Control",
gov_creator: 2275,
description: "",
parent: null,
date_created: 1367878768,
image: null
}
},
}
],
assets: [
],
benchmark: 0.36078095436096
},
status: {
type: "success",
message: "Success",
code: 200,
code_message: "Ok"
}
}
}
The real meat is in the request_types key, the second one, which is a JSONArray. Each index contains an object, each object can contain a Custom Fields key which is a json array as well, which in some cases can contain an options json array.
I have models for all of these, for a different parsing paradigm, but not for GSON. I will need to use GSON now because of memory limitations
You will need lets say class A with one instance of class B in it.
public class A {
private B response;
}
then you will need class B to have 1 instance of class C
public class B {
private C request_types;
}
Then C would contains int c_id and array of a class D and a class for each of the other arrays as well. Then class D would contain a single object for class E called objectKey. Class E would contains all the fields under objectKey...
So on and so forth... you're right the JSON is crazy convoluted.

Categories

Resources