JSONArray alternative in Android - android

I'm attempting to parse a string that contains an array of JSON objects, but the org.json.JSONArray is not supported until the API 19 (Kit-Kat) operating system. For obvious reasons I need to figure out a way around this. Is there a better alternative to this? Or am I using this method incorrectly?
Here is the code that keeps telling me I need API 19 or higher:
protected void onPostExecute(JSONArray result) {
pDialog.dismiss();
try {
// Getting JSON Array from URL
info = new JSONArray(result);
for(int i = 0; i < info.length(); i++){
JSONObject c = info.getJSONObject(i);
// Storing JSON item in a Variable
String title = c.getString(TAG_TITLE);
String article = c.getString(TAG_ARTICLE);
String timestamp = c.getString(TAG_TIMESTAMP);
String datestring = c.getString(TAG_DATESTRING);
// Adding value HashMap key => value
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_TITLE, title);
map.put(TAG_ARTICLE, article);
map.put(TAG_TIMESTAMP, timestamp);
map.put(TAG_DATESTRING, datestring);
oslist.add(map);
list=(ListView)findViewById(R.id.list);
ListAdapter adapter = new SimpleAdapter(MainActivity.this, oslist,
R.layout.list_v,
new String[] { TAG_TITLE,TAG_ARTICLE, TAG_TIMESTAMP,TAG_DATESTRING }, new int[] {
R.id.title,R.id.article, R.id.timestamp,R.id.date_string});
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(MainActivity.this, "You Clicked at "+oslist.get(+position).get("name"), Toast.LENGTH_SHORT).show();
}
});
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
btw I am using an AsyncTask to put the information into a ListView. I have another class to fetch the result of the webpage. Thanks!

The new API 19 function you are using is:
info = new JSONArray(result);
Since result is already an JSONArray, why do you need to create another?

Dude try this framework is much better
https://code.google.com/p/google-gson/
or
http://www.javacodegeeks.com/2011/01/android-json-parsing-gson-tutorial.html

Here is a solution under 19API lvl:
First of all. Make a Gson obj. --> Gson gson = new Gson();
Second step is get your jsonObj as String with StringRequest(instead of JsonObjectRequest)
The last step to get JsonArray...
YoursObjArray[] yoursObjArray = gson.fromJson(response, YoursObjArray[].class);

Related

Parsing JSON object using jackson

