EDIT after proper initialisation but everything works but I still get only the first object in "events" array. Why ?
I've an AsyncTask which connects to server to download JSON file and to get JSON array from there. The problem is that when I want to extract another data from the same array using for loop I got a null pointer exception. Why ? I am extracting the values "lat","lon","text" from array "events".
Here is how my JSON looks :
{
"current_ts": 1425907330,
"username": "guri",
"events": [
{
"id": 16591481,
"ts": 1425907325,
"lat": 48.17,
"lon": 17.13,
"likes": 5,
"text": "Poziar na hlavnej stanici",
"tags": "#poziar #stanica #hori",
"img": "2002-06-19.jpg"
},
{
"id": 47067411,
"ts": 1425907100,
"lat": 48.81,
"lon": 17.22,
"likes": 0,
"text": "V Bille je velky vypredaj",
"tags": [
{
"tag1": "#akcia",
"tag2": "#akcia"
}
],
"img": "DSC04934.jpg"
}
]
And here is a code snippet from my AsyncTask:
#Override
protected Void doInBackground(Void... params) {
// Retrieve JSON Objects from the given URL address
jsonobject = JSONfunctions
.getJSONfromURL("http://guri.sk/mapped/mapped.json");
try {
// Locate the array name in JSON
event = jsonobject.getJSONArray("events");
for (int i = 0; i < event.length(); i++) {
jsonobject = event.getJSONObject(i);
lat2[i] = jsonobject.getDouble("lat");
lon2[i] = jsonobject.getDouble("lon");
text1[i] = jsonobject.getString("text");
number = i;
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
// Close the progressdialog
mProgressDialog.dismiss();
for (int i = 0; i < number; i++) {
mMap.addMarker(new MarkerOptions().position(new LatLng(lat2[i], lon2[i])).title(text1[i]));
}
}
How I initialize:
double[] lat2 = new double[10];
double[] lon2 = new double[10];
String[] text1 = new String[10];
Answer to your problem after edit:
If your JSON has two elements then after for loop value of number will be 1, and then in onPostExecute for loop will execute only for first element in array. So I think you should set value of number before for loop:
number = event.length();
for (int i = 0; i < event.length(); i++) {
jsonobject = event.getJSONObject(i);
lat2[i] = jsonobject.getDouble("lat");
lon2[i] = jsonobject.getDouble("lon");
text1[i] = jsonobject.getString("text");
}
The problem is that you can't directly use for whatever reason for loop in onPostExecute of AsyncTask. You have to wrap it in a method. Here is the code snippet that works:
protected Void doInBackground(Void... params) {
// Retrieve JSON Objects from the given URL address
jsonobject = JSONfunctions
.getJSONfromURL("http://guri.sk/mapped/mapped.json");
try {
// Locate the array name in JSON
event = jsonobject.getJSONArray("events");
number = event.length();
for (int i = 0; i < event.length(); i++) {
jsonobject = event.getJSONObject(i);
lat2[i] = jsonobject.getDouble("lat");
lon2[i] = jsonobject.getDouble("lon");
text1[i] = jsonobject.getString("text");
//Log.e("TAG","lat2:"+lat2[i]+"lon2:"+lon2[i]);
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
// Close the progressdialog
mProgressDialog.dismiss();
placeMarkers();
}
}
public void placeMarkers(){
for (int i = 0; i < number; i++) {
Log.e("TAG","lat2:"+lat2[i]+"lon2:"+lon2[i]);
mMap.addMarker(new MarkerOptions().position(new LatLng(lat2[i], lon2[i])).title(text1[i]));
}
}
Related
{
"batchcomplete": "",
"query": {
"pages": {
"25675557": {
"pageid": 25675557,
"ns": 0,
"title": "Cricket",
"extract": "Cricket is a bat-and-ball game played between two teams of eleven players each on a cricket field, at the centre of which is a rectangular 22-yard-long (20 metres) pitch with a target at each end called the wicket (a set of three wooden stumps upon which two bails sit). "
}
}
}
}
this is the code I tried :
public void getJSON(final String city) throws JSONException {
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
try {
URL url = new URL("https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&exintro=&explaintext=&titles=" + city);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
BufferedReader reader =
new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer json = new StringBuffer(1024);
String tmp = "";
while ((tmp = reader.readLine()) != null) {
json.append(tmp).append("\n");
}
reader.close();
data = new JSONObject(json.toString());
if (data.getInt("cod") != 200) {
System.out.println("Cancelled");
return null;
}
} catch (Exception e) {
System.out.println("Exception " + e.getMessage());
return null;
}
return null;
}
#Override
protected void onPostExecute(Void Void) {
if (data != null) {
Log.d("my weather received", data.toString());
try {
//JSONObject forecastJson = new JSONObject(data);
JSONObject forecastArray = data.getJSONObject("query");
System.out.println(forecastArray);
JSONArray pagesArray = forecastArray.getJSONArray("pages");
// JSONArray idArray = pagesArray.getJSONArray(0);
//JSONArray idArray = pagesArray.get(0);
System.out.println(pagesArray);
JSONObject obj = pagesArray.getJSONObject(0);
System.out.println(obj);
//JSONObject weatherarray = data.getJSONObject("pages");
//JSONObject weather = weatherarray.getJSONObject(0);
// final String des = weather.getString("description");
/*for (int i = 0; i < forecastArray.length(); i++) {
JSONObject dailyForecast = forecastArray.getJSONObject(i);
JSONObject tempObject = dailyForecast.getJSONObject("main");
minTemp = tempObject.getDouble("min");
maxTemp = tempObject.getDouble("max");
//add these minTemp and maxTemp to array or the
//way you want to use
}*/
System.out.println("Temp Value : "+" : ");
runOnUiThread(new Runnable() {
#Override
public void run() {
textvw.setText("");
}
});
} catch (Exception e) {
Log.e("GetFeedTask", "Error:" + e.getMessage());
}
}
}
}.execute();
}
The exception is because the response does not contain JSON Array. Change your
JSONArray pagesArray = forecastArray.getJSONArray("pages");
to
JSONObject pagesArray = forecastArray.getJSONObject("pages");
and I believe that you're trying to get keys which are dynamic. You cloud get the objects using JSONObject.getKeys() like below.
Iterator keys = pagesArray.keys();
while(keys.hasNext()) {
String dynamicKey = (String)keys.next();
JSONObject jObj = pagesArray.getJSONObject(dynamicKey);
//Get other attributes by jObj.getString() method.
}
Try and let me know if it works.
The error is clear enough. you try to assign a JSONobject to a JSONArray
JSONArray pagesArray = forecastArray.getJSONArray("pages");
Replace by
JSONObject pagesArray = forecastArray.JSONObject("pages");
the data of a JSONArray are between [] and not {}.
your error is in :
JSONArray pagesArray = forecastArray.getJSONArray("pages");
Your problem is that you getJSONArray while pages are a JsonObject in your data .if your "pages" is a array in your data you must send it in [] from server like this:
{
"batchcomplete": "",
"query": {
"pages": [ {
"pageid": 25675557,
"ns": 0,
"title": "Cricket",
"extract": "Cricket is a bat-and-ball game played between two teams of eleven players each on a cricket field, at the centre of which is a rectangular 22-yard-long (20 metres) pitch with a target at each end called the wicket (a set of three wooden stumps upon which two bails sit). "
},
{
"pageid": 25675557,
"ns": 0,
"title": "Cricket",
"extract": "Cricket is a bat-and-ball game played between two teams of eleven players each on a cricket field, at the centre of which is a rectangular 22-yard-long (20 metres) pitch with a target at each end called the wicket (a set of three wooden stumps upon which two bails sit). "
}
]
}
}
and in android :
try {
//JSONObject forecastJson = new JSONObject(data);
JSONObject forecastArray = data.getJSONObject("query");
System.out.println(forecastArray);
JSONArray pagesArray = forecastArray.getJSONArray("pages");
System.out.println(pagesArray);
for (int k = 0; k < pagesArray.length(); k++) {
try {
JSONObject object = pagesArray.getJSONObject(k);
String pageid = object.getString("pageid");
String ns = object.getString("ns");
String title = object.getString("title");
String extract = object.getString("extract");
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
Log.e("GetFeedTask", "Error:" + e.getMessage());
}
I am parsing a json url: http://www.json-generator.com/api/json/get/bQmwsOmYeq?indent=2 but I failed to make it happen. I am getting an error. What's wrong with this code?
public void parseJsonResponse(String result) {
Log.i(TAG, result);
pageCount++;
try {
JSONObject json = new JSONObject(result);
JSONArray jArray = json.getJSONArray("name");
for (int i = 0; i < jArray.length(); i++) {
JSONObject jObject = jArray.getJSONObject(i);
CountryInfor country = new CountryInfor();
country.setId(jObject.getString("id"));
country.setName(jObject.getString("name"));
countries.add(country);
}
adapter.notifyDataSetChanged();
if (dialog != null) {
dialog.dismiss();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Replace
JSONObject json = new JSONObject(result);
JSONArray jArray = json.getJSONArray("name");
these two lines by
JSONArray jArray = new JSONArray(result);
Also change
country.setId(jObject.getString("id"));
by
country.setId(jObject.getInt("id") + "");
Because id is of type int not a String.
And it will work fine.
You are getting response like
[
{
"id": 1,
"name": "Vietnam"
},
{
"id": 2,
"name": "China"
},
{
"id": 3,
"name": "USA"
},
{
"id": 4,
"name": "England"
},
{
"id": 10,
"name": "Russia"
}
]
So the response is JSONArray and not JSONObject.
Hope it'll help.
Edit
#Override
protected String doInBackground(Void... params) {
// call load JSON from url method
if(loadJSON(this.url) != null) {
return loadJSON(this.url).toString();
}
Log.d("LoadJSONFromUrl", "Failed to get JSONObject.");
return null;
}
You are getting JSONObject null, so the error is.
- You should know what is NullPointerException
the issue is with this line
JSONArray jArray = json.getJSONArray("name");
There is no array with name name. it is failing here. Correct this part to obtain the array properly. Rest looks fine.
I am working on an app which I need to parse jsonarray. I have my json values in base64 and I need to decode strings to retrive data with decode String. Here is my code :
private class DecodeData extends AsyncTask<String, Void, String> {
#SuppressWarnings("unchecked")
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
String response = params[0];
String keys = "";
String value = "";
String b64Value = "";
LinkedHashMap<String, String> map = new LinkedHashMap<String, String>();
try {
JSONArray array = new JSONArray(response);
for (int i = 0; i < array.length(); i++) {
Iterator<String> it = array.getJSONObject(i).keys();
while (it.hasNext()) {
keys = (String)it.next();
value = (String)array.getJSONObject(i).get(keys);
b64Value = Base64.DecodeStrToStr(value);
Log.i("ASYNC TASK VALUE", b64Value);
map.put(keys, b64Value);
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return map.toString();
}
I get only the first JSONObject and I need to get all JSONObject with all values. I can't use getString(name) because my json can have others keys. What am I doing wrong and why am I getting only the first JSONObject and not the others ?
json type :
[
{
"value": "ZG1WdVpISmxaR2tnTWpVZ1lYWnlhV3c4WW5JZ0x6NEtSMVZaUVU1QklFRk1UQ0JUVkVGUw==",
"date_create": "MjAxNC0wNC0yNSAwMDowMDowMA==",
"picture": "aHR0cDovL3dzLmFwcHMtcGFuZWwubmV0L2RhdGEvcGFsYWNpby8yNWF2cmlsLmpwZw==",
"link": "",
"title": "MjVhdnJpbA==",
"media": "",
"id_news": "MTA5NjI0",
"id_reference": "",
"type": "",
"id_categorie": "",
"date_event": "MjAxNC0wNC0yNSAwMDowMDowMA==",
"chapo": "",
"auteur": "",
"value_out": "dmVuZHJlZGkgMjUgYXZyaWxHVVlBTkEgQUxMIFNUQVI="
},
{
"value": "YzJGdFpXUnBJREkySUdGMmNtbHNQR0p5SUM4K0NrMUJVbFpKVGlCaGJtUWdSbEpKUlU1RVV3PT0=",
"date_create": "MjAxNC0wNC0yNiAwMDowMDowMA==",
"picture": "aHR0cDovL3dzLmFwcHMtcGFuZWwubmV0L2RhdGEvcGFsYWNpby8yNmF2cmlsMi5qcGc=",
"link": "",
"title": "MjZhdnJpbA==",
"media": "",
"id_news": "MTA5NjMx",
"id_reference": "",
"type": "",
"id_categorie": "",
"date_event": "MjAxNC0wNC0yNiAwMDowMDowMA==",
"chapo": "",
"auteur": "",
"value_out": "c2FtZWRpIDI2IGF2cmlsTUFSVklOIGFuZCBGUklFTkRT"
},
Here is what i am getting with my code :
RESPONSE :{date_create=MjAxNC0wNS0yNSAwMDowMDowMA==, link=, date_event=MjAxNC0wNS0yNSAwMDowMDowMA==, type=, value_out=ZGltYW5jaGUgMjUgbWFpRE9MQSBNSVpJSyBlbiBjb25jZXJ0, picture=aHR0cDovL3dzLmFwcHMtcGFuZWwubmV0L2RhdGEvcGFsYWNpby8yNW1haS5qcGc=, title=MjUgbWFp, id_reference=, chapo=, value=WkdsdFlXNWphR1VnTWpVZ2JXRnBQR0p5SUM4K0NqeGljaUF2UGdwRVQweEJJRTFKV2tsTElHVnVJR052Ym1ObGNuUT0=, id_news=MTA5NjM0, media=, auteur=, id_categorie=}
Anybody has an idea of how I can do ?
Thank you
Problem:
You are putting all results in the same Map. Each object in the JSONArray will erase the values of previous objects because the keys are the same.
In the end, you get only one value for each key.
Solution:
You need one map per JSON object in the array. You could use a list (or array) of Maps, for instance. Here is some code:
ArrayList<HashMap<String, String>> decodedArray = new ArrayList<>();
JSONArray array = new JSONArray(response);
for (int i = 0; i < array.length(); i++) {
HashMap<String, String> map = new HashMap<>();
Iterator<String> it = array.getJSONObject(i).keys();
while (it.hasNext()) {
keys = (String) it.next();
value = (String) array.getJSONObject(i).get(keys);
b64Value = Base64.DecodeStrToStr(value);
Log.i("ASYNC TASK VALUE", b64Value);
map.put(keys, b64Value);
}
decodedArray.add(map);
}
Add you json value into model object I hope it would be helpful for you.
public class A {
private Vector<B> b = new Vector<B>();
public Vector<B> getB() {
return b;
}
public void addB(B b) {
this.b.add(b);
}
public class B{
private String value;
private String picture;
//add your paramatere here like link, title etc
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getPicture() {
return picture;
}
public void setPicture(String picture) {
this.picture = picture;
}
}
}
Then after parsing value set into bean object like that.
A a = new A();
for (int i = 0; i < jsonArray.length(); i++) {
B b= a.new B();
JSONObject jsonObject= (JSONObject)jsonArray.get(i);
String value= jsonObject.getString("value");
jsonObject.getString("picture");
// get all value from json object set into b object
a.addB(b);
}
I want to get only some selected values from the JSON response.For example if JSON contains 100 string values then i need to take the values which are starting with # symbol from that 100 values.
How can I do that ?
Following is my JSON,
[{"Obj" :
{ "ID":"11",
"NAME":"XYZ",
"GENDER":"M"
}
{ "ID":"11",
"NAME":"#XYZ",
"GENDER":"M"
}
{ "ID":"11",
"NAME":"#XYZ",
"GENDER":"M"
}
}]
Here I need to fetch Name which having # symbol
You can use below method to get the Name which start with # :
JSONObject jsonObject = new JSONObject(response);// u can change it as per your need
JSONArray jArray = jsonObject.getJSONArray("Obj");// if your `Obj` is an JsonArray
for (int i = 0; i < jArray.length(); i++) {
String json_name = jArray.getJSONObject(i).getString("NAME");
if(json_name.startsWith("#"))
{
Log.d(TAG,"It start with #");
}
}
Try out as below:
private void parseJSON(String json) {
try {
JSONArray items = new JSONArray(<your Json Response>);
for (int i = 0; i < items.length(); i++) {
JSONObject item = items.getJSONObject(i);
System.err.println("Object---" + item.getString("Obj"));
JSONObject obj=item.getJSONObject("Obj");
for (int j = 0; j < obj.length(); j++) {
String Name=obj.getString("NAME");
if(obj.getString("NAME").toString().contains("#"))
{
Log.d("Name starts with-->", Name);
}
else
{
Log.d("Name does not start with-->", Name);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Try this.
first of all that's not a valid json may be below json is correct format
[
{
"Obj": [
{
"ID": "11",
"NAME": "XYZ",
"GENDER": "M"
},
{
"ID": "11",
"NAME": "#XYZ",
"GENDER": "M"
},
{
"ID": "11",
"NAME": "#XYZ",
"GENDER": "M"
}
]
}
]
if your response like above try below code this may help you.
try {
JSONArray jsoArray = new JSONArray(json);
JSONArray JobjArray = jsoArray.getJSONObject(0).getJSONArray("Obj");
for(int i=0; i < JobjArray.length(); i++)
{
JSONObject Jobj = JobjArray.getJSONObject(i);
Iterator<String> iter = Jobj.keys();
while (iter.hasNext()) {
String key = iter.next();
Log.v("key--", key);
try {
Object value = Jobj.get(key);
Log.v("value--", ""+value);
String str_value = value.toString().trim();
if(str_value.startsWith("#"))
{
Log.d(""+str_value,"value started with #");
}
} catch (JSONException e) {
// Something went wrong!
e.printStackTrace();
}
}
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
How can i extract the json below and save it in an arraylist.
{
"trains": {
"train": [
{
"#id": 1000000103,
"#version": 1,
"#status": "active",
"#name": "dffffff",
"#description": "ffffff half of the nineteenth century.",
"#city": "fff",
"#phone": "+230 595-1454",
"#email": "ffffr#mffc.mu",
"#website": "www4u",
"#latitude": -5.2882,
"#longitude": 3.499,
"#defaultLocale": "",
"#holes": 48,
"#par": 72,
"#slope": 0,
"#distance": 5.005273,
"circuits": {
"circuit": []
},
"localizations": {
"localization": []
}
},
{
"#id": 1000000105,
"#version": 1,
"#status": "active",
"#name": " xClub",
"#description": "",
"#city": " xlet",
"#phone": "+44465\t",
"#email": "",
"#website": "wweffl.com",
"#latitude": -2.040318,
"#longitude": 54548,
"#defaultLocale": "",
"#holes": 18,
"#par": 32,
"#slope": 0,
"#distance": 2441673,
"circuits": {
"circuit": []
},
"localizations": {
"localization": []
}
}
]
}
}
my working
try {
jobj_trouve_train = new JSONObject(reponse_trouve_train);
String jsonobj = jobj_trouve_golf.getString("trains");
//String jsonobj1 = jobj_trouve_golf.getString("train");
//jobj_trouve_train = new JSONObject(reponse_trouve_train);
//jsonArray = jobj_trouve_golf.getJSONArray("trains");
//jsonArray= new JSONArray(jsonobj);
//System.out.println("jsonArray "+jsonArray);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Try this..
try {
jobj_trouve_train = new JSONObject(reponse_trouve_train);
JSONObject jsonobj = jobj_trouve_train.getJSONObject("trains");
JSONArray jsonobj1 = jsonobj.getJSONArray("train");
for(int i = 0;i< jsonobj1.length();i++){
JSONObject jsonj = jsonobj1.getJSONObject(i);
System.out.println("#id "+jsonj.getString("#id"));
// Same for remaining all
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You can use the Gson library developed by Google to parse Json into objects.
The reference is here:
https://code.google.com/p/google-gson/
And, a sample example is here:
JSON Parsing with GSON
JSONObject trains = jobj_trouve_train.getJSONObject("trains");
JSONArray trainArray = trains.getJSONArray("train");
JSONObject train1 = trainArray.getJSONObject(0);
...
if i didn't get confuse maybe this one will be right
JSONArray jasonArray = new JSONArray(result.getProperty("trains").toString());
for (int i = 0; i < jasonArray.length(); i++) {
JSONObject jsonObj = jasonArray.optJSONObject(i);
trainObject = new JSONObject(jsonObj.optString("train").toString());
int id = trainObject.optInt("id");
and so on..
}
public Object void toObject(String jsonMsg) throws JSONException {
JSONObject trains= (JSONObject) new JSONTokener(jsonMsg).nextValue();
if(trains.has("trains")){
JSONArray train = (JSONArray) new JSONTokener(object.getString("train")).nextValue();
for (int t = 0; t < jsonArray.length(); t++) {
String temp = jsonArray.getJSONObject(t).toString();
JSONObject object = (JSONObject) new JSONTokener(temp).nextValue();
if(object.has("#id"))
object.getString("#id");
// now similar procedure of reading
// read values and save it in an "object"
}
return savedObject;
}
-- tested, i have tried to modify code to match your JSON data. complete the rest.