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?
Related
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'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);
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 :)
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.
I want to fill a ListFragment with certain objects loaded from my MySql database.
It has to load the first 10 'objects' from my ResultSet.
I want to use an AsyncTaskLoader for this and put the loaded object in a ListItem each time I retreive it from the database.
Can anybody help me with this one? Tried searching for good examples or tutorials but I haven't really found something that's really useful...
Create your adapter with a new list in your preexecute method. Set that adapter to your listview.
Then in doInBackground read your database, create objects to fit in your list, but don't add them. Pas each object after made as parameter for your publishprogress method.
In onProgressUpdate add your object to the list and notify your adapter that the dataset is changed.
Below is an example for how I do it reading a twitter call.
private class parseTwitterTask extends AsyncTask<Void, TCListObject2, List<TCListObject2>> {
TCListObjectAdapter2 adapter;
List<TCListObject2> list;
#Override
protected void onPreExecute() {
list = new ArrayList<TCListObject2>();
ListView lv = (ListView)findViewById(R.id.twitterlist);
adapter = new TCListObjectAdapter2(list);
lv.setAdapter(adapter);
super.onPreExecute();
}
#Override
protected List<TCListObject2> doInBackground(Void... params) {
try {
String url = social.get("twittersearchurl");//"http://search.twitter.com/search.json?q=" + social.get("twitter");
String json = Internet.request(url, null);
JSONObject jo = new JSONObject(json);
if(jo.has("results")) {
JSONArray ar = jo.getJSONArray("results");
for(int i = 0; i < ar.length(); i++) {
TCListObject2 tweet = new TCListObject2();
JSONObject jobj = (JSONObject) ar.get(i);
tweet.id = "false";
tweet.img = jobj.getString("profile_image_url");
String text = jobj.getString("text");
text = Html.fromHtml(text).toString();
tweet.params.put(R.id.sub2, text);
String name = jobj.getString("from_user");
name = Html.fromHtml(name).toString();
tweet.params.put(R.id.text, name);
String time = jobj.getString("created_at");
tweet.params.put(R.id.sub1, Converter.timeToTimeAgo(time));
try {
tweet.time = new Date(time);
} catch(Exception e) {
e.printStackTrace();
}
tweet.celLayout = R.layout.cell_tweetobject;
publishProgress(tweet);
}
}
} catch(Exception e) {
e.printStackTrace();
}
return list;
}
#Override
protected void onProgressUpdate(TCListObject2... values) {
list.add(values[0]);
adapter.notifyDataSetChanged();
super.onProgressUpdate(values);
}