Custom ListView with single choice selection and dynamic data - android

I'm working on an app that I need to be able to load a list of locations into a ListView, and then let the user select a single location which will then determine the rest of the user's experience down the line.
Currently I have the list of locations being pulled from a JSON request and I can easily display the information into a ListView - the problem I am having though is getting that same list into some form of list that the user can select just one location. I personally have no preference on if it's a radio button list or a spinner. I have been trying various methods for the past week now from tutorials on the net, but I can never get any of them to work with my current method of retrieving and storing the list, so I'm finally at wits end and looking for some guidance. I am extremely new to java/android programming so I know that my lack of experience is probably the most to blame here. So I guess if someone can at least just point me in the right direction so I'm not spinning my wheels on a solution that would require a ton of re-work then I would greatly appreciate it!
Below is my current activity that retrieves the JSON and slaps it into a standard ListView - I have it storing the info into a DB for use further down the app's line.
public class SQLiteJSONParsing extends ListActivity {
private ProgressDialog pDialog;
//////////////////////// JSON URL //////////////////////////
private static String url = "http://my/link/to/json";
//////////////////////// JSON Node Names //////////////////////////
private static final String TAG_CONTACTS = "contacts";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_CON_POSITION = "con_position";
private static final String TAG_ADDRESS = "address";
private static final String TAG_SUBURB = "suburb";
private static final String TAG_STATE = "state";
private static final String TAG_POSTCODE = "postcode";
private static final String TAG_TELEPHONE = "telephone";
private static final String TAG_EMAIL_TO = "email_to";
//////////////////////// JSON Array //////////////////////////
JSONArray contacts = null;
private DatabaseHelper databaseHelper;
//////////////////////// HashMap ListView //////////////////////////
ArrayList<HashMap<String, String>> locationsList;
///////////////////////// Start onCreate method ////////////////////////////
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_launch_options);
databaseHelper = new DatabaseHelper(SQLiteJSONParsing.this);
locationsList = new ArrayList<HashMap<String, String>>();
//////////////////////// Skip Button //////////////////////////
Button cancel = (Button)findViewById(R.id.cancel);
cancel.setOnClickListener(new OnClickListener()
{ public void onClick(View v)
{
Intent locationList = new Intent(SQLiteJSONParsing.this, MainActivity.class);
startActivity(locationList);
finish();
}
});
//////////////////////// Start ASYNC //////////////////////////
new GetLocations().execute();
}
//////////////////////// ASYNC HTTP Call //////////////////////////
private class GetLocations extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(SQLiteJSONParsing.this);
pDialog.setMessage("Loading Locations...");
pDialog.setCancelable(true);
pDialog.show();
}
//////////////////////// Start Background Service Handler & Load the DB //////////////////////////
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
LocationsFeedServiceHandler sh = new LocationsFeedServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, LocationsFeedServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
//////////////////////// Get the JSON Node Array //////////////////////////
contacts = jsonObj.getJSONArray(TAG_CONTACTS);
//////////////////////// Loop Through the Results //////////////////////////
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String con_position = c.getString(TAG_CON_POSITION);
String address = c.getString(TAG_ADDRESS);
String suburb = c.getString(TAG_SUBURB);
String state = c.getString(TAG_STATE);
String postcode = c.getString(TAG_POSTCODE);
String telephone = c.getString(TAG_TELEPHONE);
String email_to = c.getString(TAG_EMAIL_TO);
//////////////////////// Save Records to DB //////////////////////////
databaseHelper.saveTableRecord(id, name, con_position, address, suburb, state, postcode, telephone, email_to);
//////////////////////// Single Items HashMap //////////////////////////
HashMap<String, String> items = new HashMap<String, String>();
//////////////////////// Add Items to the HashMap //////////////////////////
items.put(TAG_ID, id);
items.put(TAG_NAME, name);
items.put(TAG_CON_POSITION, con_position);
items.put(TAG_ADDRESS, address);
items.put(TAG_SUBURB, suburb);
items.put(TAG_STATE, state);
items.put(TAG_POSTCODE, postcode);
items.put(TAG_TELEPHONE, telephone);
items.put(TAG_EMAIL_TO, email_to);
//////////////////////// Add Items to the LocationsList //////////////////////////
locationsList.add(items);
}
//////////////////////// Capture Exceptions //////////////////////////
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("LocationsFeedServiceHandler", "Couldn't get any data from the url");
}
return null;
}
//////////////////////// Close Progress Dialog //////////////////////////
protected void onPostExecute(Void location_result) {
super.onPostExecute(location_result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
//////////////////////// Update the Parsed JSON into the ListAdapter //////////////////////////
ListAdapter locations_adapter = new SimpleAdapter(
SQLiteJSONParsing.this, locationsList,
R.layout.first_launch_locations_detail,
new String[] { TAG_NAME },
new int[] { R.id.name });
setListAdapter(locations_adapter);
}
}

