android google news json parsing woes - android

I am writing an Android news reader as a learning exercise and having lots of trouble parsing the data. I have searched everywhere. The tutorials I have found use JSON streams that are of a much simpler structure than what google is sending.
Here is a snippet of the string I capture - the JSON array starts with "entries" and I am showing two entries, with the middle of the second one deleted for brevity.
{
"responseData": {
"feed": {
"feedUrl": "http://news.google.com/news?output\u003drss",
"title": "Top Stories - Google News",
"link": "http://news.google.com/news? pz\u003d1\u0026amp;ned\u003dus\u0026amp;hl\u003den",
"author": "",
"description": "Google News",
"type": "rss20",
"entries": [{
"title": "Major air rescue planned in flooded Colorado county - Fox News",
"link": "http://news.google.com/news/url? sa\u003dt\u0026fd\u003dR\u0026usg\u003dAFQjCNHCJS1c-eurSg- 8tAt0PjZ4tiaLdA\u0026url\u003dhttp://www.foxnews.com/weather/2013/09/15/colorado-braces-for-more-heavy-rain-deadly-floods/",
"author": "",
"publishedDate": "Mon, 16 Sep 2013 04:49:21 -0700",
"contentSnippet": "U.S. News \u0026 World ReportMajor air rescue planned in flooded Colorado countyFox NewsResidents of Boulder County, Colorado are ...",
"content": "\u003ctable border\u003d\"0\" cellpadding\u003d\"2\" cellspacing\u003d\"7\" 3d\"\"border\u003d\"1\" width\u003d\"80\" height\u003d\"80\"\u003e\u003cbr\u003e\u003cfont size\u003d\"-2\"\u003eU.S. News \u0026amp; 03e\u003c/font\u003e\u003cbr\u003e\u003cfont size\u003d\"-1\"\u003eResidents of Boulder County, Colorado are being asked to help guide helicopter pilots to their locations Monday as a major air rescue is being planned to take advantage of a clear weather forecast. \u0026quot;The pilots are going to go anywhere and everywhere they \u003cb\u003e...\u003c/b\u003e\u003c/font\u003e\u003cbr\u003e\u003cfont size\u003d\"-1\"\u003e\u003ca href\u003d\"http://news.google.com/news/url? sa\u003dt\u0026amp;fd\u003dR\u0026amp;usg\u003dAFQjCNHc6lIe9u_YShLkh7NV5WR9rO6YHQ\u0026amp; url\u003dhttp://www.therepublic.com/view/story/b663f09bbf48403c9041a86623fe428e/CO-- Colorado-Flooding-National-Guard\"\u003eNational Guard members trapped during evacuations from flooded Colorado town\u003c/a\u003e\u003cfont size\u003d\"-1\" color\u003d\"#6f6f6f\"\u003eThe Republic\u003c/font\u003e\u003c/font\u003e\u003cbr\u003e\u003cfont size\u003d\"-1\"\u003e\u003ca href\u003d\"http://news.google.com/news/url? sa\u003dt\u0026amp;fd\u003dR\u0026amp;usg\u003dAFQjCNFij70BTG-5dO69JM0BVO32S0S- aA\u0026amp;url\u003dhttp://www.cnn.com/2013/09/15/us/colorado-flooding/? hpt%3Dhp_t1\"\u003eColorado floods: More than 500 still unaccounted for as \u0026#39;devastating\u0026#39; rain looms\u003c/a\u003e\u003cfont size\u003d\"-1\" Radio\u003c/a\u003e\u003c/font\u003e\u003cbr\u003e\u003cfont size\u003d\"-1\"\u003e\u003ca href\u003d\"http://news.google.com/news/more? ncl\u003ddQHisuNx5u46LtMZh5z80DBxCCRjM\u0026amp;ned\u003dus\u0026amp;topic\u003dh\"\u003e\u 003cb\u003eall 1,507 news articles »\u003c/b\u003e\u003c/a\u003e\u003c/font\u003e\u003c/div\u003e\u003c/font\u003e\u003c/td\u0 03e\u003c/tr\u003e\u003c/table\u003e",
"categories": ["Top Stories"]
},
{
"title": "Costa Concordia salvage begins: Will ship stay in one piece during righting? - CNN",
"link": "http://news.google.com/news/url? sa\u003dt\u0026fd\u003dR\u0026usg\u003dAFQjCNFD_8vBF3Gb6B2_6DnbCDwMELEkFQ\u0026url\u003dhtt p://www.cnn.com/2013/09/15/world/europe/italy-costa-concordia-salvage/",
"author": "",
....deletedcontentsforbrevity...."categories": ["Top Stories"]
}]
}
},
"responseDetails": null,
"responseStatus": 200
}
So I have successfully captured the string and now want to create a JSONArray and extract the JSONObjects from it. Here is the code:
private void parseJSONString( JSONObject Jobj) throws IOException, JSONException {
try {
// Getting Array of news
newsItems = Jobj.getJSONArray(ENTRIES);
// looping through All Contacts
for(int i = 0; i < newsItems.length(); i++){
JSONObject c = newsItems.getJSONObject(i);
// Storing each json item in variable
String title = c.getString(TITLE);
String link = c.getString(LINK);
String author = c.getString(AUTHOR);
String pubDate = c.getString(PUBLISHED_DATE);
String content = c.getString(CONTENT);
}
} catch (JSONException e) {
e.printStackTrace();
}
I am catching the JSONException with the message "No values for entries" from the very
first line of code: newsItems = Jobj.getJSONArray(ENTRIES);
The parameter jobj and call to this method is created onPostExecute like this:
protected void onPostExecute(Void result) {
mTextView.setText(mDataString);
if (mDataString != null)
try {
mJSONObj = new JSONObject(mDataString);
parseJSONString(mJSONObj);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
Log.e("JSON Parser", "Error converting string to json " + e.toString());
}
}
Yet as you can see, "entries" clearly precedes the array marker "[" in the text file. I am truly stumped. Would appreciate a little help.

You must firstly get:
responseData -> feed -> entries
JSONObject responseData = Jobj.getJSONObject("responseData");
JSONObject feed = responseData.getJSONObject("feed");
and only after:
newsItems = feed.getJSONArray("entries");

Related

Android - How to Represent JSON Information from URL through GSON

I have been attempting to retrieve information from an online JSON Source using a URL. I initially got the information parsed to a TextView in Android, however I got ALL Information from the JSON. Below is a screenshot of what I am referring to.
Text View Showing All Data In Json
Essentially, What I want is to just show the Location, so in the above example, Oslo, in Norway in one Textview, then in another show the Current Moon Phase for that location, so - using the above example again, Waxing Crescent.
This is the JSON I am using.
{
"version": 2,
"locations": [{
"id": "187",
"geo": {
"name": "Oslo",
"country": {
"id": "no",
"name": "Norway"
},
"latitude": 59.913,
"longitude": 10.740
},
"astronomy": {
"objects": [{
"name": "moon",
"days": [{
"date": "2018-09-13",
"events": [],
"moonphase": "waxingcrescent"
}]
}]
}
}]
}
To parse the JSON to the Textview showing all the data I used the following.
JSONObject jo = new JSONObject(data);
JSONArray locations = jo.getJSONArray("locations");
for (int i = 0; i < locations.length(); ++i) {
JSONObject loc = locations.getJSONObject(0);
JSONObject geo = loc.getJSONObject("geo");
JSONObject country = geo.getJSONObject("country");
JSONObject astronomy = loc.getJSONObject("astronomy");
JSONObject objects = astronomy.getJSONArray("objects").getJSONObject(0);
JSONObject day = objects.getJSONArray("days").getJSONObject(0);
StringBuilder result = new StringBuilder();
String singleParsed = "Moon: "+ astronomy.getString("moonphase");
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
MainActivity.fetcheddata.setText(this.data);
}
NOTE: A String is created in the For Loop, Called "Single Parsed", This is what I want to put on the screen, however - once I call that variable, nothing shows on the screen. It only shows when using:
MainActivity.fetcheddata.setText(this.data);
But Not with the following, I do actually receive an error saying "Cannot Resolve Symbol, singleParsed as well.
MainActivity.fetcheddata.setText(this.singleParsed);
After some research and previous questions on Stack, I believe GSON is the way to go to do what I wish, however I have no idea where to start, or how to do the task using GSON.
All help is appreciated.
JSON Information from URL through GSON
Simple answer - Look at using Retrofit, and find a tutorial on it, as well as Gson
However
You don't need Gson to fix your problem, and I suggest fixing the problem at hand rather than going down an unnecessary path.
First, singleParsed is a local variable within a loop. Therefore, this.singleParsed doesn't exist. Or if it does, you never set it.
Secondly, let's assume you only have one location, so you don't need a loop. Similar to how you accessed the other JSON arrays, just get the first array item.
Finally, you'll need to understand how AsyncTask works, but my general recommended solution is at How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
But, for this purpose, here is a simple example with AsyncTask<String, Void, String>
// protected String doInBackground(String... url) { // I assume you have this ??
// String data = parseJsonFrom(url[0]);
String singleParsed = "(none)";
try {
JSONObject jo = new JSONObject(data);
JSONObject firstLocationAstronomy = jo
.getJSONArray("locations").getJSONObject(0)
.getJSONObject("astronomy");
JSONObject firstDay = firstLocationAstronomy
.getJSONArray("objects").getJSONObject(0)
.getJSONArray("days").getJSONObject(0);
singleParsed = firstDay.getString("moonphase");
} catch (Exception e) { // TODO: catch a JSONParseException
}
return singleParsed; // This is returned to onPostExecute, don't store a variable elsewhere
}
Then in the MainActivity, wherever you make this task, and set the text
new MoonPhaseTask() {
#Override
protected void onPostExecute(String moonPhase) {
MainActivity.this.textView.setText("Phase: " + moonPhase);
}
}.execute("some url");
What I want is to just show the Location, so in the above example, Oslo, in Norway in one Textview, then in another show the Current Moon Phase for that location
You can change the AsyncTask to return you the entire JSONObject to the onPostExecute, and parse the JSON there if you really wanted. Just the networking pieces need to be off the UI thread... parsing is not computationally expensive.