I am usin android built in parser but it is very slow. I want to use jackson but i am not able to understand hoe to perform same things with jackson as i did with android built it parser.
here is my code
String data = getArguments().getString("data");
String RECCO_INFO = null;
try {
RECCO_INFO = getReccos(data);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JSONArray RECCO_ARRAY = new JSONArray();
try {
RECCO_ARRAY = new JSONArray(RECCO_INFO);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for(int i = 0; i < RECCO_ARRAY.length(); i++) {
try {
JSONObject recco = RECCO_ARRAY.getJSONObject(i);
String program = recco.getString("program");
String outlet = recco.getString("outlet");
String normalized_weight = recco.getString("normalized_weight");
String distance = recco.getString("distance");
HashMap<String, String> map = new HashMap<String, String>();
String program_name = new JSONObject(program).getString("name");
String outlet_basics = new JSONObject(outlet).getString("basics");
String outlet_name = new JSONObject(outlet_basics).getString("name");
map.put("program_name", program_name);
map.put("outlet_name", outlet_name);
map.put("normalized_weight", normalized_weight);
map.put("distance", distance);
oslist.add(map);
list= (ListView) rootView.findViewById(R.id.recco_list);
ListAdapter adapter = new SimpleAdapter(getActivity(), oslist,
R.layout.recco_list_view, new String[] {"program_name","outlet_name", "normalized_weight", "distance"},
new int[]{R.id.program_name,R.id.outlet_name, R.id.normalized_weight, R.id.distance});
list.setAdapter(adapter);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return rootView;
}
public String getReccos (String data) throws JSONException {
JSONObject json = new JSONObject(data);
JSONObject info = json.getJSONObject("info");
JSONObject RECCO = info.getJSONObject("RECCO");
JSONArray RECCO_INFO = RECCO.getJSONArray("info");
return RECCO_INFO.toString(1);
}
Please anybody help me usin jackson, i have already downloaded jars. i have tried it seeing some examples but i am able to fully understand it.
Create Getters and Setters for all the key in json.
Create an instance of ObjectMapper.
Configure the object mappers.
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
objectMapper.setSerializationInclusion(Include.NON_NULL);
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
pass the response and class.
GetDetails mDetails = objectMapper.readValue(response, GetDetails.class)
Starting getting the values.
Here is a simple example for the OP's JSON. If you can post your JSON, I can post the code to parse and get all values.
Here is one more example.
The main problem here is not the JSON parsing but these lines:
for(....){
list= (ListView) rootView.findViewById(R.id.recco_list);
ListAdapter adapter = new SimpleAdapter(getActivity(), oslist,
R.layout.recco_list_view, new String[] {"program_name","outlet_name", "normalized_weight", "distance"},
new int[]{R.id.program_name,R.id.outlet_name, R.id.normalized_weight, R.id.distance});
list.setAdapter(adapter);
}
They are heavily unoptimised. All of this should be done outside the list, because you are creating/inflating them many many times. If you want the effect that items appear one by one, use adapter.notifyDataSetChanged method. Move them out and you will notice that performance improved many times.
Well answering my own question.
I am using Gson to deserialise json into java POJO. it is quite simple and easy.
This link will help.

Android Listview multiple select

I know there are lots of tutorials and solutions regarding android listview multiple select. But I am getting trouble on finding the correct solution on my kind of implementation.
I have listview from json object which is shown below. I have a question regarding the implementation of multiple select on following implementation. The following is the class, that extends Asynctask. Now I want to implement multiple select in it. To be straight multiple select to delete multiple items. How could I adopt my code.
I know There are lots of implementation but I am at the end of my project and I have implemented all my list views like following and changing all is now not possible for me.
Thanks in advance
#Override
protected JSONObject doInBackground(String... args) {
user = db.getUserDetails();
UserFunctions userFunction = new UserFunctions();
JSONObject json = userFunction.getSiteList(user.get("uid"), user.get("uauth"));
return json;
}
#Override
protected void onPostExecute(JSONObject json) {
try {
if(json.has("error_msg")){
pDialog.dismiss();
String err = json.getString("error_msg");
site_error.setText(err);
site_error.setVisibility(View.VISIBLE);
//Toast.makeText(getApplicationContext(), "Dont have any Location", Toast.LENGTH_LONG).show();
}else{
pDialog.dismiss();
// Now since we dont have any error lets put this in the list view.
site = json.getJSONArray(TAG_SITE);
for(int i = 0; i < site.length(); i++){
JSONObject c = site.getJSONObject(i);
//put json obkject on variable
String id = c.getString(TAG_ID);
String location = c.getString(TAG_LOCATION);
// Adding value HashMap key => value
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_ID, id);
map.put(TAG_LOCATION, location);
sitelist.add(map);
// Finding the list view
list=(ListView)findViewById(R.id.sitelist);
// Put data on listview content
ListAdapter adapter = new SimpleAdapter(SitePage.this, sitelist,
R.layout.site_list,
new String[] {TAG_LOCATION,TAG_ID}, new int[] {
R.id.siteLocation});
list.setAdapter(adapter);
// List View click event
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
/*Open the new activity for single transaction detail*/
Intent intent = new Intent(SitePage.this, AddNewSite.class);
intent.putExtra("site", sitelist.get(+position).get("site_location"));
intent.putExtra("siteid", sitelist.get(+position).get("site_id"));
startActivity(intent);
//Toast.makeText(SitePage.this, "You Clicked at "+sitelist.get(+position).get("site_id"), Toast.LENGTH_SHORT).show();
}
});
}
}
}catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

