I have a problem populating separate TextView with the content from the same JSON.
Each fragment is having a ListView populated by adapter. Data is pulled from JSON file. First, I am importing data from JSONArray and adding it to object Article created separately:
JSONObject e = articlesJsonResponse.getJSONObject(i);
String title = e.getString("title");
int itemId = e.getInt("id");
Article article = new Article(title, itemId);
articles.add(article);
Then, I have created ArticleAdapter where I am putting this content into ListView. This works.
In my Activity, I am then creating a list out of that:
ListView mainListView = (ListView) findViewById(R.id.main_list);
mAdapter = new ArticleAdapter (getActivity(), new ArrayList<Article>());
mainListView.setAdapter(mAdapter);
Now, I would like to create a TextView in the same activity, which would pull "title" from the first object Article in the list.
TextView featuredImageTitle = (TextView) findViewById(R.id.featuredimage_title);
featuredImageTitle.setText(??????????);
Should I pass this info from adapter? Or from Article object? Or should I read it from the 0 position in the list I have built for the ListView?
Here is my full code which imports the content and creates the object.
public final class QueryUtils {
public QueryUtils() {
}
// Returns new URL object from the URL String
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Problem building URL", e);
}
return url;
}
// makes a HTTP request to the URL and returns String
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving articles JSON.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// Closing the input stream could throw an IOException, which is why
// the makeHttpRequest(URL url) method signature specifies than an IOException
// could be thrown.
inputStream.close();
}
}
return jsonResponse;
}
// Query the JSON info and return a list of {#link Article} objects.
public static List<Article> extractArticles(String requestUrl) {
// Create URL object
URL url = createUrl(requestUrl);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = null;
try {
jsonResponse = makeHttpRequest(url);
} catch (IOException e) {
Log.e(LOG_TAG, "Problem making the HTTP request.", e);
}
List<Article> articles = extractFromJson(jsonResponse);
// Return the list of articles
return articles;
}
/**
* Convert the {#link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return a list of {#link Article} objects that has been built up from
* parsing a JSON response.
*/
public static List<Article> extractFromJson(String articleJSON) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(articleJSON)) {
return null;
}
// Create an empty ArrayList that we can start adding earthquakes to
List<Article> articles = new ArrayList<>();
// Try to parse JSON response. If there's a problem with the way the JSON
// is formatted, a JSONException exception object will be thrown.
// Catch the exception so the app doesn't crash, and print the error message to the logs.
try {
// Create a JSONArray from the JSON response string
JSONArray articlesJsonResponse = new JSONArray(articleJSON);
// For each article in the articleArray, create an Article object
for (int i=0; i < articlesJsonResponse.length(); i++) {
// Parse the response given by the json string and
// build up a list of article objects with the corresponding data.
JSONObject e = articlesJsonResponse.getJSONObject(i);
String title = e.getString("title");
int articleId = e.getInt("id");
int views = e.getInt("views");
int comments = e.getInt("comments");
String thumb = e.getString("image");
String url = e.getString("url");
String date = e.getString("date");
Article article = new Article(title, articleId, views, comments, thumb, url, date);
articles.add(article);
}
} catch (JSONException e) {
// If an error is thrown when executing any of the above statements in the "try" block,
// catch the exception here, so the app doesn't crash. Print a log message
// with the message from the exception.
Log.e("QueryUtils", "Problem parsing JSON results", e);
}
// Return the list of articles
return articles;
}
}
If you need to access only the first object title on the list
get the 0 positions of your list but also check if list size > 0 to not give Index exception
like
if(articles.size > 0){
featuredImageTitle.setText(articles.get(0).getTitle)
}
but if you need to get the title from the clicked object in the list you need to implement OnItemClickListener to you listView
mainListView.setOnItemClickListener(new OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,int position, long arg3)
{
featuredImageTitle.setText(articles.get(position).getTitle);
}
and be sure to set android:descendantFocusability="blocksDescendants" on the first parent layout inside the list
Related
I am usind TMDb API to build a project app. Every api call gives me back 20 movies, so normally the app shows only 20 movie posters on startup. I added this code to fetch another 20 movies, using the &page= query, when the user scrolls down the grid View.
gridView.setOnScrollListener(onScrollListener());
private AbsListView.OnScrollListener onScrollListener() {
return new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
int threshold = 1;
int count = gridView.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (gridView.getLastVisiblePosition() >= count - threshold && pageCount < 2) {
Log.v(LOG_TAG, "loading more data");
// Execute LoadMoreDataTask AsyncTask
updateMovies(sortBy, true);
}
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
int totalItemCount) {
}
};
}
But this solution works really bad. If i scroll down it executes updateMovies(sortBy, true); for 2-3 times at once, jumping pages and making it impossible to read.
Also, the data shown on screen is completely replaced after every page refresh, for example if I am seeing the data on page=1 and I scroll down then i see only the data from page 2 or 3 but the original data is gone.
here is my AsyncTask
public class FetchMoviesTask extends AsyncTask<String, Void, List<Movie>> {
private final String LOG_TAG = FetchMoviesTask.class.getSimpleName();
private final static String API_KEY = "480a9e79c0937c9f4e4a129fd0463f96";
#Override
protected List<Movie> doInBackground(String... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
String jsonStr = null;
try {
final String BASE_URL = "http://api.themoviedb.org/3/movie";
final String API_KEY_PARAM = "api_key";
final String PAGE_PARAM = "page";
URL url;
if (params[1].equals("true")){
// if a bool is true
// then I intend to load an additional page
// (needed otherwise going back from detailAct loads a new increasing page
currentPage += 1;
pageCount++;
}else{
currentPage = 1;
}
if (params[0].equals(POPULARITY_DESC)){
Uri builtUri = Uri.parse(BASE_URL).buildUpon()
.appendPath("popular")
.appendQueryParameter(API_KEY_PARAM, API_KEY) // my own API key
.appendQueryParameter(PAGE_PARAM , Integer.toString(currentPage))
.build();
url = new URL(builtUri.toString());
}else if(params[0].equals(RATING_DESC)) {
Uri builtUri = Uri.parse(BASE_URL).buildUpon()
.appendPath("top_rated")
.appendQueryParameter(API_KEY_PARAM, API_KEY)// my own API key
.appendQueryParameter(PAGE_PARAM , Integer.toString(currentPage))
.build();
url = new URL(builtUri.toString());
}else {
Log.v(LOG_TAG, "Something went wrong with URI building :(");
url = new URL("ERROR URL");
}
Log.v(LOG_TAG, "URL BUILT: " + url);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
return null;
}
jsonStr = buffer.toString(); // finally parsed JSON string
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try {
return getMoviesDataFromJson(jsonStr);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
// This will only happen if there was an error getting or parsing the forecast.
return null;
}
private List<Movie> getMoviesDataFromJson(String jsonStr) throws JSONException {
JSONObject movieJson = new JSONObject(jsonStr);
JSONArray movieArray = movieJson.getJSONArray("results");
List<Movie> results = new ArrayList<>();
for(int i = 0; i < movieArray.length(); i++) {
JSONObject movie = movieArray.getJSONObject(i);
Movie movieModel = new Movie(movie); // basically Movie has already the fields to fill (image,
// description, rating, etc) and this adds those values from the JSONObject
results.add(movieModel); // it does this one object at the time, for the lenght of the array
}
return results;
}
#Override
protected void onPostExecute(List<Movie> mv) {
if (mv != null) {
if (movieGridAdapter != null) {
movieGridAdapter.clear();
for (Movie movie : mv) {
movieGridAdapter.add(movie);
}
}
movies = new ArrayList<>();
movies.addAll(mv);
}
}
}
I am trying to click a hyperlink and call method in android programming...
But the problem is , the link is not showing up and neither the method is getting called. How to achieve this result?
I am basically a javascript/jsp developer, this is my first android application , which i am learning. Accordingly i am trying to click link and call method with parameter....
Results looking like
Java code
private class CallAPI extends AsyncTask<String, String, String> {
private String Content;
#Override
protected String doInBackground(String... params) {
String urlString=params[0]; // URL to call
String resultToDisplay = "";
InputStream in = null;
emailVerificationResult result = null;
// HTTP Get
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream());
System.out.println("test");
BufferedReader reader = null;
// Get the server response
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while ((line = reader.readLine()) != null) {
// Append server response in string
sb.append(line + "\n");
}
// Append Server Response To Content String
Content = sb.toString();
} catch (Exception e ) {
System.out.println(e.getMessage());
return e.getMessage();
}
/****************** Start Parse Response JSON Data *************/
String OutputData = "<center><b><u>Weight Training</u></b></center><br/><br/>";
JSONObject jsonResponse;
try {
/****** Creates a new JSONObject with name/value mappings from the JSON string. ********/
jsonResponse = new JSONObject(Content);
/***** Returns the value mapped by name if it exists and is a JSONArray. ***/
/******* Returns null otherwise. *******/
JSONArray jsonMainNode = jsonResponse.optJSONArray("articleList");
/*********** Process each JSON Node ************/
int lengthJsonArr = jsonMainNode.length();
for (int i = 0; i < lengthJsonArr; i++) {
/****** Get Object for each JSON node.***********/
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
/******* Fetch node values **********/
String name = jsonChildNode.optString("menu_name").toString();
String number = jsonChildNode.optString("id").toString();
String date_added = jsonChildNode.optString("parent_id").toString();
OutputData += " " +
String.format("<a onClick='verifyEmail("+number+","+date_added+")'><b>"+name+"<b> "+ number+" "+ date_added+"</a> ") +"<br/><br/>";
}
/****************** End Parse Response JSON Data *************/
/* Show Parsed Output on screen (activity) */
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
resultToDisplay =OutputData ;
return resultToDisplay;
}
// This is the method that is called when the submit button is clicked
public void verifyEmail(String m,String p) {
String urlString = apiURL + "mid=" + m + "&pid=" + p;
new CallAPI().execute(urlString);
}
protected void onPostExecute(String result) {
Intent intent = new Intent(getApplicationContext(), ResultActivity.class);
intent.putExtra(EXTRA_MESSAGE, result);
startActivity(intent);
}
Update:
Instead of link, can i put a button and provide on click method and pass parameter to the method
(Thankfully) You cannot call a function using HTML tags in android. Instead try setting ClickableSpan on you you TextView to get the desired effect
SpannableString ss = new SpannableString("Click Me to do magic");
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
doSomeMagic();
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
}
};
// apply the clickable span on "Click Me" part which is on index 0 -> 7
// 8 is used because it goes from a -> b-1
ss.setSpan(clickableSpan, 0, 8, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
TextView textView = (TextView) findViewById(R.id.foo);
textView.setText(ss);
I currently implemented parsing json from a server (url). But I couldn't find a way to parse json from sdcard (/Download/example.json). Can someone help me to solve this issue/change this code?
I used asyncTask for this. sample tutorial or sample code is more appreciated. (sorry for my English.)
public class Main extends Activity {
private TextView shopsDisplay;
private static String searchURL = "http://example.com/sample.json";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.baby);
//reference throughout class
shopsDisplay = (TextView)findViewById(R.id.tweet_txt);
new GetShops().execute(searchURL);
}
private class GetShops extends AsyncTask<String, Void, String> {
/*
* Carry out fetching task in background
* - receives search URL via execute method
*/
#Override
protected String doInBackground(String... shopsURL) {
//start building result which will be json string
StringBuilder shopsFeedBuilder = new StringBuilder();
//should only be one URL, receives array
for (String searchURL : shopsURL) {
HttpClient shopsClient = new DefaultHttpClient();
try {
//pass search URL string to fetch
HttpGet shopsGet = new HttpGet(searchURL);
//execute request
HttpResponse shopsResponse = shopsClient.execute(shopsGet);
//check status, only proceed if ok
StatusLine searchStatus = shopsResponse.getStatusLine();
if (searchStatus.getStatusCode() == 200) {
//get the response
HttpEntity shopsEntity = shopsResponse.getEntity();
InputStream shopsContent = shopsEntity.getContent();
//process the results
InputStreamReader shopsInput = new InputStreamReader(shopsContent);
BufferedReader shopsReader = new BufferedReader(shopsInput);
String lineIn;
while ((lineIn = shopsReader.readLine()) != null) {
shopsFeedBuilder.append(lineIn);
}
}
else
shopsDisplay.setText("Whoops - something went wrong!");
}
catch(Exception e){
shopsDisplay.setText("Whoops - something went wrong!");
e.printStackTrace();
}
}
//return result string
return shopsFeedBuilder.toString();
}
/*
* Process result of search query
* - this receives JSON string representing shops with search term included
*/
protected void onPostExecute(String result) {
//start preparing result string for display
StringBuilder shopsResultBuilder = new StringBuilder();
try {
//get JSONObject from result
JSONObject resultObject = new JSONObject(result);
//get JSONArray contained within the JSONObject retrieved - "results"
JSONArray shopsArray = resultObject.getJSONArray("shops");
//loop through each item in the shops array
for (int t=0; t<shopsArray.length(); t++) {
//each item is a JSONObject
JSONObject shopsObject = shopsArray.getJSONObject(t);
//for if condition
String id = (String) shopsObject.get("id");
//get the name and description for each shops
if (id.equals("550")){
shopsResultBuilder.append(shopsObject.getString("name")+": ");
shopsResultBuilder.append(shopsObject.get("description")+"\n\n");
}
}
}
catch (Exception e) {
shopsDisplay.setText("Whoops - something went wrong!");
e.printStackTrace();
}
//check result exists
if(shopsResultBuilder.length()>0)
shopsDisplay.setText(shopsResultBuilder.toString());
else
shopsDisplay.setText("Sorry - no shops found for your search!");
}
}
}
For JSONObject, use standard Java file I/O to read the file into a String, then pass it to the JSONObject constructor.
If you have a large JSON file, though, you may wish to switch to some other JSON parser (e.g., JsonReader), which may give you different options (e.g., use a FileReader with JsonReader).
Hi, this is my code which load Json form resource I want to change this code to load Json from URL what do I do? How I will change this code help me please. I just want to load Json form URL help me please
private JSONObject getContent() throws IOException, JSONException
{
BufferedReader bufferedReader = null;
try
{
InputStream inStream = getResources().openRawResource(R.raw.json);
BufferedInputStream bufferedStream = new BufferedInputStream(inStream);
InputStreamReader reader = new InputStreamReader(bufferedStream);
bufferedReader = new BufferedReader(reader);
StringBuilder builder = new StringBuilder();
String line = bufferedReader.readLine();
while (line != null)
{
builder.append(line);
line = bufferedReader.readLine();
}
return new JSONObject(builder.toString());
}
finally
{
if (bufferedReader != null)
{
bufferedReader.close();
}
}
}
/**
* Populates the table in the main view with data.
*
* #param data
* the read JSON data
* #throws JSONException
*/
private void populateTable(JSONObject data) throws JSONException
{
JSONArray dataArray = data.getJSONObject("observations").getJSONArray("data");
final TableLayout table = (TableLayout) findViewById(R.id.table);
for (int i = 0; i < dataArray.length(); i++)
{
final View row = createRow(dataArray.getJSONObject(i));
table.post(new Runnable()
{
public void run()
{
table.addView(row);
}
});
}
}
/**
* Creates a row for the table based on an observation.
*
* #param item
* the JSON object containing the observation
* #return the created row
* #throws JSONException
*/
private View createRow(JSONObject item) throws JSONException
{
View row = getLayoutInflater().inflate(R.layout.rows, null);
((TextView) row.findViewById(R.id.localTime)).setText(item.getString("local_date_time_full"));
((TextView) row.findViewById(R.id.apprentTemp)).setText(item.getString("apparent_t"));
return row;
}
your code is not clear and not getting any idea, you may follow Android JSON Parsing Tutorial this will really helpful to you.
I am a beginner in Android, and I am writing a short program to download a JSON feed from URL and parse it. I use AsyncTask to do the downloading.
The doInBackground() part seems to work well. Then I set my breakpoint to onPostExecute(), it can even stop at parseJSON(result), and 'result' is showing the correct json string downloaded. But when I try to step into parseJSON(result), it will NOT step into the function correctly(either throw JSONException directly or go to some random lines within parseJSON(result)).
From DDMS log it's not showing any valuable information as well.
How might I find what the problem is? Is it because I used onPostExecute() incorrectly, or parseJSON() has some problem?
public class MainActivity extends Activity {
private listItem[] items;
public class listItem {
String title;
String description;
String imageHref;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
items = new listItem[50];
new DownloadJsonFeed().execute("http://dl.dropbox.com/u/10168342/facts.json");
}
private class DownloadJsonFeed extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
try {
return downloadUrl(params[0]);
} catch (IOException e) {
return "Unable to retrieve json feed. URL may be invalid.";
}
}
#Override
protected void onPostExecute(String result) {
try {
parseJSON(result); // Here !!!!!!
} catch (JSONException e) {
}
}
}
private String downloadUrl(String myurl) throws IOException {
InputStream is = null;
try {
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
is = conn.getInputStream();
// Convert the InputStream into a string
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
is.close();
return sb.toString();
} finally {
if (is != null) {
is.close();
}
}
}
private void parseJSON(String feed) throws JSONException {
JSONObject json_obj = new JSONObject(feed);
title = json_obj.getString("title");
String rows = json_obj.getString("rows");
JSONArray jArray = new JSONArray(rows);
for (int i = 0; i < jArray.length(); i++) {
JSONObject tmp = jArray.getJSONObject(i);
items[i].title = tmp.getString("title");
items[i].description = tmp.getString("description");
items[i].imageHref = tmp.getString("imageHref");
}
}
JSONObject.getString() will try to get String type value, but what you want is array type.
I think you didn't get the JSON array right. The json_obj.getString will give you an String instead an array.
Try to change as follows:
private void parseJSON(String feed) throws JSONException {
JSONObject json_obj = new JSONObject(feed);
title = json_obj.getString("title");
String rows = json_obj.getString("rows");
JSONArray jArray = json_obj.getJSONArray("rows"); //<---- change this line
for (int i = 0; i < jArray.length(); i++) {
JSONObject tmp = jArray.getJSONObject(i);
items[i].title = tmp.getString("title");
items[i].description = tmp.getString("description");
items[i].imageHref = tmp.getString("imageHref");
}
}