Json parsin gorg.json.JSONObject cannot be converted to JSONArray [duplicate]

This question already has answers here:
How do I parse JSON in Android? [duplicate]
(3 answers)
Closed 5 years ago.
My json is like this i want to parse newsitems to get tittle,url,contents,feelabel,url and feedlabel
{
"appnews": {
"appid": 466560,
"newsitems": [
{
"gid": "2284879949551103234",
"title": "These are the top 100 Steam games of 2017",
"url": "http://store.steampowered.com/news/externalpost/rps/2284879949551103234",
"is_external_url": true,
"author": "contact#rockpapershotgun.com (Alec Meer)",
"contents": "Another year over, a new one just begun, which means, impossibly, <em>even more games.</em> But what about last year? Which were the games that most people were buying and, more importantly, playing? As is now something of a tradition, Valve have let slip a big ol’ breakdown of the most successful titl...",
"feedlabel": "Rock, Paper, Shotgun",
"date": 1514919601,
"feedname": "rps",
"feed_type": 0,
"appid": 550
},
{
"gid": "2284879949546841782",
"title": "ShiroGames - Bye bye 2017 and WELCOME 2018 !!!",
"url": "http://store.steampowered.com/news/externalpost/steam_community_announcements/2284879949546841782",
"is_external_url": true,
"author": "Lord_brioche",
"contents": "Hello Northgardians, As the end of 2017 is upon us, we wanted to share with you a few thoughts. What a year! At the beginning of 2017, Northgard was about to start its 6-months Early Access period. At the time, the game was supposed to be a fun, solo strategy game with 4 clans and ShiroGames was onl...",
"feedlabel": "Community Announcements",
"date": 1514818282,
"feedname": "steam_community_announcements",
"feed_type": 1,
"appid": 466560
},
{
"gid": "2284879949521363459",
"title": "Best PC games of 2017",
"url": "http://store.steampowered.com/news/externalpost/rps/2284879949521363459",
"is_external_url": true,
"author": "contact#rockpapershotgun.com (RPS)",
"contents": "The calendar’s doors have been opened and the games inside have been eaten. But fear not, latecomer – we’ve reconstructed the list in this single post for easy re-consumption. Click on to discover the best games of 2017. (more…) ",
"feedlabel": "Rock, Paper, Shotgun",
"date": 1514206814,
"feedname": "rps",
"feed_type": 0,
"appid": 240720
}
]
,
"count": 57
}
}
Json parsing code is like this
#Override
protected Void doInBackground(Void... arg0) {
News news = new News();
HttpHandler sh = new HttpHandler();
// Making a request to url and getting response
String url = "http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/?appid=466560&count=3&maxlength=300&format=json";
String jsonStr = sh.makeServiceCall(url);
;
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
JSONArray contacts = jsonObj.getJSONArray("appnews");
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
news.setTittle( c.getString("title"));
news.setContent(c.getString("content"));
news.setDate(c.getString("date"));
news.setFeed(c.getString("feedlabel"));
news.setUrl(c.getString("url"));
newsList.add(news);
}
} catch (final JSONException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
}
} else {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server",
Toast.LENGTH_LONG).show();
}
});
}
return null;
}
I got error like this i want to parse newsitems to get tittle,url,contents,feelabel,url and feedlabel i used this tutorial https://www.tutorialspoint.com/android/android_json_parser.htm
org.json.JSONException: Value {"appid":466560,"newsitems":[{"gid":"2284879949551103234","title":"These are the top 100 Steam games of 2017","url":"http:\/\/store.steampowered.com\/news\/externalpost\/rps\/2284879949551103234","is_external_url":true,"author":"contact#rockpapershotgun.com (Alec Meer)","contents":"Another year over, a new one just begun, which means, impossibly, <em>even more games.<\/em> But what about last year? Which were the games that most people were buying and, more importantly, playing? As is now something of a tradition, Valve have let slip a big ol’ breakdown of the most successful titl...","feedlabel":"Rock, Paper, Shotgun","date":1514919601,"feedname":"rps","feed_type":0,"appid":550},{"gid":"2284879949546841782","title":"ShiroGames - Bye bye 2017 and WELCOME 2018 !!!","url":"http:\/\/store.steampowered.com\/news\/externalpost\/steam_community_announcements\/2284879949546841782","is_external_url":true,"author":"Lord_brioche","contents":"Hello Northgardians, As the end of 2017 is upon us, we wanted to share with you a few thoughts. What a year! At the beginning of 2017, Northgard was about to start its 6-months Early Access period. At the time, the game was supposed to be a fun, solo strategy game with 4 clans and ShiroGames was onl...","feedlabel":"Community Announcements","date":1514818282,"feedname":"steam_community_announcements","feed_type":1,"appid":466560},{"gid":"2284879949521363459","title":"Best PC games of 2017","url":"http:\/\/store.steampowered.com\/news\/externalpost\/rps\/2284879949521363459","is_external_url":true,"author":"contact#rockpapershotgun.com (RPS)","contents":"The calendar’s doors have been opened and the games inside have been eaten. But fear not, latecomer – we’ve reconstructed the list in this single post for easy re-consumption. Click on to discover the best games of 2017. <a href=\"https:\/\/www.rockpapershotgun.com\/2017\/12\/25\/best-pc-games-of-2017\/#more-503951\" class=\"more-link\">(more…)<\/a> ","feedlabel":"Rock, Paper, Shotgun","date":1514206814,"feedname":"rps","feed_type":0,"appid":240720}],"count":57} at appnews of type org.json.JSONObject cannot be converted to JSONArray
appnews is JSONObject so
// fetch appnews jsonobject
JSONArray news= jsonObj.getJSONObject("appnews");
// fetch the news items jsonarray which actually contains your data
JSONArray contacts = news.getJSONArray("newsitems");
There is a typo and apparently, there's already a news object so
JSONArray appNews= jsonObj.getJSONObject("appnews");
JSONArray contacts = appNews.getJSONArray("newsitems");
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
news.setTittle( c.getString("title"));
news.setContent(c.getString("contents"));
news.setDate(c.getString("date"));
news.setFeed(c.getString("feedlabel"));
news.setUrl(c.getString("url"));
newsList.add(news);
}
Try This
try
{
JSONObject jsonObj = new JSONObject(jsonStr);
JSONObject jsonObjAppnews = jsonObj.getString("appnews");
JSONArray contacts = jsonObjAppnews.getJSONArray("newsitems");
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
news.setTittle( c.getString("title"));
news.setContent(c.getString("contents"));
news.setDate(c.getString("date"));
news.setFeed(c.getString("feedlabel"));
news.setUrl(c.getString("url"));
newsList.add(news);
}
}
catch (final JSONException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}

