Im making an app for a site, and i need some help making an for statement. I parse the JSON from the API (Server) and catch it, this is working, however i want it to show in a ListView, i've made my adapter and all that, which is working. Now when i launch the app only one line in the listview shows. So i have no idea on how to get all the values into the listview.
My Activity:
public class FilesActivity extends SherlockActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dblist);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("Files");
String response = null;
DefaultHttpClient httpClient = new DefaultHttpClient();
ResponseHandler <String> resonseHandler = new BasicResponseHandler();
HttpPost postMethod = new HttpPost("http://api.bayfiles.net/v1/account/files?session=<SessionId>");
try {
JSONObject json = new JSONObject();
postMethod.setEntity(new ByteArrayEntity(json.toString().getBytes("UTF8")));
postMethod.setHeader( "Content-Type", "application/json" );
response = httpClient.execute(postMethod,resonseHandler);
JSONObject request = new JSONObject(response);
for (Iterator<?> keyIterator = request.keys(); keyIterator.hasNext(); ) {
String key = (String) keyIterator.next();
JSONObject object = request.optJSONObject(key);
ArrayList<fileObject> objectList = new ArrayList<fileObject>();
//ArrayList<fileObject> results = new ArrayList<fileObject>();
if (object != null) {
fileObject obj = new fileObject();
obj.setFileId(key);
obj.setFileName(object.getString("filename"));
obj.setSize(object.getString("size"));
obj.setInfoToken(object.getString("infoToken"));
obj.setDeleteToken(object.getString("deleteToken"));
obj.setSha1(object.getString("sha1"));
objectList.add(obj);
Log.d("log_tag", object.getString("filename"));
}
final ListView lv1 = (ListView) findViewById(R.id.listobjects);
lv1.setAdapter(new MyCustomBaseAdapter(this, objectList));
lv1.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = lv1.getItemAtPosition(position);
fileObject fullObject = (fileObject)o;
Toast.makeText(FilesActivity.this, "You have chosen: " + " " + fullObject.getFileName(), Toast.LENGTH_LONG).show();
}
});
}
}
catch(Exception e)
{
e.printStackTrace();
Log.d("log_tag", "Error: " + e.toString());
}
}
}
And the adapter and fileObject are just standard, how can i make my listview show all the values?
You are creating a new ArrayListenter code here and a new MyCustomBaseAdapter in every loop iteration. Move that outside of your loop and it will show all the items.
See this: Populating a ListView using an ArrayList?
You're re-creating the arraylist every cycle through the loop. It's only ever going to have one item in it. Just create the ArrayList prior to the for-loop, and populate it inside the loop. Then after you've done that add the whole arraylist to the listview. No need to do it every single cycle. Should look like:
ArrayList<fileObject> objectList = new ArrayList<fileObject>();
for (Iterator<?> keyIterator = request.keys(); keyIterator.hasNext(); ) {
String key = (String) keyIterator.next();
JSONObject object = request.optJSONObject(key);
//ArrayList<fileObject> results = new ArrayList<fileObject>();
if (object != null) {
fileObject obj = new fileObject();
obj.setFileId(key);
obj.setFileName(object.getString("filename"));
obj.setSize(object.getString("size"));
obj.setInfoToken(object.getString("infoToken"));
obj.setDeleteToken(object.getString("deleteToken"));
obj.setSha1(object.getString("sha1"));
objectList.add(obj);
Log.d("log_tag", object.getString("filename"));
}
}//end the for-loop right here. No need to do that other stuff over and over.
Related
I am loading some json into a list view and want to delete items from the list on click and for the item to be deleted from the json. The delete functionality seems to be working. The method delete is called, the items are removed on click and debugging shows the item being removed. However after going to another activity and viewing the list again, the deleted items come back. what am i doing wrong? This is my class:
public class edit extends AppCompatActivity
{
public ListView pizzaList;
ListView addicList;
ArrayAdapter<String> arrayAdapter;
String appreciations;
String currentPizza;
ArrayList<String> list = new ArrayList<String>();
private String name;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_activity);
pizzaList = (ListView) findViewById(R.id.pizzas);
registerForContextMenu(pizzaList);
arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
pizzaList.setAdapter(arrayAdapter);
pizzaList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
delete(view,position);
arrayAdapter.notifyDataSetChanged();
}
});
try {
FileManager fileManager = new FileManager();
String str = fileManager.ReadFile(this);
if (str != null) {
JSONArray jarray = new JSONArray(str);
String outputText = "";
for (int i = 0; i < jarray.length(); i++) {
JSONObject jsonObject = jarray.getJSONObject(i);
String pizzaName = jsonObject.getString("name");
int price = jsonObject.getInt("price");
outputText = outputText + " " + pizzaName + " " + " $" + price + "\n";
appreciations = outputText;
list.add(appreciations);
arrayAdapter.notifyDataSetChanged();
outputText = "";
}
} else {
Toast to = Toast.makeText(getApplicationContext(), "No saved Pizzas", Toast.LENGTH_LONG);
to.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void delete(View view, int pos)
{
try {
FileManager fileManager = new FileManager();
String str = fileManager.ReadFile(this);
if (str != null)
{
JSONArray jarray = new JSONArray(str);
JSONObject jsonObject = jarray.getJSONObject(pos);
jarray.remove(pos);
list.remove(pos);
arrayAdapter.notifyDataSetChanged();
JSONArray jsArray = new JSONArray(jarray);
arrayAdapter.notifyDataSetChanged();
} else {
Toast to = Toast.makeText(getApplicationContext(), "No saved Pizzas", Toast.LENGTH_LONG);
to.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
You would need to remove the item from the database, use asynchronous request such as volley or robospice for it. Then instead of making the request when coming back you would use the data stored on the cache the second time and only make the request again when data has been changed. You can create your cache logic in your application class to make it visible throughout your app.
I have a custom base adapter that extracts new data from the database on Button Click, it works however the old data is discarded and I would like to keep it and append the new data to it. I was looking over this example how to append latest data to custom base adapter list view in android? and it seems incomplete, for instance how can I append the new data to the old one without creating a new object.
This is the area of my code that I am struggling with
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
CustomView CV;
try {
ListView lv = (ListView) m.findViewById(R.id.mylistview);
JSONObject jsonn = new JSONObject(result);
JSONArray jArray = jsonn.getJSONArray("myarray");
JSONObject jobject = null;
JSONArray sss = new JSONArray();
for (int i = 0; i < jArray.length(); i++) {
jobject = jArray.getJSONObject(i);
jobject.getString("message");
sss.put(jobject);
}
jsonn.put("myarray", sss);
if(data==1)
{
CV = new CustomView(jsonn, m);
DMF.notifyDataSetChanged();
lv.setAdapter(CV);
}
else
{
// New data should be appended here
CV = new CustomView(jsonn, m);
DMF.notifyDataSetChanged();
lv.setAdapter(CV);
}
} catch (Exception e) {
Log.e("JSONException", "Error: " + e.toString());
System.err.println();
}
}
I can not figure out how to append the new data and not create a new object. The data integer will equal 1 on first pass and 2 on the other pass. I as stated before can not seem to figure how to append like on what this post is stating
how to append latest data to custom base adapter list view in android?
This is my
I want to parse it but i am getting no value for theater how can i solve this problem?
My code is:
CustomizedListView.java
public class CustomizedListView extends Activity {
// All static variables
static final String URL ="";
// XML node keys
JSONArray theaters = null;
JSONObject json = null;
ListView list;
LazyAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<HashMap<String, String>> songsList = new ArrayList<HashMap<String, String>>();
json=new JSONObject();
try {
// Getting Array of Contacts
theaters = json.getJSONArray(KEY_SONG);
// looping through All Contacts
for(int i = 0; i < theaters.length(); i++){
JSONObject c = theaters.getJSONObject(i);
// Storing each json item in variable
String name = c.getString(KEY_TITLE);
String distance = c.getString(KEY_DURATION);
String pincode = c.getString(KEY_ARTIST);
//String image = c.getString(TAG_MOVIEIMAGE);
// Phone number is agin JSON Object
// creating new HashMap
HashMap<String, String> map1 = new HashMap<String, String>();
// adding each child node to HashMap key => value
map1.put(KEY_TITLE,distance);
map1.put(KEY_DURATION,pincode);
map1.put(KEY_ARTIST,name);
//map.put(TAG_MOVIEIMAGE, image);
// adding HashList to ArrayList
songsList.add(map1);
}
} catch (JSONException e) {
e.printStackTrace();
System.out.println("this is error" +e);
}
// adding HashList to ArrayList
list=(ListView)findViewById(R.id.list);
// Getting adapter by passing xml data ArrayList
adapter=new LazyAdapter(this, songsList);
list.setAdapter(adapter);
// Click event for single list row
list.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
}
});
}
}
I want to parse it but i am getting no value for theater how can i solve this problem?
My code is:I want to parse it but i am getting no value for theater how can i solve this problem?
My code is:
pl help me to resolve error..
You are not assigning any value to the json object, you have to do it in Async Task to fetch the feed from your service.
As #Abed El Majeed K has already said, you need to do it as an async task.
i've found that any downloading, or internet actions are required to be preformed on a separate thread & not on the MainUI.
An example:
public class task extends AsyncTask<String, Void, String>{
private StringBuilder inputStreamToString(InputStream is){
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedRead rd = new Buffer3edReader(new InputStreamReader(is));
while((rLine = rd.readLine()) != null){
answer.append(rLine);
}
return answer;
}
protected String doInBackground(String... param){
String uRL = "http://example.com";
URL url = new URL(uRL);
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
HttpResponse response = httpclient.execute(httppost);
String jsonResult = inputStreamToString(response.getEntity().getContent()).toString();
return jsonResult;
}
protected void onPostExecute(String result){
JSONObject jsonResponse = new JSONObject(result);
JSONArray jsonNode = jsonResponse.getJSONArray(whatever_your_json_stream_is_called);
for(int i = 0; i < jsonMainNode.length(); i++){
JSONObject jsonchild = jsonNode.getJSONObject(i);
String some_value = jsonchild.getString(some_key);
...
}
}
}
by running requests on AsyncTask, you are not causing the MainUiThread to pause, or wait for the download to complete.
With that said, the JSON source you are using is incorrect.
JSON structure is like this:
{"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]}
here might help: http://json.org/
Using JSON I have trimmed the URL of an online gallery and filled an array list with the image sources, or image URLs.
I now want to return the ArrayList back to the MainActivity so that I can then convert the ArrayList to an Array and use that Array of Image URLs to download the images and put them in a gridview.
My problem is that I am not returning the ArrayList from the AsyncTask to the MainActivity. Any pointers would be greatly appreciated.
Thanks for your time.
Main Activity:
public class MainActivity extends Activity {
public static ArrayList<String> list = new ArrayList<String>();
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new myAsyncTask().execute(list);
Log.v("jknfsda: ",list.get(1));
//TextView line1 = (TextView) findViewById(R.id.line1);
//for(int i=0; i<list.size(); i++){
// line1.append(i+1 + ": " + list.get(i));
}
}
AsyncTask:
public class myAsyncTask extends AsyncTask<ArrayList<String>, Void, ArrayList<String>> {
static String quellaGalleryInfo = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22http%3A%2F%2Fwww.quellabicycle.com%2Fgallery%22&format=json&callback=";
public static ArrayList<String> urlArr = new ArrayList<String>();
#Override
protected ArrayList<String> doInBackground(ArrayList<String>... list) {
DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost(quellaGalleryInfo);
httppost.setHeader("Content-type", "application/json");
InputStream inputStream = null;
String result = null; // Hold all of the data from the URL
try{
HttpResponse response = httpclient.execute(httppost); //Response from webservice (may or may not get)
HttpEntity entity = response.getEntity(); // all the content from the requested URL along with headers etc.
inputStream = entity.getContent(); // get maincontent from URL
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"),8);// Read all data from inputStream until buffer is full
StringBuilder theStringBuilder = new StringBuilder();//Store all the data
String line = null;
while((line = reader.readLine())!=null){
theStringBuilder.append(line + "\n");
}
//read all the data from the buffer until nothing is left
result = theStringBuilder.toString(); // everything now inside result
}
catch (Exception e){
e.printStackTrace();
}
finally { //close inputstream
try{
if(inputStream !=null) inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
JSONObject jsonObject;
try{
Log.v("JSONParser Result: ", result);
jsonObject = new JSONObject(result);//object of all the data
JSONObject queryJSONObject = jsonObject.getJSONObject("query");//get query objects
JSONObject resultsJSONObject = queryJSONObject.getJSONObject("results");//get results object inside of query object
JSONObject bodyJSONObject = resultsJSONObject.getJSONObject("body");
JSONArray divJSONArray = bodyJSONObject.getJSONArray("div");
JSONObject div_position_zero = divJSONArray.getJSONObject(0);
JSONArray ulJSONArray = div_position_zero.getJSONArray("ul");
JSONObject ul_position_two = ulJSONArray.getJSONObject(2);
JSONArray liJSONArray = ul_position_two.getJSONArray("li");
for(int i=0; i < liJSONArray.length(); i++){
JSONObject li_position = liJSONArray.getJSONObject(i);
JSONObject a_JSONObject = li_position.getJSONObject("a");
JSONObject imgJSONObject = a_JSONObject.getJSONObject("img");
urlArr.add(imgJSONObject.getString("src"));//final object where data resides
}
for(String item : urlArr){
Log.v("JSONParser list items: ", item);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return null;
}
//protected void onPostExecute(ArrayList<String>... list){
// if(MainActivity.list.size()>0){
// MainActivity.list.clear();
//for(int i =0; i<urlArr.size();i++){
// Log.v("ope urlarr: ", urlArr.get(i));
//MainActivity.list.add(urlArr.get(i));
//}
}
}
}
It works up until here
Log.v("JSONParser list items: ", item);
and then my LogCat just goes blank.
Thanks again.
You can override the postexecute in the main activity as seen below.
new myAsyncTask({
#Override
void onPostExecute(ArrayList<String> Param){
//Should be able to do something here
}
}).execute();
reference
Returning an ArrayList in android AsyncTask class
As I can see, there are two mistakes:
The first is you are passing an instance of the list to the asynctask, but never filling it with result: instead you are creating and filling a new ArrayList called urlArr. You should fill the one retrieved in the doInBackground() parameters. Because of the varargs syntax, you can do it in this way:
ArrayList<String> myList = list[0];
This is because, in the vararg syntax, you can pass a variable number of arguments, and they will be represented as an array called, in your case, "list".
The second error is you cannot know when the asynctask execution will terminate. In the onCreate method you are going to read the result just after the call. But asynctask is basically a wrapper to a Java Thread, and is intended to execute code asyncronously. When you call
Log.v("jknfsda: ",list.get(1));
your array is probably still empty. You should use a callback to notify the activity the results are ready. A simple way to do it is to pass an activity instance to your asynctask class
new myAsyncTask(this).execute(list);
, retrieve it in the asynctask class and store it in a field
protected ArrayList<String> myAsyncTask(MainActivity context){...}
and, in the end, notify the activity in the onPostExecute calling a method in the activity. In example, if you created a method called myResultsAreReady() in the activity, you can call it as:
protected void onPostExecute(ArrayList<String>... list){
context.myResultsAreReady();
}
Obviously you can use that method for sending data to the activity, if you wish ;)
In your AsyncTask:
Return the correct value at the end of doInBackground, you are always returning null.
for(String item : urlArr){
Log.v("JSONParser list items: ", item);
}
return urlArr;
And you will have access to it in the onPostExecute, just uncomment yours and use the list parameter (you can can use a non static ArrayList too).
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 :)