adapter is null when calling notifyDataSetChanged() onResume()

I have a fragment that contains a listView that i want to be updated whenever a new record is added. Im trying to call .notifyDataSetChanged() in onResume() in fragment but the adapter = null.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_log,
container, false);
exmaplePrefs = this.getActivity().getSharedPreferences(PREFS, 0);
json = exmaplePrefs.getString("jsonString", "cant find json");
JSONObject MainObj = null;
JSONArray JsonArray = null;
try {
MainObj = new JSONObject(json);
JsonArray = MainObj.getJSONArray("Events");
for(int i = 0; i < JsonArray.length(); i++){
JSONObject c = JsonArray.getJSONObject(i);
// Storing JSON item in a Variable
String time = c.getString("time");
String event = c.getString("event");
String player = c.getString("player");
String from[] = {"time","event", "player"};
int to[] = {R.id.time,R.id.event, R.id.player};
// Adding value HashMap key => value
HashMap<String, String> map = new HashMap<String, String>();
map.put("time", time);
map.put("event", event);
map.put("player",player);
newItemlist.add(map);
listV=(ListView)rootView.findViewById(android.R.id.list);
adapter = new SimpleAdapter(getActivity(), newItemlist, R.layout.custom_list_row, from, to);
listV.setAdapter(adapter);
}
} catch (Exception e) {
// TODO: handle exception
System.out.print("ERROR");
}
return rootView;
}
#Override
public void onResume(){
super.onResume();
System.out.println("worked");
if (adapter != null){
adapter.notifyDataSetChanged();
}
}
I think this is something to do with the adapter being created onCreateView() and is not visible when I return to the Fragment.
Looking at this, I see a few problems.
It's generally very poor practice to catch ( Exception ex). Try catching only the specific Exceptions you are worried about, it makes fixing problems easier.
Why is your ArrayAdapter created inside of a for loop? You probably wand something like this:
ArrayList list=new ArrayList(); //Specify what type of value is in the ArrayAdapter
adapter = new SimpleAdapter(getActivity(), newItemlist, R.layout.custom_list_row,list);
listV.setAdapter(adapter);
MainObj = new JSONObject(json);
JsonArray = MainObj.getJSONArray("Events");
for(int i = 0; i < JsonArray.length(); i++){
JSONObject c = JsonArray.getJSONObject(i);
// Storing JSON item in a Variable
String time = c.getString("time");
String event = c.getString("event");
String player = c.getString("player");
String from[] = {"time","event", "player"};
int to[] = {R.id.time,R.id.event, R.id.player};
// Adding value HashMap key => value
HashMap<String, String> map = new HashMap<String, String>();
map.put("time", time);
map.put("event", event);
map.put("player",player);
newItemlist.add(map);
listV=(ListView)rootView.findViewById(android.R.id.list);
adapter.add(map);
}
I'm not quite sure what SimpleArrayAdapter is, but you want to create a new one once outside of the loop, and add things to it inside of the loop most likely, re-creating it seems like a poor choice. You'll probably need to do some playing with the adapter.add(map) command in particular, but this general pattern should help. You'll also need to change the ArrayList list to something like ArrayList<String> list=new ArrayList<String>(), to whatever your ArrayAdapter is storing (Looks like HashMap<String,String>)
If an Exception is thrown, you will directly move to the catch block, hence skipping adapter's initialization. This probably means that there is an error parsing your JSON string.

Call JSON on Spinner OnItemSelected and display data into another Spinner