I used this following example code, which i need to select single item from the listview.
http://amitandroid.blogspot.in/2013/03/android-custon-single-choice-lsitview.html

Related

how to prevent to show the duplicate and repetatvie value in listview when we update it by swipe down?

i used a list view in my app.i used scroll bar for update the details. i got complete updated list again.which added all the data in ny list. i wants to avoid it so plz suggest me how i retrict the duplicate values in list after updation.... my code snippet is here.....
public class MainActivity extends ListActivity implements SwipeRefreshLayout.OnRefreshListener {
private ProgressDialog pDialog;
ListView mListView;
SwipeRefreshLayout swipeLayout;
Adapter mAdapter;
// URL to get contacts JSON
private static String url = "http://api.androidhive.info/contacts/";
// JSON Node names
private static final String TAG_CONTACTS = "contacts";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_EMAIL = "email";
private static final String TAG_ADDRESS = "address";
private static final String TAG_GENDER = "gender";
private static final String TAG_PHONE = "phone";
private static final String TAG_PHONE_MOBILE = "mobile";
private static final String TAG_PHONE_HOME = "home";
private static final String TAG_PHONE_OFFICE = "office";
// contacts JSONArray
JSONArray contacts = null;
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// SwipeRefreshLayout mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.activity_main_swipe_refresh_layout);
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(this);
swipeLayout.setColorScheme(android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
contactList = new ArrayList<HashMap<String, String>>();
ListView lv = getListView();
// Listview on item click listener
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
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 single contact activity
Intent in = new Intent(getApplicationContext(),
ak.class);
in.putExtra(TAG_NAME, name);
in.putExtra(TAG_EMAIL, cost);
in.putExtra(TAG_PHONE_MOBILE, description);
startActivity(in);
}
});
// Calling async task to get json
new GetContacts().execute();
}
/**
* Async task class to get json by making HTTP call
*/
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
// pDialog = new ProgressDialog(MainActivity.this);
// pDialog.setMessage("Please wait...");
// pDialog.setCancelable(false);
//Dialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
contacts = jsonObj.getJSONArray(TAG_CONTACTS);
// looping through All Contacts
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String email = c.getString(TAG_EMAIL);
String address = c.getString(TAG_ADDRESS);
String gender = c.getString(TAG_GENDER);
// Phone node is JSON Object
JSONObject phone = c.getJSONObject(TAG_PHONE);
String mobile = phone.getString(TAG_PHONE_MOBILE);
String home = phone.getString(TAG_PHONE_HOME);
String office = phone.getString(TAG_PHONE_OFFICE);
// tmp hashmap for single contact
HashMap<String, String> contact = new HashMap<String, String>();
// adding each child node to HashMap key => value
contact.put(TAG_ID, id);
contact.put(TAG_NAME, name);
contact.put(TAG_EMAIL, email);
contact.put(TAG_PHONE_MOBILE, mobile);
// adding contact to contact list
contactList.add(contact);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
/* if (pDialog.isShowing())
pDialog.dismiss();*/
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, contactList,
R.layout.list_item, new String[]{TAG_NAME, TAG_EMAIL,
TAG_PHONE_MOBILE}, new int[]{R.id.name,
R.id.email, R.id.mobile});
setListAdapter(adapter);
}
}
#Override
public void onRefresh() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
new GetContacts().execute();
swipeLayout.setRefreshing(false);
}
}, 5000);
}
The only thing you have to do is set adapter like this way and it won't replicate data. It just add new data below older one.
adapter = null;
if (adapter == null) {
adapter = new CustomAdapter(this, arrayList);
listvie.setAdapter(adapter);
}
adapter.notifyDataSetChanged();
Hope it will work.
Thanks. :)
Solution is very simple.
Create ListAdapter before executing AsyncTask with empty Collection
Set adapter for ListView with created adapter
In AsyncTask create local field ArrayList<HashMap<String, String>> localList
Parsed contacts put to localList, not to contactList
After download items, clear Collection by calling contactList.clear();
Add download contacts contactList.addAll(localList);
Call adapter.notifyDataSetChanged();

