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"
Related
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
I currently have a ListAdapter set up that is passed information pulled from a MYSQL database via JSON. I'm trying to display an image I have stored in the drawable folder based on the ID of the product. e.g For Product 1 R.drawable.img1 is shown in and so on..
public class GetProducts extends ListActivity {
// Progress Dialog
private ProgressDialog pDialog;
// Creating JSON Parser object
JSON jParser = new JSON();
Functions uf = new Functions();
ArrayList<HashMap<String, Object>> productsList;
// url to get all products list
private static String url_all_products = "http://jumpto.be/api/get_all_products.php";
// JSON Node names
private static final String TAG_SUCCESS = "success";
private static final String TAG_PRODUCTS = "products";
private static final String TAG_PID = "pid";
private static final String TAG_NAME = "name";
private static final String TAG_IMGURL = "image";
// products JSONArray
JSONArray products = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view_products);
// Hashmap for ListView
productsList = new ArrayList<HashMap<String, Object>>();
new GetProductsFromDB().execute();
// Loading products in Background Thread
// Get listview
ListView lv = getListView();
// on seleting single product
// launching Edit Product Screen
/*lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String pid = ((TextView) view.findViewById(R.id.pid)).getText()
.toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(),
OrderBuild.class);
// sending pid to next activity
in.putExtra(TAG_PID, pid);
// starting new activity and expecting some response back
startActivityForResult(in, 100);
}
});*/
}
class GetProductsFromDB extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(GetProducts.this);
pDialog.setMessage("Loading products. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url_all_products, params);
// Check your log cat for JSON reponse
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_PRODUCTS);
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);
String ImgUrl = c.getString(TAG_PID);
// creating new HashMap
HashMap<String, Object> map = new HashMap<String, Object>();
// adding each child node to HashMap key => value
map.put(TAG_PID, id);
map.put(TAG_NAME, name);
String imageLink = "R.drawable.img"+id;
map.put(TAG_IMGURL, imageLink);
// adding HashList to ArrayList
productsList.add(map);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
ListAdapter adapter = new SimpleAdapter(
GetProducts.this, productsList,
R.layout.list_item, new String[] { TAG_PID,
TAG_NAME, TAG_IMGURL},
new int[] { R.id.pid, R.id.name, R.id.img });
// updating listview
setListAdapter(adapter);
}
});
}
}
}
The current code I have just tells me it cannot find the directory. I have looked at URI but I can't figure out how I run them in the array / for loop.
Many Thanks
R.drawable.img1 is actually just an int value defined in your automatically generated R.java file, so you cannot use it directly.
However, you can retrieve your drawable using the following:
Resources resources = getResources();
int resId = resources.getIdentifier("img" + id, "drawable", getPackageName());
Drawable myDrawable = resources.getDrawable(resId);
Alternatively, you can place your image files in your assets directory and load them from there using the filename.
InputStream inputStream = getAssets().open("img" + id + ".jpg");
Drawable drawable = Drawable.createFromStream(inputStream, null);
mImageView.setImageDrawable(drawable);
You can set int value for drawable in hashmap. It is easy to bind in list adapter.
int imageLink = R.drawable.img1;
map.put(TAG_IMGURL, imageLink);
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
This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 9 years ago.
Below is my code:
private static final String TAG_TYPE = "movie_type";
private static final String TAG_NAME = "movie_name";
private static final String TAG_LENGTH = "movie_length";
private static final String TAG_SCHEDULES = "movie_schedules";
private static final String TAG_CINEMA = "movie_cinema_number";
private static final String TAG_URL = "movie_image_url";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
String readMovieSchedules = readMovieSchedules();
// Hashmap for ListView
ArrayList<HashMap<String, String>> movieList = new ArrayList<HashMap<String, String>>();
JSONArray jsonArray = new JSONArray(readMovieSchedules);
Log.i(MainActivity.class.getName(),
"Number of entries " + jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.i(MainActivity.class.getName(), jsonObject.getString("movie_name"));
// Storing each json item in variable
String name = jsonObject.getString(TAG_NAME);
String type = jsonObject.getString(TAG_TYPE);
String length = jsonObject.getString(TAG_LENGTH);
String cinema = jsonObject.getString(TAG_CINEMA);
String schedules = jsonObject.getString(TAG_SCHEDULES);
String url = jsonObject.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_NAME, name);
map.put(TAG_TYPE, type);
map.put(TAG_LENGTH, length);
map.put(TAG_CINEMA, cinema);
map.put(TAG_SCHEDULES, schedules);
map.put(TAG_URL, url);
// adding HashList to ArrayList
movieList.add(map);
//String strURL = TAG_URL.replaceAll(" ", "%20");
/**
* Updating parsed JSON data into ListView
* */
ListAdapter adapter = new SimpleAdapter(MainActivity.this, movieList,
R.layout.list_item,
new String[] { TAG_NAME, TAG_CINEMA, TAG_SCHEDULES },
new int[] { R.id.name, R.id.cinema, R.id.schedules });
//new String[] {},
//new int[] {});
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 name = ((TextView) view.findViewById(R.id.name)).getText().toString();
String cost = ((TextView) view.findViewById(R.id.cinema)).getText().toString();
String description = ((TextView) view.findViewById(R.id.schedules)).getText().toString();
//String url = ((TextView) view.findViewById(R.id.image_)).getText().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
in.putExtra(TAG_NAME, name);
in.putExtra(TAG_CINEMA, cost);
in.putExtra(TAG_SCHEDULES, description);
//in.putExtra(TAG_URL, url);
startActivity(in);
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
This code is working on SDK 8, but not working on 17. I'm stuck with this problem. Does anyone here know how to debug this? I'd gladly appreciate your help. thanks.
You can't make network calls on the main thread since API 11 (3.0). Read more here:
http://www.androiddesignpatterns.com/2012/06/app-force-close-honeycomb-ics.html
You have to put your code inside an AsyncTask , it is forbidden to download anything on the main UI thread since API 14 I believe.
It would be something like this:
public class someTask extends AsyncTask<String, Void, String> {
public MainActivity activity;
public someTask(MainActivity a)
{
activity = a;
}
#Override
protected String doInBackground(String... urls) {
String stringtoparse=null;
for (String url : urls) {
stringtoparse= readMovieSchedules(url); // getting XML from URL
}
return stringtoparse;
}
#Override
protected void onPreExecute(){
}
#Override
protected void onPostExecute(String readMovieSchedules) {
// Hashmap for ListView
ArrayList<HashMap<String, String>> movieList = new ArrayList<HashMap<String, String>>();
JSONArray jsonArray = new JSONArray(readMovieSchedules);
Log.i(MainActivity.class.getName(),
"Number of entries " + jsonArray.length());
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.i(MainActivity.class.getName(), jsonObject.getString("movie_name"));
// Storing each json item in variable
String name = jsonObject.getString(TAG_NAME);
String type = jsonObject.getString(TAG_TYPE);
String length = jsonObject.getString(TAG_LENGTH);
String cinema = jsonObject.getString(TAG_CINEMA);
String schedules = jsonObject.getString(TAG_SCHEDULES);
String url = jsonObject.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_NAME, name);
map.put(TAG_TYPE, type);
map.put(TAG_LENGTH, length);
map.put(TAG_CINEMA, cinema);
map.put(TAG_SCHEDULES, schedules);
map.put(TAG_URL, url);
// adding HashList to ArrayList
movieList.add(map);
}
}
You have to modify the readMovieSchedules() to take the url as an argument like this readMovieSchedules(url) and I think it'll work just fine, you would call the task like this:
getMovieSched task = new someTask(MainActivity.this);
task.execute(url);
ASyncTask is specifically made for scenarios like this. It allows you to communicate over the network in a seperate thread without you needing to work with threads.
ASyncTask has these methods :
onPreExecute() : this is invoked before the main processing happens ... one use of it would be to start the progress dialog notifying the user of the transaction.
doInBackground() : this is where you perform data exchange from the network . no UI fiddling around here.
onProgressUpdate() : can be used to notify progress of the transaction
onPostExecute() : dismiss the progressDialogs/bars and update your views from the fetched data!
another solution would be to use runOnUiThread() but this is discouraged!
class nwthread extends AsyncTask<Void,Void,Void>
{
#Override
protected void onPreExecute() {
//progress dialog invoke ( notifies the user about whats going on better than making them stare on a blank screen)
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
//make http request/parse json here
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
//dismiss progress dialog
// update the UI here ... ie declare adapters / bind them, update other views
}
}
finally invoke nwthread.execute(); after setContentView();
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! : )