Android JSON Parsing with multiple arrays - android

I need to parse JSON file with multiple arrays.
Array is in format:
{
"List": {
"Something": [
{
"Name": "John",
"phone": "test"
}
]
"SomethingElse": [
{
"Name": "Smith",
"phone": "test"
}
]
}
}
Problem is that i don't know what wold be next array name. It is possible to parse data from all arrays without name of it and without changing structure of it?
Thanks.

JSON
{
"data": {
"current_condition": [
{
"cloudcover": "25",
"humidity": "62",
"observation_time": "04:57 PM",
"precipMM": "0.1",
"pressure": "1025",
"temp_C": "10",
"temp_F": "50",
"visibility": "10",
"weatherCode": "113",
"weatherDesc": [
{
"value": "Clear"
}
]
}
]
}
}
TO GET THE VALUE OF "weatherDesc"
private class DownloadJSON extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a progressdialog
mProgressDialog = new ProgressDialog(MainActivity.this);
// Set progressdialog title
mProgressDialog.setTitle("Android JSON Parse Tutorial");
// Set progressdialog message
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// Create an array
arraylist = new ArrayList<HashMap<String, String>>();
// Retrieve JSON Objects from the given URL address
jsonobject = JSONfunctions
.getJSONfromURL("http://api.worldweatheronline.com/free/v1/weather.ashx?q=London&format=json&num_of_days=5&key=8mqumbup9fub7bcjtsxbzxx9");
try {
// Locate the array name in JSON
JSONObject on=jsonobject.getJSONObject("data");
jsonarray = on.getJSONArray("current_condition");
for (int i = 0; i < jsonarray.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
jsonobject = jsonarray.getJSONObject(i);
JSONArray sen1=jsonobject.getJSONArray("weatherDesc");
// Retrive JSON Objects
for(int j=0;j<sen1.length();j++){
jsonobject2 = sen1.getJSONObject(j);
map.put("value0", jsonobject2.getString("value"));
map.put("value1",jsonobject2.getString("value"));
map.put("flag", null);
// Set the JSON Objects into the array
arraylist.add(map);
}
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
// Locate the listview in listview_main.xml
listview = (ListView) findViewById(R.id.listview);
// Pass the results into ListViewAdapter.java
adapter = new ListViewAdapter(MainActivity.this, arraylist);
// Set the adapter to the ListView
listview.setAdapter(adapter);
// Close the progressdialog
mProgressDialog.dismiss();
}
}

try this
I had write a function to iterate JsonObject recursively without knowing keys name.
private void parseJson(JSONObject data) {
if (data != null) {
Iterator<String> it = data.keys();
while (it.hasNext()) {
String key = it.next();
try {
if (data.get(key) instanceof JSONArray) {
JSONArray arry = data.getJSONArray(key);
int size = arry.length();
for (int i = 0; i < size; i++) {
parseJson(arry.getJSONObject(i));
}
} else if (data.get(key) instanceof JSONObject) {
parseJson(data.getJSONObject(key));
} else {
System.out.println("" + key + " : " + data.optString(key));
}
} catch (Throwable e) {
System.out.println("" + key + " : " + data.optString(key));
e.printStackTrace();
}
}
}
}

There is a comma missing in your JSON after the Something value, but apart from that, you can parse it using any JSON parser.

Related

no value for a JSON key

i'm trying to parse this json
{
"data": [
{ "name": "4th Floor",
"is_broken": true,
"is_repaired": false,
"is_ok": false,
"asset_parent": {
"name": "Buni Building",
"is_broken": true,
"is_repaired": false,
"is_ok": false
}
}
]
}
with this code
class daftarAset extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Sedang menampilkan...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
String link_url = "https://example.com/api/assets";
HttpHandler sh = new HttpHandler();
String json = sh.makeServiceCall(link_url);
Log.e(TAG, "Response from url: " + json);
if (json != null) {
try {
JSONObject jsonObject = new JSONObject();
JSONArray data = jsonObject.getJSONArray("data");
for (int i = 0; i < data.length(); i++) {
JSONObject ar = data.getJSONObject(i);
String aset = ar.getString("name");
JSONObject parent = ar.getJSONObject("asset_parent");
String nama = parent.getString("name");
HashMap map = new HashMap();
map.put(in_aset, aset);
map.put(in_ruang, nama);
data_map.add(map);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getActivity().getApplicationContext(),
"Json parsing error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
});
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
list = (ListView) getView().findViewById(R.id.baik_list);
adapter = new AssetsAdapter(getActivity(), data_map);
list.setAdapter(adapter);
setListViewHeightBasedOnChildren(list);
}
});
}
return null;
}
#Override
protected void onPostExecute(String s) {
pDialog.dismiss();
}
and it says error that no value for data. i dont know why the data said no value where i already call it before with JSONArray. it must be nothing to do with the listview where i have to put the value.
please help why it says has no value for data but it actualy has
You're getting error because you aren't passing the json string to your json object.
it should be
JSONObject jsonObject = new JSONObject(json);
instead of
JSONObject jsonObject = new JSONObject(); //json is missing here