I am making an android app in which I am using two spinners. In first spinner I am displaying data from JSON which I've done successfully. Now by clicking an item of first spinner I need to display data from another JSON service into second spinner.
First Service (I am displaying city_name from this service on first spinner):
{"result":{"data":[{"city_id":"16","city_name":"\u00c4ngelholm"},
{"city_id":"23","city_name":"B\u00e5stad"},
{"city_id":"22","city_name":"Halmstad"},
{"city_id":"19","city_name":"H\u00f6gan\u00e4s"},{"city_id":"20","city_name":"Helsingborg"},
{"city_id":"15","city_name":"Klippan"},
{"city_id":"24","city_name":"Kungsbacka"},
{"city_id":"21","city_name":"Laholm"},{"city_id":"18","city_name":"Landskrona"}],
"status":"true","description":""}}
Second Service:
{"result":{"data":[{"category_id":"18","category":"Aff\u00e4rsverksamhet",
"city_id":"16","city_name":"\u00c4ngelholm"},{"category_id":"19","category":"\u00d6vrigt",
"city_id":"16","city_name":"\u00c4ngelholm"},{"category_id":"13","category":"Bostad",
"city_id":"16","city_name":"\u00c4ngelholm"},{"category_id":"15","category":"Elektronik",
"city_id":"16","city_name":"\u00c4ngelholm"},{"category_id":"12","category":"F\u00f6r hemmet","city_id":"16","city_name":"\u00c4ngelholm"},{"category_id":"11","category":"Fordon",
"city_id":"16","city_name":"\u00c4ngelholm"},
{"category_id":"16","category":"Fritid & Hobby",
"city_id":"16","city_name":"\u00c4ngelholm"}],
"status":"true","description":""}}
As you can see in both services city_id and city_name are common fields. If I select city_name from first spinner it will match through city_id or city_name and display category against that city_name.
Below is my code I have tried.
private class AllCities extends AsyncTask<String, String, JSONObject>
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected JSONObject doInBackground(String... params)
{
try
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("url of First Service");
HttpResponse resp = client.execute(post);
HttpEntity entity = resp.getEntity();
String response = EntityUtils.toString(entity);
return new JSONObject(response);
}
catch(Exception ex)
{
ex.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(JSONObject result)
{
super.onPostExecute(result);
if(result != null)
{
myList = new ArrayList<HashMap<String,String>>();
if(! result.has("false"))
{
try
{
JSONObject object = result.getJSONObject("result");
JSONArray array = object.getJSONArray("data");
stringArray = new ArrayList<String>();
for(int i=0; i<array.length(); i++)
{
HashMap<String, String> map = new HashMap<String, String>();
map.put("city_id", array.getJSONObject(i).getString("city_id"));
map.put("city_name", array.getJSONObject(i).getString("city_name"));
myList.add(map);
stringArray.add(array.getJSONObject(i).getString("city_name"));
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(PostAdds.this,
android.R.layout.simple_spinner_item, stringArray);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_city.setAdapter(adapter);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
else if(result == null)
{
Toast.makeText(PostAdds.this,
"Hittade inga Detaljer Vänligen Kontrollera din Internet-anslutning",
Toast.LENGTH_LONG).show();
}
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
{
//what am I suppose to do here????
}
#Override
public void onNothingSelected(AdapterView<?> parent)
{
}
Sorry about the late answer. I was solved this by my self but never came back here to post the solution which worked for me. Now I am posting this answer if any one has same kind of problem can get help from here.
So What I did
1) Call the first service and populate city names on first spinner and when item is selected of first spinner, save its value in a global String like
String selectedCity;
selectedCity = spinner1.getSelectedItem().toString();
2) When click any item of first spinner call the second service and put a simple check while populating the second spinner.
ArrayList<String> categories = new ArrayList<String>();
try {
JSONObject object = result.getJSONObject("result");
JSONArray array = object.getJSONArray("data");
for(int a = 0; a < array.length(); a++) {
String cityName = array.getJSONObject(a).getString("city_name");
if(cityName.equals(selectedCity)) // this check is important
{
categories.add(cityName );
}
}
// after for loop ends populate adapter of second spinner
ArrayAdapter<String> adapt = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, categories);
spinner2.setAdapter(adapt);
}
catch(Exception e) {
e.printStackTrace();
}
In this way I got my desired result. There are other solutions of this problem as well like one of them is when you call second service pass city_id or city_name along with url as params and service will only return you the desired categories.
Hope this will solve for any one has similar kind of problem. I just check my Stackoverflow profile today and found this question has not answered by any one so I did it my self :)

How to parse JSON data to Android?

I have followed a tutorial online and tweaked some of the code, I would like the application to read information from a different location. Currently the app is correctly reading the data from here. Now I would like to read data from here. I'm looking to attain Observation Time, Temp_C & Visibility, I imagine I would need to change my code within the try { bracket in order to read this data? Any suggestions?
public class MainActivity extends ListActivity {
// url to make request
private static String url = "http://api.androidhive.info/contacts/";
// JSON Node names
private static final String TAG_DATA = "contacts";
private static final String TAG_OBSERV = "name";
private static final String TAG_TEMP = "email";
private static final String TAG_VISIB = "gender";
// contacts JSONArray
JSONArray contacts = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
// Creating JSON Parser instance
JSONParse jParser = new JSONParse();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
// Getting Array of Contacts
contacts = json.getJSONArray(TAG_DATA);
// looping through All Contacts
for(int i = 0; i < contacts.length(); i++){
JSONObject c = contacts.getJSONObject(i);
// Storing each json item in variable
String name = c.getString(TAG_OBSERV);
String email = c.getString(TAG_TEMP);
String gender = c.getString(TAG_VISIB);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_OBSERV, name);
map.put(TAG_TEMP, email);
map.put(TAG_VISIB, gender);
// adding HashList to ArrayList
contactList.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
// Updating parsed JSON data into ListView
ListAdapter adapter = new SimpleAdapter(this, contactList,
R.layout.list_item,
new String[] { TAG_OBSERV, TAG_TEMP, TAG_VISIB }, new int[] {
R.id.name, R.id.email, R.id.mobile });
setListAdapter(adapter);
// selecting single ListView item
ListView lv = getListView();
// Launching new screen on Selecting Single ListItem
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
String cost = ((TextView) view.findViewById(R.id.email)).getText().toString();
String description = ((TextView) view.findViewById(R.id.mobile)).getText().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
in.putExtra(TAG_OBSERV, name);
in.putExtra(TAG_TEMP, cost);
in.putExtra(TAG_VISIB, description);
startActivity(in);
}
});
}
}
How to parse JSON data to Android?
So at first you should move your code where you are attempt to perfrom network connection(fetching data from JSON) to background Thread. Actually you're doing it at Main(UI) Thread and it's not very good and correct. If your app will be installed on a device that runs on Android 3.0+ you will get NetworkOnMainThreadException and it's not nice, ins't?
Second, save your JSON and make some formatting to see its structure better. Multiset bracket { indicates JSONObject and bracket [ indicated JSONArray.
Now you should be able to parse JSON. Now i write you a little snippet of code how to start:
JSONObject o = new JSONObject(sourceString);
if (o != null) {
JSONObject data = o.getJSONObject("data"); // getting JSONObject with key data
if (data != null) {
JSONArray current = data.getJSONArray("current_condition");
}
}
...
The easiest and prettiest way would be to create a DTO with the wanted properties and then use a library such as Jackson or Gson to map the JSON to object(s). Then it would be 2 lines of code instead of that 'manual parsing'.
Here is the way you should parse and get your values from that json :
JSONObject mMainObject = new JSONObject(myResponseString);
if(mMainObject != null){
JSONObject data = mMainObject.getJSONObject("data");
if(data != null){
JSONArray currentCondition = data.getJSONArray("current_condition");
if(currentCondition != null){
for(int i = 0; i < currentCondition.lenght(); i++){
JSONObject obj = currentCondition.get(i);
if(obj != null){
String observation_time = obj.getString("observation_time");
String temp_C = obj.getString("temp_C");
String visibility = obj.getString("visibility");
}
}
}
}
}
Doing that you should consider the proper way to download the data from internet using AsyncTask for example. In this way it will not block your UI and your app will be more responsive.
Hope this help! : )

Categories

Resources