Display image from URL into ImageView?

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"

'for' statement does not loop (contact application)

I am trying to send the numbers of my contacts to the server to check if these numbers are contained in my database. All numbers contained in database and in the address list of the phone finally should be displayed in a listview.
While using the for each loop ('for (String phoneNumberString : aa)') I get this warning: 'for' statement does not loop...
How can I solve this problem?
public class AllUserActivity extends ListActivity {
// Progress Dialog
private ProgressDialog pDialog;
// Creating JSON Parser object
JSONParser jParser = new JSONParser();
ArrayList<HashMap<String, String>> usersList;
// url to get all users list
private static String url_all_user = "http://.../.../.../get_user.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_USER = "user";
private static final String TAG_PHONE = "phone";
private static final String TAG_UID = "uid";
private static final String TAG_USERNAME = "username";
String phoneNumber;
ArrayList<String> aa= new ArrayList<String>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.all_user);
// Hashmap for ListView
usersList = new ArrayList<HashMap<String, String>>();
// Loading users in Background Thread
new LoadAllUsers().execute();
getNumber(this.getContentResolver());
}
// get all numbers of contacts
public void getNumber(ContentResolver cr)
{
Cursor phones = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
// use the cursor to access the contacts
while (phones.moveToNext())
{
phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String phoneNumberString = phoneNumber.replaceAll("\\D+","");
// get phone number
System.out.println(".................."+phoneNumberString);
aa.add(phoneNumberString);
}
phones.close();// close cursor
}
class LoadAllUsers extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(AllUserActivity.this);
pDialog.setMessage("Loading users. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
for (String phoneNumberString : aa){
params.add(new BasicNameValuePair("phone[]", phoneNumberString));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_user, "GET", params);
// Check your log cat for JSON response
Log.d("All users: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
JSONArray users = json.getJSONArray(TAG_USER);
// looping through all contacts
for (int i = 0; i < users.length(); i++) {
JSONObject c = users.getJSONObject(i);
// Storing each json item in variable
String uid = c.getString(TAG_UID);
String phone = c.getString(TAG_PHONE);
String username = c.getString(TAG_USERNAME);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_UID, uid);
map.put(TAG_PHONE, phone);
map.put(TAG_USERNAME, username);
// adding HashList to ArrayList
usersList.add(map);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
return null;
}
// After completing background task Dismiss the progress dialog
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all users
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
// Updating parsed JSON data into ListView
ListAdapter adapter = new SimpleAdapter(
AllUserActivity.this, usersList,
R.layout.list_users, new String[] { TAG_PHONE,
TAG_USERNAME},
new int[] { R.id.phone, R.id.name });
// updating listview
setListAdapter(adapter);
}
});
}}
}
You have a return statement at the end of your for loop, meaning it will go through the first element and return from your doInBackground() call.

JSON data is read but cannot be converted to JSONArray