Android: Best practice for handling JSON data

I've been researching how to query JSON data from a server and parse it for use in my application. However, I've found a number of different ways to do the same thing. I realize there are different JSON parsers out there, so let's assume I'm sticking with the standard one. The main question I have has to do with the server requests. Here is my current code for my MapActivity
private class DownloadJSON extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Create a Progress Dialog
mProgressDialog = new ProgressDialog(MapActivity.this);
mProgressDialog.setTitle("Downloading Data");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// Create an array
arraylist = new ArrayList<HashMap<String, String>>();
try {
// Retrieve JSON Objects from the given URL address
jsonarray = JSONFunctions.getJSONfromURL("myurl");
for (int i = 0; i < jsonarray.length(); i++) {
HashMap<String, String> map = new HashMap<String, String>();
JSONObject obj = jsonarray.getJSONObject(i);
// Retrieve JSON Objects
map.put("id", String.valueOf(i));
map.put("name", obj.getString("name"));
// Set the JSON Objects into the array
arraylist.add(map);
}
} catch (JSONException e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
// Do something with data
mProgressDialog.dismiss();
}
}
If the structure of my JSON data looks weird, it's because it's stored in an unnamed array so I don't have to create an object first. Anyway... I essentially based this off of this tutorial. However, they have soooo much more code. Is that all really necessary? I didn't think so. I searched around more and found other examples that used half the code and essentially did the same thing. So my question, as a beginning Android programmer, is what is the best practice for handling JSON data? Thanks!
Example of JSON file:
[
{
"name": "test",
"lat": "42.01108",
"long": "93.679196"
},
{
"name": "test",
"lat": "42.01108",
"long": "93.679196"
}
]
Try this...
private class TestJSONParsing extends AsyncTask<JSONArray, Void, JSONArray>
{
ArrayList<HashMap<String, String>> arraylist;
HashMap<String, String> map;
#Override
protected void onPreExecute()
{
super.onPreExecute();
mProgressDialog = new ProgressDialog(MapActivity.this);
mProgressDialog.setTitle("Downloading Data");
mProgressDialog.setMessage("Loading...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.show();
}
#Override
protected JSONArray doInBackground(JSONArray... params)
{
return JSONFunctions.getJSONfromURL("myurl");
}
#Override
protected void onPostExecute(JSONArray resultArray)
{
super.onPostExecute(resultArray);
mProgressDialog.dismiss();
if (null != resultArray)
{
int resultLength = resultArray.length();
if (resultLength > 0)
{
try
{
for (int i = 0; i < resultLength; i++)
{
JSONObject jsonObject = resultArray
.getJSONObject(i);
map.put("id", String.valueOf(i));
map.put("name", jsonObject.getString("name"));
arraylist.add(map);
}
} catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
}
if (arraylist.size() > 0)
{
SimpleAdapter adapter = new SimpleAdapter(
MapActivity.this, arraylist,
R.layout.your_simple_row, new String[]
{ "id", "name" }, new int[]
{ R.id.nameId, R.id.name });
// bind adapter to your components
listView.setAdapter(adapter);
}
}
} else
{
Toast.makeText(getApplicationContext(), "No data",
Toast.LENGTH_SHORT).show();
}
}
}
#leerob Hello, at one time I found myself in a dilemma where you are, but lately I have used base classes that brings Android to handle json and is pretty good, a good practice I recommend you is to declare constants for the keys of json, I share an example:
public void insertMovieTypeFromJson(String movieTypeJsonStr) throws JSONException {
final String ID = "id";
final String TYPE = "type";
final String DESCRIPTION = "description";
if (movieTypeJsonStr == null)
return;
try {
JSONArray movieTypeArrayJson = new JSONArray(movieTypeJsonStr);
Vector<ContentValues> cVVector = new Vector<>(movieTypeArrayJson.length());
for (int i = 0; i < movieTypeArrayJson.length(); i++) {
long id;
String type;
String description;
JSONObject movie = movieTypeArrayJson.getJSONObject(i);
id = movie.getLong(ID);
type = movie.getString(TYPE);
description = movie.getString(DESCRIPTION);
ContentValues movieTypeValues = new ContentValues();
movieTypeValues.put(MovieContract.MovieTypeEntry._ID, id);
movieTypeValues.put(MovieContract.MovieTypeEntry.COLUMN_TYPE, type);
movieTypeValues.put(MovieContract.MovieTypeEntry.COLUMN_DESCRIPTION, description);
cVVector.add(movieTypeValues);
}
int inserted = 0;
if (cVVector.size() > 0) {
ContentValues[] cvArray = new ContentValues[cVVector.size()];
cVVector.toArray(cvArray);
inserted = getContext().getContentResolver().bulkInsert(MovieContract.MovieTypeEntry.CONTENT_URI, cvArray);
}
Log.d(LOG_TAG, "MovieTask Complete. " + inserted + " MovieType Inserted");
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
}
Json:
[
{
"id": "1",
"type": "Action & Adventure",
"description": "Action & Adventure"
},
{
"id": "2",
"type": "Animation",
"description": "Animation"
},
{
"id": "3",
"type": "Comedy",
"description": "Comedy"
},
{
"id": "4",
"type": "Terror",
"description": "Terror"
}
]

Put data to array from JSON array in android

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]));
}
}