post array of objects that contains image data as multipart through retrofit in android

I have to post some data from android in this form
[
{
"title": "song's title",
"artists": "artist1, artist2,....",
"album": "album name",
"genre": "genre name",
"added_at": "datetime etc",
"counter": x (int value i.e. 3),
"cover_art": "image data"(File)
},
{
"title": "song's title",
"artists": "artist1, artist2,....",
"album": "album name",
"genre": "genre name",
"added_at": "datetime etc",
"counter": x (int value i.e. 3),
"cover_art": "image data"(File)
},
.......and so on.
]
How can i post this from retrofit. From what i know is that one can upload images as Multipart in retrofit but here i have json array which contains Image data.
Please help , thanks in advance.
Okay so I did this - i created a class with these fields -
public class PostServerSongDM {
String title , artists , album , genre, added_at;
long counter;
byte[] cover_art;
public PostServerSongDM(String t , String ar , String al , String ge, String addat , long cou , String path){
title = t;
artists = ar;
album = al;
genre = ge;
added_at = addat;
counter = cou;
File image = new File(path.substring(7));
int size = (int) image.length();
cover_art = new byte[size];
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(image));
buf.read(cover_art, 0, cover_art.length);
buf.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
and then created a Retofit interface like this -
public interface PostSongList {
#POST("your api")
Call<SampleResponse> request(#Body ArrayList<PostServerSongDM> list);
}
and with this , i was able to post a request to server with exact json data format which is given in question.
P.S - I don't know if this was an obvious solution or not but i couldn't figure this out before and now i did.

Android REST api (JSON array) to Couchbase Lite

I have an android application, which fetch data from REST api and save it to arraylist. But now I want to save data from REST api to Couchbase Lite. How can I do this? One more thing is, if data in REST api change, then the change also save in Couchbase Lite. Please help.
Here is my REST api JSON array data..
[
{
"ID": "1001",
"VAT": 0,
"barCode": "1023sewe",
"catagoryName": "Mobile",
"name": "Samsung Galaxy A5",
"purchasingPrice": 20000,
"quantity": 5,
"sellingPrice": 25000
},
{
"ID": "1002",
"VAT": 0,
"barCode": "215qwqw",
"catagoryName": "Mobile",
"name": "Iphone S5",
"purchasingPrice": 40000,
"quantity": 3,
"sellingPrice": 45000
}
]
You can perform insert and update operations in Couchbase lite. Follow this link that explains the CRUD operations.
http://developer.couchbase.com/documentation/mobile/1.2/develop/training/build-first-android-app/do-crud/index.html
Insert sample
private String createDocument(Database database) {
// Create a new document and add data
Document document = database.createDocument();
String documentId = document.getId();
Map<String, Object> map = new HashMap<String, Object>();
map.put("name", "Big Party");
map.put("location", "My House");
try {
// Save the properties to the document
document.putProperties(map);
} catch (CouchbaseLiteException e) {
Log.e(TAG, "Error putting", e);
}
return documentId;
}
Update sample
private void updateDoc(Database database, String documentId) {
Document document = database.getDocument(documentId);
try {
// Update the document with more data
Map<String, Object> updatedProperties = new HashMap<String, Object>();
updatedProperties.putAll(document.getProperties());
updatedProperties.put("eventDescription", "Everyone is invited!");
updatedProperties.put("address", "123 Elm St.");
// Save to the Couchbase local Couchbase Lite DB
document.putProperties(updatedProperties);
} catch (CouchbaseLiteException e) {
Log.e(TAG, "Error putting", e);
}
}

Parsing Android String to JSONArray

I have a JSONString that came back successfully and I want to convert it into a JSONArray where I can parse the bits. The string came back successfully but when I try to log the "title" within each movie's object inside the "results" array, it's not coming up.
public List<MovieItem> fetchItems() {
List<MovieItem> items = new ArrayList<>();
try {
String url = Uri.parse("https://api.themoviedb.org/3/movie/popular")
.buildUpon()
.appendQueryParameter("api_key", API_KEY)
.build().toString();
String jsonString = getUrlString(url);
Log.i(TAG, "Received JSON: " + jsonString);
JSONObject jsonBody = new JSONObject(jsonString);
JSONArray photoJsonArray = jsonBody.getJSONArray("results");
for(int i = 0; i < photoJsonArray.length(); i++){
JSONObject jsonPart = photoJsonArray.getJSONObject(i);
Log.i("title", jsonPart.getString("title"));
}
} catch (IOException ioe) {
Log.e(TAG, "Failed to fetch items", ioe);
} catch (JSONException je) {
Log.e(TAG, "Failed to parse", je);
}
return items;
}
-
02-03 13:34:43.236 4728-4746/? I/MovieFetchr: Received JSON: {
"page":1,
"results":[
{
"poster_path":"\/oXUWEc5i3wYyFnL1Ycu8ppxxPvs.jpg",
"adult":false,
"overview":"In the 1820s, a frontiersman, Hugh Glass, sets out on a path of vengeance against those who left him for dead after a bear mauling.",
"release_date":"2015-12-25",
"genre_ids":[37,18,12,53],
"id":281957,
"original_title":"The Revenant",
"original_language":"en",
"title":"The Revenant",
"backdrop_path":"\/uETWtwsE1QjfoFqRQqFLnSjppPA.jpg",
"popularity":42.096309,
"vote_count":1079,
"video":false,
"vote_average":7.36
},
{
"poster_path":"\/kqjL17yufvn9OVLyXYpvtyrFfak.jpg",
"adult":false,
"overview":"An apocalyptic story set in the furthest reaches of our planet, in a stark desert landscape where humanity is broken, and most everyone is crazed fighting for the necessities of life. Within this world exist two rebels on the run who just might be able to restore order. There's Max, a man of action and a man of few words, who seeks peace of mind following the loss of his wife and child in the aftermath of the chaos. And Furiosa, a woman of action and a woman who believes her path to survival may be achieved if she can make it across the desert back to her childhood homeland.",
"release_date":"2015-05-13",
"genre_ids":[878,53,28,12],
"id":76341,
"original_title":"Mad Max: Fury Road",
"original_language":"en",
"title":"Mad Max: Fury Road",
"backdrop_path":"\/tbhdm8UJAb4ViCTsulYFL3lxMCd.jpg",
"popularity":32.157869,
"vote_count":3566,
"video":false,
"vote_average":7.5
},
try changing
Log.i("title", jsonPart.getString("title"));
to
Log.i(TAG, "Title: " + jsonPart.getString("title"));
and comment out the above log statement so it can be read easily

Categories

Resources