I'm developing an app which reads JSON data. Json Data is parsed but it is not viewing in the listview. Logcat says about a type mismatch. I'm not that much familiar in Json.
http://api.openweathermap.org/data/2.5/forecast/daily?lat=6.421465&lon=81.332396&cnt=10&mode=json
This is my logcat and code. Please hemp me with this.
org.json.JSONException: Index 1 out of range [0..1)
org.json.JSONArray.get(JSONArray.java:263)
org.json.JSONArray.getString(JSONArray.java:421)
com.is.parsej.ParseJ$GetContacts.doInBackground(ParseJ.java:141)
com.is.parsej.ParseJ$GetContacts.doInBackground(ParseJ.java:1)
android.os.AsyncTask$2.call(AsyncTask.java:287)
java.util.concurrent.FutureTask.run(FutureTask.java:234)
android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
public class ParseJ extends ListActivity {
private ProgressDialog pDialog;
// URL to get contacts JSON
private static String url = "http://api.openweathermap.org/data/2.5/forecast/daily?lat=6.421465&lon=81.332396&cnt=10&mode=json";
// JSON Node names
private static final String TAG_COd = "list"; //edited
private static final String TAG_ID = "dt"; //edited
private static final String TAG_WEATHER = "weather";
private static final String TAG_MAIN = "main";
private static final String TAG_DESC = "description";
private static final String TAG_TEMP = "temp";
private static final String TAG_DAY = "day";
private static final String TAG_MIN = "min";
private static final String TAG_MAX = "max";
private static final String TAG_NIGHT = "night";
private static final String TAG_MORN= "morn";
private static final String TAG_HUMIDITY = "humidity";
// contacts JSONArray
JSONArray contacts = null;
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parse_j);
contactList = new ArrayList<HashMap<String, String>>();
ListView lv = getListView();
// Listview on item click listener
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String weather = ((TextView) view.findViewById(R.id.main))
.getText().toString();
String Temp = ((TextView) view.findViewById(R.id.Descrption))
.getText().toString();
String Humidity = ((TextView) view.findViewById(R.id.temp))
.getText().toString();
// Starting single contact activity
Intent in = new Intent(getApplicationContext(),
SingleContactActivity.class);
in.putExtra(TAG_WEATHER, weather);
in.putExtra(TAG_TEMP, Temp);
in.putExtra(TAG_HUMIDITY, Humidity);
startActivity(in);
}
});
// Calling async task to get json
new GetContacts().execute();
}
/**
* Async task class to get json by making HTTP call
* */
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(ParseJ.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
contacts = jsonObj.getJSONArray(TAG_COd);
// looping through All Contacts
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
String id = c.getString(TAG_ID);
String humidity = c.getString(TAG_HUMIDITY);
// Phone node is JSON Object
JSONObject temp = c.getJSONObject(TAG_TEMP);
String day = temp.getString(TAG_DAY);
String maxTemp = temp.getString(TAG_MAX);
String minTemp = temp.getString(TAG_MIN);
String morningTemp = temp.getString(TAG_MORN);
//edited
JSONArray weather = c.getJSONArray(TAG_WEATHER);
String main = weather.getString(1);
String desc = weather.getString(2);
// tmp hashmap for single contact
HashMap<String, String> contact = new HashMap<String, String>();
// adding each child node to HashMap key => value
contact.put(TAG_ID, id);
contact.put(TAG_DAY, day);
contact.put(TAG_DESC, desc);
contact.put(TAG_HUMIDITY, humidity);
// adding contact to contact list
contactList.add(contact);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
ParseJ.this, contactList,
R.layout.list_item, new String[] { TAG_DAY, TAG_DESC,
TAG_HUMIDITY }, new int[] { R.id.temp,
R.id.main, R.id.Descrption });
setListAdapter(adapter);
}
}
}
based on your JSON it is just a list of element. Arrays have [ at the beginning and ] at the end. look closely at your JSON you may find some array elements there that has [].
weather only has 1 element
"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04d"}]
index out of bounds because you are using
JSONArray weather = c.getJSONArray(TAG_WEATHER);
String main = weather.getString(1);
String desc = weather.getString(2);
where there is no 1 and 2 in your json array weather, since the weather seems to have only 1 element put it in another json object
JSONObject weather = c.getJSONArray(TAG_WEATHER).getJSONObject(0);
String main = weather.getString("main");
String desc = weather.getString("description");
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
contacts = jsonObj.getJSONArray("list");
// looping through All Contacts
for (int i = 0; i < contacts.length(); i++) {
}
change this in your code and let me know, if any issue.
the json is here
{"cod":"200","message":0.2809,"city":{"id":1244926,"name":"Hambantota","coord":{"lon":81.1185,"lat":6.1241},"country":"LK","population":0},"cnt":10,"list":[{"dt":1409896800,"temp":{"day":301.95,"min":300.47,"max":302.12,"night":301.31,"eve":301.87,"morn":300.47},"pressure":1020.63,"humidity":88,"weather":[{"id":803,"main":"Clouds","description":"broken
clouds","icon":"04d"}],"speed":6.47,"deg":243,"clouds":56},{"dt":1409983200,"temp":{"day":301.11,"min":299.62,"max":301.29,"night":299.62,"eve":300.76,"morn":300.13},"pressure":1021.53,"humidity":92,"weather":[{"id":802,"main":"Clouds","description":"scattered
clouds","icon":"03d"}],"speed":6.66,"deg":249,"clouds":48},{"dt":1410069600,"temp":{"day":300.9,"min":299.36,"max":300.9,"night":299.58,"eve":300.2,"morn":299.36},"pressure":1022.25,"humidity":90,"weather":[{"id":803,"main":"Clouds","description":"broken
clouds","icon":"04d"}],"speed":7.21,"deg":242,"clouds":80},{"dt":1410156000,"temp":{"day":299.47,"min":298.71,"max":300.44,"night":299.5,"eve":299.96,"morn":298.71},"pressure":1023.27,"humidity":98,"weather":[{"id":802,"main":"Clouds","description":"scattered
clouds","icon":"03d"}],"speed":5.83,"deg":252,"clouds":44},{"dt":1410242400,"temp":{"day":301.38,"min":297.39,"max":301.38,"night":298.36,"eve":300.82,"morn":297.39},"pressure":1012.02,"humidity":0,"weather":[{"id":500,"main":"Rain","description":"light
rain","icon":"10d"}],"speed":3.87,"deg":250,"clouds":76,"rain":0.38},{"dt":1410328800,"temp":{"day":301.77,"min":297.49,"max":301.77,"night":299.44,"eve":301.13,"morn":297.49},"pressure":1011.84,"humidity":0,"weather":[{"id":500,"main":"Rain","description":"light
rain","icon":"10d"}],"speed":4.88,"deg":259,"clouds":27,"rain":0.82},{"dt":1410415200,"temp":{"day":302.15,"min":299.15,"max":302.15,"night":299.43,"eve":300.52,"morn":299.15},"pressure":1011.1,"humidity":0,"weather":[{"id":500,"main":"Rain","description":"light
rain","icon":"10d"}],"speed":6.3,"deg":257,"clouds":64,"rain":1.82},{"dt":1410501600,"temp":{"day":301.52,"min":299.16,"max":301.52,"night":299.36,"eve":300.59,"morn":299.16},"pressure":1011.05,"humidity":0,"weather":[{"id":500,"main":"Rain","description":"light
rain","icon":"10d"}],"speed":8.05,"deg":257,"clouds":50,"rain":2.38},{"dt":1410588000,"temp":{"day":301.26,"min":298.74,"max":301.26,"night":299.53,"eve":300.43,"morn":298.74},"pressure":1010.43,"humidity":0,"weather":[{"id":500,"main":"Rain","description":"light
rain","icon":"10d"}],"speed":7.69,"deg":258,"clouds":33,"rain":1.34},{"dt":1410674400,"temp":{"day":300.01,"min":298.37,"max":300.01,"night":298.48,"eve":298.37,"morn":298.87},"pressure":1010.17,"humidity":0,"weather":[{"id":501,"main":"Rain","description":"moderate
rain","icon":"10d"}],"speed":8.36,"deg":253,"clouds":55,"rain":8.91}
and then you get object with tag "cod"
contacts = jsonObj.getJSONArray(TAG_COd)
"cod":"200"
you will get "200"
how can "200" be converted to JSONArray?
the array structure is just like this
[{"dt":1409896800},{"dt":1409896800},{"dt":1409896800},{"dt":1409896800}]
starts with "[" and end with "]"
Exception is self Explaining
org.json.JSONException: Value 200 at cod of type java.lang.String cannot be converted to JSONArray
You are converting String to JSONArray here,
contacts = jsonObj.getJSONArray(TAG_COd);
cod is a String while you're converting it to JSONArray
String cod = jsonObj.getJSONString(TAG_COd);

ListView works in emulator, but not in phone

I tried to make a simple application that will take the API from the internet, rearrange them and show as list.
In the emulator it works. The phone shows a white screen. The phone has Android 2.3.7. But when I tried it on the tablet, the app stopped working. The tablet has Android 4.1.
MainActivity
public class MainActivity extends ListActivity implements OnItemClickListener{
private ProgressDialog pDialog;
private String url = "http://www.cscpro.org/secura/market/"; //food-29-5.json;
private String res;
private String ql;
JSONArray market;
final static String RESOURCES = "res";
final static String QUALITY = "q";
private static final String TAG_OFFER = "offer";
private static final String TAG_PRICE = "price";
private static final String TAG_SALLER = "seller";
private static final String TAG_SALLER_NAME = "name";
ArrayList<HashMap<String, String>> listSaller;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listSaller = new ArrayList<HashMap<String, String>>();
Intent in = getIntent();
res = in.getStringExtra(RESOURCES);
ql = in.getStringExtra(QUALITY);
ListView lv = getListView();
lv.setOnItemClickListener(this);
// Calling async task to get json
new GetContacts().execute();
}
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String rate = ((TextView) view.findViewById(R.id.rate)).getText().toString();
String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
// Starting single contact activity
Intent in = new Intent(getApplicationContext(),
SingleContactActivity.class);
in.putExtra(TAG_PRICE, rate);
in.putExtra(TAG_SALLER_NAME, name);
startActivity(in);
}
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String myURL = url+res+"-29-"+ql+".json";
String jsonStr = sh.makeServiceCall(myURL, ServiceHandler.GET);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
market = jsonObj.getJSONArray(TAG_OFFER);
// looping through All Contacts
for (int i = 0; i < market.length(); i++) {
JSONObject c = market.getJSONObject(i);
String rate = c.getString(TAG_PRICE);
// Phone node is JSON Object
JSONObject saller = c.getJSONObject(TAG_SALLER);
String name = saller.getString(TAG_SALLER_NAME);
// tmp hashmap for single contact
HashMap<String, String> sallers = new HashMap<String, String>();
// adding each child node to HashMap key => value
sallers.put(TAG_PRICE, rate);
sallers.put(TAG_SALLER_NAME, name);
// adding contact to contact list
listSaller.add(sallers);
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(
MainActivity.this, listSaller,
R.layout.list_item, new String[] { TAG_PRICE, TAG_SALLER_NAME}, new int[] { R.id.rate,
R.id.name});
setListAdapter(adapter);
}
}
}
SingleContactActivity
public class SingleContactActivity extends Activity {
// JSON node keys
private static final String TAG_PRICE = "price";
private static final String TAG_SALLER_NAME = "name";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_contact);
// getting intent data
Intent in = getIntent();
// Get JSON values from previous intent
String rate = in.getStringExtra(TAG_PRICE);
String name = in.getStringExtra(TAG_SALLER_NAME);
// Displaying all values on the screen
TextView lblName = (TextView) findViewById(R.id.name_label);
TextView lblRate = (TextView) findViewById(R.id.rate_label);
lblName.setText(name);
lblRate.setText(rate);
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<!-- Main ListView
Always give id value as list(#android:id/list)
-->
<ListView
android:id="#android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
activity_single_contact.xml is a simple LinearLayout with two TextViews.

Categories

Resources