Retrieve json data

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);
}

How to extract json data?

I am getting this trouble?
[
{
"username": "apap",
"status": "",
"log": "",
"email": "apap#gmail.com",
"lat": "",
"dob": "5-11-1986"
},
{
"username": "apapp",
"status": "",
"log": "",
"email": "apapp#gmail.com",
"lat": "",
"dob": "5-11-1986"
}
],
"returncode": "0"
}
Error parsing data org.json.JSONException: Value {"incircle": at response of type org.json.JSONObject cannot be converted to JSONArray
For extracting incircle array value,I am writing following code:
public class MainActivity extends Activity {
TextView username;
TextView email;
TextView dob;
TextView lat;
TextView log;
ListView listView;
ArrayList<HashMap<String,String>> jsonlist;
JsonAdapter objAdapter;
Context ctx;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.listView);
jsonlist = new ArrayList<HashMap<String,String>>();
JSONObject json = JSONfunctions
.getJSONfromURL("http://www.railsboxtech.com/flirtalert/alluser.php");
try {
JSONArray flirt = json.getJSONArray("response");
Toast.makeText(MainActivity.this, "namr", Toast.LENGTH_LONG).show();
for (int i = 0; i < flirt.length(); i++) {
JSONObject ei = flirt.getJSONObject(i);
JSONArray eie = ei.getJSONArray("incircle");
for (int j = 0; j < eie.length(); j++) {
JSONObject e = eie.getJSONObject(j);
HashMap<String, String> map = new HashMap<String, String>();
map.put("User",e.getString("username"));
map.put("Email",e.getString("email"));
map.put("dob",e.getString("dob"));
map.put("lat",e.getString("lat"));
map.put("log",e.getString("log"));
jsonlist.add(map);
}
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
ListAdapter adapter = new SimpleAdapter(this, jsonlist, R.layout.user_list,
new String[] { "User", "Email","dob","lat","log"}, new int[] {
R.id.username, R.id.email, R.id.dob, R.id.lat, R.id.log});
listView.setAdapter(adapter);
listView.setTextFilterEnabled(true);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
When you retrieve the elements of the array with this line
JSONArray ja1= eie.getJSONArray(j);
You require the elements to be arrays themselfs, however, in your input the elements are objects.
Since the input has only one array but your code assumes two nested arrays, you probably want something like:
JSONObject json = JSONfunctions
.getJSONfromURL("http://www.railsboxtech.com/flirtalert/alluser.php");
try {
JSONObject ei = json.getJSONObject("response");
JSONArray eie = ei.getJSONArray("incircle");
for (int j = 0; j < eie.length(); j++) {
JSONObject e = eie.getJSONObject(j);
HashMap<String, String> map = new HashMap<String, String>();
map.put("User",e.getString("username"));
map.put("Email",e.getString("email"));
map.put("dob",e.getString("dob"));
map.put("lat",e.getString("lat"));
map.put("log",e.getString("log"));
jsonlist.add(map);
}
} catch ...

Categories

Resources