I have an Android app (created from tutorials) that creates a list from JSON and depending on the data it creates a yellow or black background.
What i want is when a person clicks on a item from the list, data is transmitted to a server (works)
But then i want to refresh my list because the data has changed (cannot get this to work) Can anyone help me?
This is my code:
public class AndroidJSONParsingActivity extends ListActivity {
// url to make request
private static String url = "http://www.somesite.com/kaku/kaku_list.php/";
// JSON Node names
private static final String TAG_ONTVANGERS = "ontvangers";
private static final String TAG_ID = "id";
private static final String TAG_BESCHRIJVING = "beschrijving";
private static final String TAG_KANAAL = "kanaal";
private static final String TAG_NUMMER = "nummer";
private static final String TAG_STATUS = "status";
// contacts JSONArray
JSONArray ontvangers = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Hashmap for ListView
ArrayList<HashMap<String, String>> ontvanger = new ArrayList<HashMap<String, String>>();
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
// Getting Array of Contacts
ontvangers = json.getJSONArray(TAG_ONTVANGERS);
// looping through All Contacts
for(int i = 0; i < ontvangers.length(); i++){
JSONObject c = ontvangers.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ID);
String beschrijving = c.getString(TAG_BESCHRIJVING);
String kanaal = c.getString(TAG_KANAAL);
String nummer = c.getString(TAG_NUMMER);
String status = c.getString(TAG_STATUS);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ID, id);
map.put(TAG_BESCHRIJVING, beschrijving);
map.put(TAG_KANAAL, kanaal);
map.put(TAG_NUMMER, nummer);
map.put(TAG_STATUS, status);
// adding HashList to ArrayList
ontvanger.add(map);
}
} catch (JSONException e) {
e.printStackTrace();
}
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new OntvangerAdapter(this, ontvanger,
R.layout.list_item,
new String[] { TAG_BESCHRIJVING, TAG_ID, TAG_STATUS }, new int[] {
R.id.beschrijving, R.id.Ontvanger_id, R.id.status});
setListAdapter(adapter);
// selecting single ListView item
ListView lv = getListView();
// Launching new screen on Selecting Single ListItem
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String Ontvanger_id = ((TextView) view.findViewById(R.id.Ontvanger_id)).getText().toString();
JSONParser jParser = new JSONParser();
String url1 = "http://www.somesite.com/kaku/action.php?id="+Ontvanger_id+"/" ;
// getting JSON string from URL
jParser.getJSONFromUrl(url1);
}
});
}
}
From your comments
ListAdapter does not have notifyDataSetChanged()
http://developer.android.com/reference/android/widget/ListAdapter.html
You will to use ArrayAdapter or BaseAdapter. Its better to use a Custom Listview with a Custom Adapter extending either ArrayAdapter of BaseAdapter.(you can customize listview items easily).
http://developer.android.com/reference/android/widget/ArrayAdapter.html
http://developer.android.com/reference/android/widget/BaseAdapter.html#notifyDataSetChanged()
public void notifyDataSetChanged ()
Added in API level 1
Notifies the attached observers that the underlying data has been changed and any View reflecting the data set should refresh itself.
Use the method notifyDataSetCHanged(); and it'll be good.
To update the data/list in list view, you have to make a call to the method notifyDataSetChanged();
How and when to call that?
After you modify your ontvanger , call the function above.
Another side note, I think for newer API, you are not allowed to make HTTP request on UI thread anymore, you have to do it on AsyncTask or some background thread.
Hope that helps
Related
First of all , there is a listview in the activity named "user" . In the activity class, I have a thread that runs every 10 seconds. The thread calls a function which executes an AsyncTask . The AsyncTask does an http request and the response is parsed by a class named JSONparse . The data is then used in a listview inside a for loopwith a simple adapter.
The actual problem here is that the older data stay in the listview , and the same elements are added every 10 seconds.
The onPostExecute is inside the JSONparse class:
private static final String TAG_OS = "istekler";
private static final String TAG_VER = "isim";
private static final String TAG_NAME = "istek";
private static final String TAG_API = "mesaj";
protected void onPostExecute(JSONObject json) {
try {
// Getting JSON Array from URL
android = json.getJSONArray(TAG_OS);
for(int i = 0; i < android.length(); i++){
JSONObject c = android.getJSONObject(i);
// Storing JSON item in a Variable
String isim = c.getString(TAG_VER);
String mesaj = c.getString(TAG_NAME);
String istek = c.getString(TAG_API);
// Adding value HashMap key => value
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_VER, isim);
map.put(TAG_NAME, mesaj);
map.put(TAG_API, istek);
oslist.add(map);
list=(ListView)findViewById(R.id.list);
ListAdapter adapter = new SimpleAdapter(user.this, oslist,
R.layout.list_v,
new String[] { TAG_VER,TAG_NAME, TAG_API }, new int[] {
R.id.isim,R.id.mesaj, R.id.istek});
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(user.this, "Parça: "+oslist.get(+position).get("istek"), Toast.LENGTH_SHORT).show();
}
});
}
} catch (JSONException e) {
e.printStackTrace();
}
}
on your code you just add new elements to your list. You should call oslist.clear() to remove the old data.
I want to display images from urls, this urls are recieved from a mysql database along with other information, like username, post title, and message. I already managed to do that the url is recieved from the database and displayed as text in the post.
Now I changed the type from textview to imageview:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/url"
android:layout_gravity="center_horizontal" />
I dont know how to proceed.
This is my code:
public class ReadComments extends ListActivity {
// Progress Dialog
private ProgressDialog pDialog;
//php read comments script
//localhost :
//testing on your device
//put your local ip instead, on windows, run CMD > ipconfig
//or in mac's terminal type ifconfig and look for the ip under en0 or en1
// private static final String READ_COMMENTS_URL = "http://xxx.xxx.x.x:1234/webservice/comments.php";
//testing on Emulator:
private static final String READ_COMMENTS_URL = "http://www.eywow.com/webservice/comments.php";
//testing from a real server:
//private static final String READ_COMMENTS_URL = "http://www.mybringback.com/webservice/comments.php";
//JSON IDS:
private static final String TAG_SUCCESS = "success";
private static final String TAG_TITLE = "title";
private static final String TAG_POSTS = "posts";
private static final String TAG_POST_ID = "post_id";
private static final String TAG_USERNAME = "username";
private static final String TAG_MESSAGE = "message";
private static final String TAG_URL = "url";
//it's important to note that the message is both in the parent branch of
//our JSON tree that displays a "Post Available" or a "No Post Available" message,
//and there is also a message for each individual post, listed under the "posts"
//category, that displays what the user typed as their message.
//An array of all of our comments
private JSONArray mComments = null;
//manages all of our comments in a list.
private ArrayList<HashMap<String, String>> mCommentList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//note that use read_comments.xml instead of our single_post.xml
setContentView(R.layout.read_comments);
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
//loading the comments via AsyncTask
new LoadComments().execute();
}
public void addComment(View v)
{
Intent i = new Intent(ReadComments.this, AddComment.class);
startActivity(i);
}
public void startButton(View v)
{
Intent a = new Intent(ReadComments.this, UploadToServer.class);
startActivity(a);
}
/**
* Retrieves recent post data from the server.
*/
public void updateJSONdata() {
// Instantiate the arraylist to contain all the JSON data.
// we are going to use a bunch of key-value pairs, referring
// to the json element name, and the content, for example,
// message it the tag, and "I'm awesome" as the content..
mCommentList = new ArrayList<HashMap<String, String>>();
// Bro, it's time to power up the J parser
JSONParser jParser = new JSONParser();
// Feed the beast our comments url, and it spits us
//back a JSON object. Boo-yeah Jerome.
JSONObject json = jParser.getJSONFromUrl(READ_COMMENTS_URL);
//when parsing JSON stuff, we should probably
//try to catch any exceptions:
try {
//I know I said we would check if "Posts were Avail." (success==1)
//before we tried to read the individual posts, but I lied...
//mComments will tell us how many "posts" or comments are
//available
mComments = json.getJSONArray(TAG_POSTS);
// looping through all posts according to the json object returned
for (int i = 0; i < mComments.length(); i++) {
JSONObject c = mComments.getJSONObject(i);
//gets the content of each tag
String title = c.getString(TAG_TITLE);
String content = c.getString(TAG_MESSAGE);
String username = c.getString(TAG_USERNAME);
String url = c.getString(TAG_URL);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_TITLE, title);
map.put(TAG_MESSAGE, content);
map.put(TAG_USERNAME, username);
map.put(TAG_URL, url);
// adding HashList to ArrayList
mCommentList.add(map);
//annndddd, our JSON data is up to date same with our array list
}
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* Inserts the parsed data into the listview.
*/
private void updateList() {
// For a ListActivity we need to set the List Adapter, and in order to do
//that, we need to create a ListAdapter. This SimpleAdapter,
//will utilize our updated Hashmapped ArrayList,
//use our single_post xml template for each item in our list,
//and place the appropriate info from the list to the
//correct GUI id. Order is important here.
ListAdapter adapter = new SimpleAdapter(this, mCommentList,
R.layout.single_post, new String[] { TAG_TITLE, TAG_MESSAGE,
TAG_USERNAME, TAG_URL }, new int[] { R.id.title, R.id.message,
R.id.username, R.id.url });
// I shouldn't have to comment on this one:
setListAdapter(adapter);
// Optional: when the user clicks a list item we
//could do something. However, we will choose
//to do nothing...
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// This method is triggered if an item is click within our
// list. For our example we won't be using this, but
// it is useful to know in real life applications.
}
});
}
class PostLike{
}
public class LoadComments extends AsyncTask<Void, Void, Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(ReadComments.this);
pDialog.setMessage("Loading Comments...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected Boolean doInBackground(Void... arg0) {
//we will develop this method in version 2
updateJSONdata();
return null;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
pDialog.dismiss();
//we will develop this method in version 2
updateList();
}
}
}
There is many ways, but this library makes your work easy a lot:
Click on Picasso and read the documentation, it's very simple you'll need to only write one line of code:
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);
But please next time you ask a question, provide clean and short code.
Good luck.
In your case:
String url = "...";
ImageView imageView = (ImageView) findViewById(R.id.url);
Picasso.with(context).load(url).into(imageView);
But make sure you download the JAR file and include it to your project, unless this code will not work.
Ok I added it and included the .jar but it doesnt work, the app just crashes, I think this is the relevant part to solve this issue:
try {
mComments = json.getJSONArray(TAG_POSTS);
// looping through all posts according to the json object returned
for (int i = 0; i < mComments.length(); i++) {
JSONObject c = mComments.getJSONObject(i);
//gets the content of each tag
String title = c.getString(TAG_TITLE);
String content = c.getString(TAG_MESSAGE);
String username = c.getString(TAG_USERNAME);
String url = c.getString(TAG_URL);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_TITLE, title);
map.put(TAG_MESSAGE, content);
map.put(TAG_USERNAME, username);
map.put(TAG_URL, url);
// PART TO GET IMAGES - "Can not resolve context"
ImageView imageView = (ImageView) findViewById(R.id.url);
Picasso.with(context).load(url).into(imageView);
// adding HashList to ArrayList
mCommentList.add(map);
//annndddd, our JSON data is up to date same with our array list
}
EDIT
When I started to build the app, I created 2 posts with direct file paths of the images, where they are stored at the device, they are displayed correct:
Screenshot
The uploaded images are not displayed, they have a url like this:
"http://www.eywow.com/webservice/uploads/name.jpg"
I want to list text and image from json which is placed in particular url
I have successively displayed textview but how to display image my code is
public class AndroidJSONParsingActivity extends ListActivity {
// url to make request
private static String url = "***MY URL***";
// JSON Node names
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_PRICE = "price";
private static final String TAG_URL = "hosting_thumbnail_url";
// contacts JSONArray
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_jsonparsing);
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONArray json = jParser.getJSONFromUrl(url);
try {
// Getting Array of Contacts
// looping through All Contacts
for(int i = 0; i < json.length(); i++){
JSONObject c = json.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String email = c.getString(TAG_PRICE);
//String image1 = c.getString( TAG_URL);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
map.put(TAG_PRICE, email);
//map.put(TAG_URL, image1);
// 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_NAME, TAG_PRICE }, new int[] {
R.id.name, R.id.email });
setListAdapter(adapter);
}
}
i want listview like this "http://pic002.cnblogs.com/images/2012/372551/2012021011374176.jpg"
You will need to write a custom list adapter. Google for "android custom listadapter image". The first hit is this one, which looks like a decent example.
As SimonSays said, you have to implement your own ListView adapter class and its getView() method.
If you plan to obtain these JSON objects dynamically in ListView I strongly recommend to use some Thread mechanism, that would set data from that JSON object to ListView immediately when it's obtained - i.e. AsyncTask
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! : )
It is my mainactivity code. Following is my main activity code and it shows four errors:
adapter cannot be resolved to a type
Syntax error on token ")", { expected after this token
Syntax error on token "adapter", VariableDeclaratorId expected after this token.
Source code:
public class HospitalParseActivity extends ListActivity {
//url where request is made
private static String url="url";
//JSON node names
private static final String TAG_NETFOX="transfer";
private static final String TAG_DATE="date";
private static final String TAG_CWEB="c_web";
private static final String TAG_CBANK="c_bank";
private static final String TAG_CCASH="c_cash";
private static final String TAG_SWEB="s_web";
private static final String TAG_SBANK="s_bank";
private static final String TAG_SCASH="s_cash";
//creation of JSONArray
JSONArray netfoxlimited=null;
private List<? extends Map<String, ?>> contactList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
try {
// Getting Array of Contacts
netfoxlimited = json.getJSONArray(TAG_NETFOX);
// looping through All Contacts
for(int i = 0; i < netfoxlimited.length(); i++){
JSONObject c = netfoxlimited.getJSONObject(i);
// Storing each json item in variable
String date = c.getString(TAG_DATE);
String c_web = c.getString(TAG_CWEB);
String c_bank = c.getString(TAG_CBANK);
String c_cash = c.getString(TAG_CCASH);
String s_web = c.getString(TAG_SWEB);
String s_bank = c.getString(TAG_SBANK);
String s_cash = c.getString(TAG_SCASH);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_DATE, date);
map.put(TAG_CWEB, c_web);
map.put(TAG_CBANK, c_bank);
map.put(TAG_CCASH, c_cash);
map.put(TAG_SWEB, s_web);
map.put(TAG_SBANK, s_bank);
map.put(TAG_SCASH, s_cash);
// 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_DATE, TAG_CWEB, TAG_CBANK,TAG_CCASH, TAG_CWEB,TAG_CBANK, TAG_CCASH }, new int[] {
R.id.date, R.id.cweb, R.id.cbank,R.id.sweb,R.id.sbank,R.id.scash });
setListAdapter(adapter);
// selecting single ListView item
ListView lv = getListView();
// Launching new screen on Selecting Single ListItem
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String dt = ((TextView) view.findViewById(R.id.date)).getText().toString();
String web = ((TextView) view.findViewById(R.id.cweb)).getText().toString();
String bank = ((TextView) view.findViewById(R.id.cbank)).getText().toString();
String cash = ((TextView) view.findViewById(R.id.ccash)).getText().toString();
String web1 = ((TextView) view.findViewById(R.id.sweb)).getText().toString();
String bank1 = ((TextView) view.findViewById(R.id.sbank)).getText().toString();
String cash1 = ((TextView) view.findViewById(R.id.scash)).getText().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
in.putExtra(TAG_DATE, dt);
in.putExtra(TAG_CWEB, web);
in.putExtra(TAG_CBANK, bank);
in.putExtra(TAG_CCASH, cash);
in.putExtra(TAG_SWEB, web1);
in.putExtra(TAG_SBANK, bank1);
in.putExtra(TAG_SCASH, cash1);
startActivity(in);
}
});
}
}
Are you writing code outside the onCreate function? Seems like onCreate function ended at the '}' after the catch block. You may just want to remove that