I am retrieving JSON from my website and trying to parse it in my android app.
This is an automatic JSON generated by the back-end.
Whenever there is only single image uploaded, I am getting the link of the image without an array. That is as a single string.
However, in case there were images more than one uploaded I am getting them inside an array.(see JSON below) (JSON is invalid, as I removed some stuff that I do not use)
{
"Reports": [
{
"News": {
"Title": "Big Explosion",
"Info": "Lorem ipsum news etc here get here etc",
"field_image": "http://mysite.com/1.jpg"
}
},
{
"News": {
"Title": "2nd explosion",
"Info": "<p>Us a delimited list ws etc here get her</p>\n",
"field_image": [
"http://mysite.com/2.jpg",
"http://mysite.com/3.jpg",
"http://mysite.com/4.jpg"
]
}
]
}
I am using the below code in order to retrieve the JSON.
However, I am not able to get each String alone when there is more than a single image.
JSONObject json = jParser.getJSONFromUrl(url);
if (json != null)
{
JSONArray ReportsJsonArray = json.getJSONArray("Reports");
for (int i = 0; i < ReportsJsonArray.length(); i++)
{
JSONObject c = ReportsJsonArray .getJSONObject(i);
JSONObject news= node.getJSONObject("News");
String title = node.getString("Title");
String info = node.getString("Info");
String fieldImage = node.getString("fieldimage");
if (fieldImage.charAt(0) == '[')
{
Log.i("tag", "more than 1 image");
// HOW TO GET THEM
} else
{
Log.i("tag", "single image");
//already have them
}
}
My code works but gets the whole array as a single string.
(I have omitted the try-catch blocks to make the code simpler).
I think you should use google gson jsonreader or android jsonreader that avaible from android API-11 the JSONreader read per token and you can use the function peek() to see the JSONToken type without consuming it in your case it'll be like this
main function
//response from the server
response = myClient.execute(myConnection);
Reader streamReader = new InputStreamReader(response
.getEntity().getContent());
JsonReader reader = new JsonReader(streamReader);
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("reports")) {
readReports(reader);
} else {
reader.skipValue(); // avoid some unhandle events
}
}
reader.endObject();
reader.close();
readReports function
private void readReports(JsonReader reader) throws IOException {
reader.beginArray();
while(reader.hasNext()) {
reader.beginObject();
while (reader.hasNext()) {
String objectNewsName = reader.nextName();
if (objectNewsName .equals("News")) {
readNews(reader);
} else {
reader.skipValue();
}
reader.endObject();
}
reader.endObject();
}
readNews function
private void readNews(JsonReader reader) throws IOException {
reader.beginObject();
while(reader.hasNext()) {
String objectNewsDataName = reader.nextName();
if (objectNewsDataName .equals("Title")) {
Log.d("NEWS",reader.nextString());
} else if (objectNewsDataName .equals("Info")) {
Log.d("NEWS",reader.nextString());
} else if (objectNewsDataName .equals("field_image")) {
if(reader.peek() == JsonToken.BEGIN_ARRAY) {
readFieldImage(reader);
} else {
Log.d("NEWS",reader.nextString());
}
}else {
reader.skipValue();
}
}
reader.endObject();
}
readFieldImage function
private void readFieldImage (JsonReader reader) throws IOException {
reader.beginArray();
while(reader.hasNext()) {
Log.d("NEWS",reader.nextString()); //you will get the field image array content here
}
}
I hope my answer is clear enough but if you have some question about my answer feel free to ask in the comment :)
have you tried this:
....
String title = node.getString("Title");
String info = node.getString("Info");
JSONArray fieldImageArray = node.getJSONArray("fieldimage");
//iterate fieldImageArray here
....
try like this
List<String> url= new ArrayList<String>();
JSONArray field_image= news.getJSONArray("field_image");
for (int i = 0; i < field_image.length(); i++) {
url.add(field_image.get(i).toString());//adding to List
}
Related
My current response is
{"response":"validation error","status":"failure","code":400,"errors":["You can not add multiple items with different categories"]}
My current code is :
String errorBody = response.errorBody().string();
JSONObject jsonObject = new JSONObject(errorBody.trim());
jsonObject = jsonObject.getJSONObject("errors");
Iterator<String> keys = jsonObject.keys();
String errors = "";
while (keys.hasNext()) {
String key = keys.next();
JSONArray arr = jsonObject.getJSONArray(key);
for (int i = 0; i < arr.length(); i++) {
errors += key + " : " + arr.getString(i) + "\n";
}
}
I am trying to get the error code to see if it matches specific keywords to handle the response
i think your current code its not to good,better way for u is:
create modelClass for your json output and in retrofit calls write:
if (model.status=='failure' || model.code==400){
print(response.message) // or something like this
}
You can look through the following code snippet
call.enqueue(new Callback<PagedResponse<NotificationModel>>() {
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onResponse(Call<PagedResponse<NotificationModel>> call, Response<PagedResponse<NotificationModel>> response) {
if (response.isSuccessful()) {
if (response.code() == 200) {
try {
PagedResponse<NotificationModel> notifications = (PagedResponse<NotificationModel>) response.body();
tvRecordsCount.setText("Total "+response.body().getTotal()+" Notifications ");
showNotification(notifications);
} catch (Exception e){
e.printStackTrace();
}
} else {
showToast(getApplicationContext(), "Server Error");
}
}
}
#Override
public void onFailure(Call<PagedResponse<NotificationModel>> call, Throwable t) {
showToast(getApplicationContext(), t.getMessage());
}
});
I managed to get it working with this code:
String errors = "";
String errorBody = response.errorBody().string();
JsonParser parser = new JsonParser();
JsonObject rootObj = parser.parse(errorBody.trim()).getAsJsonObject();
JsonArray errorArray = rootObj.getAsJsonArray("errors");
for (JsonElement pa : errorArray) {
errors = pa.getAsString();
}
I want to assign the JSONfile inside the Resources to a instance from JsonObject and parse it.
Please guide how?
MainActivicy:
boolean bool = true;
boolean bool2=true;
String s = "";
input = getResources().openRawResource(R.raw.infojson);
JsonReader reader = new JsonReader(new InputStreamReader(input));
reader.beginObject();
while (bool==true){
String sv ="";
sv=reader.nextName();
s +=sv;
if(sv.equals("id")| sv.equals("num")){
s +=" : " ;
s+=(String.valueOf(reader.nextInt()));
}
if (sv.equals("name")){
s +=" : " ;
s+=reader.nextString();
}
s+="\t";
bool = reader.hasNext();
}
JSON Content:
{
"id":"1","name":"E1","num":1111,
"My":{"id":"2","name":"E2","num":2222}
}
Create a model to parse your json like below:
class ResourseResponse {
private String id;
private String name;
private String num;
//getter-setter
}
Then parse your json from JsonReader and create your model.
JsonReader reader = new JsonReader(new InputStreamReader(input));
Gson gson = new Gson();
if (reader.peek() != JsonToken.BEGIN_OBJECT) {
reader.beginArray();
while (reader.hasNext()) {
ResourseResponse response = gson.fromJson(reader, ResourseResponse.class);
//Add to list
}
reader.endArray();
} else {
ResourseResponse message = gson.fromJson(reader, ResourseResponse.class);
}
If the JSON content is not too big, you can easily create org.json.JSONObject and iterate its keys.
String jsonStr = "{\"id\":\"1\",\"name\":\"E1\",\"num\":1111, \"My\":{\"id\":\"2\",\"name\":\"E2\",\"num\":2222} }"
JSONObject json = new JSONObject(jsonStr);
json.keys().forEachRemaining(x -> {
System.out.println(x.toString());
try {
if (json.get(x.toString()) instanceof JSONObject) {
System.out.println(json.get(x.toString())); / here you can iterate the internal json object
}
} catch (JSONException e) {
e.printStackTrace();
}
});
Output is:
num
name
id
My
{"num":2222,"name":"E2","id":"2"}
I am trying to fetch videos from a channel's playlist. There are 132 videos but I cant fetch more than 50 videos.
I know that nextPageToken has to be fetched and passed along with url?
This is my first time working with api.
This is how I am able to fetch 50 videos.
Edit
private static String GOOGLE_YOUTUBE_API_KEY = "<API Key>";
private static String CHANNLE_GET_URL="https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=PL-nbe4FPvDBElyW0Iww5suxJqqmuGBgIH&key="+GOOGLE_YOUTUBE_API_KEY;
public ArrayList<YoutubeDataModel> parseVideoListFromResponse(JSONObject jsonObject) {
ArrayList<YoutubeDataModel> mList = new ArrayList<>();
if (jsonObject.has("items")) {
try {
JSONArray jsonArray = jsonObject.getJSONArray("items");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.getJSONObject(i);
if (json.has("id")) {
JSONObject jsonID = json.getJSONObject("id");
String video_id = "";
if (jsonID.has("videoId")) {
video_id = jsonID.getString("videoId");
}
if (jsonID.has("kind")) {
if (jsonID.getString("kind").equals("youtube#video")) {
YoutubeDataModel youtubeObject = new YoutubeDataModel();
JSONObject jsonSnippet = json.getJSONObject("snippet");
String title = jsonSnippet.getString("title");
String description = jsonSnippet.getString("description");
String publishedAt = jsonSnippet.getString("publishedAt");
String thumbnail = jsonSnippet.getJSONObject("thumbnails").getJSONObject("high").getString("url");
youtubeObject.setTitle(title);
youtubeObject.setDescription(description);
youtubeObject.setPublishedAt(publishedAt);
youtubeObject.setThumbnail(thumbnail);
youtubeObject.setVideo_id(video_id);
mList.add(youtubeObject);
}
}
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return mList;
}
Edit 2:
Added the following but it is not fetching any value.
try {
// String data=null;
JSONObject reader = new JSONObject();
String next_Page_Token = reader.getString("nextPageToken");
Log.d("NextPAgeToken", "NpT"+next_Page_Token);
}
catch (JSONException e)
{
Log.e("Error", "Error is "+e.getMessage());
Toast.makeText(getApplicationContext(),"No next page found", Toast.LENGTH_LONG).show();
}
You need to add one extra query parameter pageToken like below
private static String CHANNLE_GET_URL =
"https://www.googleapis.com/youtube/v3/playlistItems" +
"?part=snippet" +
"&maxResults=50" +
"&playlistId=PL-nbe4FPvDBElyW0Iww5suxJqqmuGBgIH" +
"&key="+GOOGLE_YOUTUBE_API_KEY +
"pageToken=" + NEXT_PAGE_TOKEN;
//Pass like this one
"https://www.googleapis.com/youtube/v3/search?part=snippet&order=date&channelId=UC2LrGJYe_uzI3FBj05BuvLA&key=AIzaSyBlj1dJ9txGcXOOblCJuQ0iwIkhUCgVt1Y&maxResults=50&pageToken=CJYBEAA"
and when you get data, you need to update NEXT_PAGE_TOKEN by fetching value from nextPageToken.
You will get data as
{
"kind": "youtube#searchListResponse",
"etag": "\"RmznBCICv9YtgWaaa_nWDIH1_GM/MgcKz6rwie5hyKKWdwMChcXzNzU\"",
"nextPageToken": "CJYBEAA",
"prevPageToken": "CGQQAQ",
"regionCode": "IN",
"pageInfo": {
"totalResults": 184,
"resultsPerPage": 50
},
"items": [...]
}
So, convert this data into JSONObject as
JSONObject mainObject = new JSONObject(data);
NEXT_PAGE_TOKEN = mainObject.getString("nextPageToken");
...//Rest your task here
This works fine.
I'm trying to get the value for the key 'GBP' in the following link: https://api.fixer.io/latest
I've managed to connect to the API successfully and I'm able to cycle through the keys until I get "rates". Inside rates though, I don't know how I cycle through all the currencies until I find 'GBP'.
Note: I'm paring the Json - I'm struggling to parse a Json object that has a Json within it. It's different to the duplicates you've referenced.
My code so far looks like this:
String urlStr = "https://api.fixer.io/latest";
AsyncTask.execute(new Runnable() {
#Override
public void run() {
// Create URL
URL url = null;
try {
url = new URL(urlStr);
} catch (MalformedURLException e) {
e.printStackTrace();
}
// Create connection
try {
HttpURLConnection myConnection =
(HttpURLConnection) url.openConnection();
if (myConnection.getResponseCode() == 200) {
InputStream responseBody = myConnection.getInputStream();
InputStreamReader responseBodyReader =
new InputStreamReader(responseBody, "UTF-8");
JsonReader jsonReader = new JsonReader(responseBodyReader);
jsonReader.beginObject(); // Start processing the JSON object
while (jsonReader.hasNext()) { // Loop through all keys
String key = jsonReader.nextName(); // Fetch the next key
if (key.equals("rates")) { // Check if desired key
// Fetch the value as a String
String value = jsonReader.nextString();
//currentCurrency = value;
break; // Break out of the loop
} else {
jsonReader.skipValue(); // Skip values of other keys
}
}
} else {
// Error handling code goes here
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
Try this
JSONObject jsonObject = new JSONObject(" your json response ");
Iterator iteratorObj = jsonObject.keys();
while (iteratorObj.hasNext())
{
String JsonObjRates = (String)iteratorObj.next();
if (JsonObjRates.equals("rates")) {
JSONObject jo_rates = jsonObject.getJSONObject(JsonObjRates);
Iterator<String> keys = jo_rates.keys();
while (keys.hasNext())
{
String key = keys.next();
String value = jo_rates.getString(key);
Log.i("RATES key", key);
Log.i("RATES value", value);
if(key.equals("GBP"))
{
Log.i("GBP RATES key", key);
Log.i("GBP RATES value", value);
}
}
}
}
Output
Instead of Using manual parsing used below things.
Please Use RoboPojo Generator into Android Studio it will helps you to create model class for you and directly setData to your model class.
if you are using Gson to setData.
Below ilink is helping to you :
https://github.com/robohorse/RoboPOJOGenerator
hope this helps you.
You can use Volleylibrary to make request that url and you will take response.
after take response via related url, you can parse it on Android Studio.
dependencies {
...
compile 'com.android.volley:volley:1.1.0'
}
above will be added in dependencies.
below will be added in your Activity(like MainActivity).
String url ="https://api.fixer.io/latest";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject resultJSON=new JSONObject(response);
JSONObject rates=resultJSON.getJSONObject("rates");
string GPB=rates.getString("GPB");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mTextView.setText("That didn't work!");
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
I guess it will work. make feedback whether it works or not.
Try this.
You have to loop through jsonobject so first create class for rates.
public Rates readRates(JsonReader reader) throws IOException {
String country_rate = null;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("GBP")) {
country_rate = reader.nextString();
} else {
reader.skipValue();
}
}
reader.endObject();
return new Rates(country_rate);
}
Decalre your class at start of this http method
Rates rate = null;
Replace this Code
if (key.equals("rates")) { // Check if desired key
// Fetch the value as a String
String value = jsonReader.nextString();
//currentCurrency = value;
break; // Break out of the loop
} else {
jsonReader.skipValue(); // Skip values of other keys
}
With this
if (key.equals("rates"))
{
rate = readRates(jsonReader);
String rate_value = rate.country_rate;
}
else
{
jsonReader.skipValue(); // Skip values of other keys
}
For more details https://developer.android.com/reference/android/util/JsonReader.html
Hope it helps.!
The only thing that's guaranteed to always be there is the messagesByDate obj.
The array and objects named such as "15 MAY 2012" are generated by a server(no control) based on rather or not messages are present for that date.
If u notice the first date represented is an array while the other dates are objects containing other objects that have been numbered.
QUESTION 1: how do i parse this without knowing what dates will be present?
QUESTION 2: Some messages are in an array instead of an object. how do I put them all together in one ArrayList. Rather its in an array or not because the array will not always been there.
Please any help would be appreciated as I'm down to my last hair
Thanks.
{
"messagesByDate":{
"15 May 2012":[
{
"id":"1383483367",
"conversation_id":"274618561",
"user_id":"4318264",
"message":"ok will do",
"date_sent":"1337133515",
"date_sent_ago":"7 mins ago"
},
{
"id":"1380222533",
"conversation_id":"274618561",
"user_id":"5159567",
"message":"ok well hmu",
"date_sent":"1337085122",
"date_sent_ago":"13 hrs ago"
},
{
"id":"1380172978",
"conversation_id":"274618561",
"user_id":"5159567",
"message":"superhead",
"date_sent":"1337083910",
"date_sent_ago":"13 hrs ago"
},
{
"id":"1380130860",
"conversation_id":"274618561",
"user_id":"5159567",
"message":"you ready B",
"date_sent":"1337082797",
"date_sent_ago":"14 hrs ago"
},
{
"id":"1378841432",
"conversation_id":"274618561",
"user_id":"5159567",
"message":"hit my cell tho",
"date_sent":"1337054524",
"date_sent_ago":"22 hrs ago"
},
{
"id":"1378836763",
"conversation_id":"274618561",
"user_id":"5159567",
"message":"whats up baby",
"date_sent":"1337054475",
"date_sent_ago":"22 hrs ago"
}
],
"12 May 2012":{
"6":{
"id":"1362948558",
"conversation_id":"274618561",
"user_id":"4318264",
"message":"ok ima text u",
"date_sent":"1336819668",
"date_sent_ago":"3 days ago"
}
},
"11 May 2012":{
"7":{
"id":"1361356267",
"conversation_id":"274618561",
"user_id":"5159567",
"message":"yea thats cool",
"date_sent":"1336790738",
"date_sent_ago":"3 days ago"
},
"8":{
"id":"1357783913",
"conversation_id":"274618561",
"user_id":"5159567",
"message":"sorry im here. would u like to exchange numebers instead?",
"date_sent":"1336722533",
"date_sent_ago":"4 days ago"
},
"9":{
"id":"1357759262",
"conversation_id":"274618561",
"user_id":"5159567",
"message":"hello?",
"date_sent":"1336721851",
"date_sent_ago":"4 days ago"
}
}
}
}
THE ANSWER SORTA-KINDA
JSONObject dateHolder = r.getJSONObject("messagesByDate");
Iterator holderItr = dateHolder.keys();
while(holderItr.hasNext()){
String thisdate = holderItr.next().toString();
Object date = dateHolder.get(thisdate);
if (date instanceof JSONArray) {
System.out.println(thisdate+" is an ARRAY.");
JSONArray jarray = (JSONArray) date;
for(int x=0;x<jarray.length();x++){
String msgId = jarray.getJSONObject(x).getString("id");
String msgConvoId = jarray.getJSONObject(x).getString("conversation_id");
String msgUserId = jarray.getJSONObject(x).getString("user_id");
String msgBody = jarray.getJSONObject(x).getString("message");
String msgDateSent = jarray.getJSONObject(x).getString("date_sent");
String msgDateSentAgo = jarray.getJSONObject(x).getString("date_sent_ago");
HashMap<String,String> temp = new HashMap<String,String>();
temp.put("msgId",msgId);
temp.put("msgUserId", msgUserId);
temp.put("msgBody", msgBody);
temp.put("msgDateSent", msgDateSent);
temp.put("msgDateSentAgo", msgDateSentAgo);
messages.add(temp);
}
} else {
System.out.println(thisdate+" is an OBJECT.");
JSONObject jobj = (JSONObject) date;
Iterator insideDate = jobj.keys();
while(insideDate.hasNext()){
String number = insideDate.next().toString();
System.out.println(number);
String msgId = jobj.getJSONObject(number).getString("id");
String msgConvoId = jobj.getJSONObject(number).getString("conversation_id");
String msgUserId =jobj.getJSONObject(number).getString("user_id");
String msgBody = jobj.getJSONObject(number).getString("message");
String msgDateSent = jobj.getJSONObject(number).getString("date_sent");
String msgDateSentAgo = jobj.getJSONObject(number).getString("date_sent_ago");
HashMap<String,String> temp = new HashMap<String,String>();
temp.put("msgId",msgId);
temp.put("msgUserId", msgUserId);
temp.put("msgBody", msgBody);
temp.put("msgDateSent", msgDateSent);
temp.put("msgDateSentAgo", msgDateSentAgo);
messages.add(temp);
}
}
}
This gives me all the messages in a HashMap and adds it to an ArrayList called messages like I want but its out of order by date. the json is listed by date...anyone know if there is a way to direct json reading? OR are my WHILE and FOR loops out of order? can i sort hashmaps by a key? I'll google that...
First create a class like this:
import java.util.LinkedList;
import android.util.Log;
public class Message{
private LinkedList<String> id = new LinkedList<String>();
private LinkedList<String> conversation_id = new LinkedList<String>();
private LinkedList<String> user_id = new LinkedList<String>();
private LinkedList<String> message = new LinkedList<String>();
private LinkedList<String> date_sent = new LinkedList<String>();
private LinkedList<String> date_sent_ago = new LinkedList<String>();
public LinkedList<String> getId() {
return id;
}
public void setId(String id) {
this.id.add(id);
}
.
.
.
// For checking response after you get info from server
public void printContent() {
for(String str : id)
Log.i("Id>>>", str);
.
.
.
}
}
Then you need to call server in onCreate() add this code:
if(Manager.isOnline(this)) // Check Internet connection and if you find it then
new MyAsyncTask().execute();
Now, you should add this class:
public class MyAsyncTask extends AsyncTask<Void, Void, Boolean> {
#Override
protected void onPreExecute() {
Log.i(TAG, "MyAsyncTask is about to start...");
showProgressBar();
}
#Override
protected Boolean doInBackground(Void... params) {
boolean status = false;
// Get News items in json format
msg = getMessageItems(); // msg is an instance of Message class define it as global variable.
msg.printContent(); // Check result in logcat
if(msg != null)
status = true;
return status;
}
#Override
protected void onPostExecute(Boolean result) {
Log.i(TAG, "MyAsyncTask finished its task. Data returned to caller.");
if(result)
displayData();
hideProgressBar();
}
}
Here we will connect to server, get Json data and parse it.
private Menu getMenuItems() {
Message mMessage = new Message ();
String response = null;
String connection = **YOUR_URL**;
try {
URL url = new URL(connection);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
int responseCode = conn.getResponseCode();
Log.i(TAG, "Try to open: " + connection);
Log.i(TAG, "Response code is: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_OK) {
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
if (in != null) {
StringBuilder strBuilder = new StringBuilder();
// Read character by character
int ch = 0;
while ((ch = in.read()) != -1)
strBuilder.append((char) ch);
// get returned message and show it
response = strBuilder.toString();
Log.i("JSON returned by server:", response);
JSONObject jObject = new JSONObject(response);
JSONArray contestantObjects = jObject.getJSONArray("**messagesByDate**");
for(int i=0; i<contestantObjects.length(); i++){
mMessage .setId(contestantObjects.getJSONObject(i).getString("id").toString());
// Repeat this to get all of other items
}
}
in.close();
} else
Log.e(TAG, "Couldn't open connection in getMenuItems()");
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return mMessage;
}
Now you have an object that each of its item is a list. You can do whatever you want in display method. you can pass it as an object to adapter to show its data.
private void displayData() {
messageAdapter.setData(msg);
listView.setAdapter(messageAdapter);
}
JSONObject json = service.getJunk();
JSONObject msgJson = json.getJSONObject("messagesByDate");
for( Iterator it = msgJson.keys(); it.hasNext(); ) {
Object obj = msgJson.get( (String)it.next() );
if( obj instanceof JSONObject ) {
JSONObject jobj = (JSONObject)obj;
// process json object
} else {
JSONArray arry = (JSONArray)obj;
// process array
}
}