Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

Getting JSON data from own website

Hi, I'm having trouble understanding why I can't display the content from the "latest news" section from this website: http://www.ilovelimerick.ie/

I used the json api plug in and can see it in json format:

http://www.ilovelimerick.ie/?json=1

When I copy and paste the json url replacing the Tree House Blog one that Ben used, the content isn't displaying. Can anyone tell me what else to change?

Thanks

16 Answers

Ethan Lowry
PLUS
Ethan Lowry
Courses Plus Student 7,323 Points

You might be on to something there, try replacing your KEY_AUTHOR variable and all its uses with a field your JSON does have like 'description' instead.

Also, your URL should be changed slightly so that its "http://www.ilovelimerick.ie/?json=1&count="+NUM_OF_POSTS, as the URL you're currently using is not doing what you expect.

Ethan Lowry
PLUS
Ethan Lowry
Courses Plus Student 7,323 Points

Does it cause any errors in your app or does it simply return something other than what you are expecting? Are you printing the returned content to your Log or anything similar? If not try logging what you get back from your http request and see if everything is what you expect.

The app loads but the error message comes up "error getting data from website". In terms of the log it doesn't seem to be grabbing the data either. I can't see the Json data listed in the log cat

Ethan Lowry
PLUS
Ethan Lowry
Courses Plus Student 7,323 Points

Could you post your code for getting and displaying the JSON here? I don't have the referenced tutorial code handy.

```package com.neils.blogreader;

import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap;

import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;

import android.app.AlertDialog; import android.app.ListActivity; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.text.Html; import android.util.Log; import android.view.View; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast;

public class MainListActivity extends ListActivity {

public static final int NUMBER_OF_POSTS = 20;
public static final String TAG = MainListActivity.class.getSimpleName();
protected JSONObject mBlogData;
protected ProgressBar mProgressBar;

private final String KEY_TITLE = "title";
private final String KEY_AUTHOR = "author";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_list);

    mProgressBar = (ProgressBar) findViewById(R.id.progressBar1);

    if(NetworkIsAvailable())    {
        mProgressBar.setVisibility(View.VISIBLE);
        GetBlogPostsTask getBlogPostsTask = new GetBlogPostsTask();
        getBlogPostsTask.execute();
    }
    else {
        Toast.makeText(this, "Network is unavailable!", Toast.LENGTH_LONG).show();
    }

    //String message = getString(R.string.no_items);
    //Toast.makeText(this, message, Toast.LENGTH_LONG).show();

}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    super.onListItemClick(l, v, position, id);
    try {
    JSONArray jsonPosts = mBlogData.getJSONArray("posts");
    JSONObject jsonPost = jsonPosts.getJSONObject(position);
    String blogUrl = jsonPost.getString("url");

    Intent intent = new Intent(this,BlogWebViewActivity.class);
    intent.setData(Uri.parse(blogUrl));
    startActivity(intent);
}
    catch (JSONException e) {
        logException(e);
    }
}

private void logException(Exception e) {
    Log.e(TAG, "Exception caught!", e);
}

private boolean NetworkIsAvailable() {
    ConnectivityManager manager = (ConnectivityManager) 
            getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = manager.getActiveNetworkInfo();

    boolean isAvailable = false;
    if(networkInfo != null && networkInfo.isConnected()) {
        isAvailable = true;
    }
    return isAvailable;
}

public void handleBlogResponse() {
    mProgressBar.setVisibility(View.INVISIBLE);
    if (mBlogData == null) {
        updateDisplayForError();
    }
    else {
        try {
            JSONArray jsonPosts = mBlogData.getJSONArray("posts");
            ArrayList<HashMap<String, String>> blogPosts = new ArrayList<HashMap<String, String>>();
            for (int i = 0; i < jsonPosts.length(); i++) {
                JSONObject post = jsonPosts.getJSONObject(i);
                String title = post.getString(KEY_TITLE);
                title = Html.fromHtml(title).toString();
                String author = post.getString(KEY_AUTHOR);
                author = Html.fromHtml(author).toString();

                HashMap<String, String> blogPost = new HashMap<String, String>();
                blogPost.put(KEY_TITLE, title);
                blogPost.put(KEY_AUTHOR, author);

                blogPosts.add(blogPost);
            }
            String[] keys = { KEY_TITLE, KEY_AUTHOR };
            int[] ids = { android.R.id.text1, android.R.id.text2 };
            SimpleAdapter adapter = new SimpleAdapter(this, blogPosts, android.R.layout.simple_list_item_2, keys, ids);
            setListAdapter(adapter);
        } catch (JSONException e) {
            logException(e);
        }
    }

}


private void updateDisplayForError() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);    
    builder.setTitle(getString(R.string.error_title));
    builder.setMessage(getString(R.string.error_message));
    builder.setPositiveButton(android.R.string.ok, null);
    AlertDialog dialog = builder.create();
    dialog.show();

    TextView emptyTextView = (TextView) getListView().getEmptyView();
    emptyTextView.setText(getString(R.string.no_items));
}

private class GetBlogPostsTask extends AsyncTask<Object, Void, JSONObject> {

    @Override
    protected JSONObject doInBackground(Object... arg0) {
           int responseCode = -1;
           JSONObject jsonResponse = null;
           try{
                URL blogFeedUrl = new URL("http://blog.teamtreehouse.com/api/get_recent_summary/?count=" + NUMBER_OF_POSTS);
                HttpURLConnection connection = (HttpURLConnection) blogFeedUrl.openConnection();
                connection.connect();

                responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = connection.getInputStream();
                    Reader reader = new InputStreamReader(inputStream);
                    int contentLength = connection.getContentLength();
                    char [] charArray = new char[contentLength];
                    reader.read(charArray);
                    String responseData = new String(charArray);

                    jsonResponse = new JSONObject(responseData);
                }
                else {
                Log.i(TAG, "Unsuccessful HTTP Response Code: " + responseCode);
                }
            }
            catch (MalformedURLException e) {
                logException(e);
            }
            catch (IOException e) {
                logException(e);
            }
            catch (Exception e) {
                logException(e);
            }

           return jsonResponse;
    }

    @Override
    protected void onPostExecute(JSONObject result) {
        mBlogData = result;
        handleBlogResponse();
    }

}

}```

Thats the main activity containing the JSON url etc.

Try to change:

'''public static final int NUMBER_OF_POSTS = 20;

to

'''public static final int NUMBER_OF_POSTS = 5;

I am not sure if it will make a difference, but it might affect the final output.

In addition can you please write down here the output from 'LogCat' or 'Problems' panel in Eclipse.

Tried changing to 5 and still an error, BUT when I did it with the tutorial code it worked so I don't think it could be that. Here is whats in red in the log cat:

02-05 17:39:11.157: E/MainListActivity(1216): Exception caught!

02-05 17:39:11.157: E/MainListActivity(1216): java.lang.NegativeArraySizeException: -1

02-05 17:39:11.157: E/MainListActivity(1216): at com.neils.blogreader.MainListActivity$GetBlogPostsTask.doInBackground(MainListActivity.java:161)

02-05 17:39:11.157: E/MainListActivity(1216): at com.neils.blogreader.MainListActivity$GetBlogPostsTask.doInBackground(MainListActivity.java:1)

02-05 17:39:11.157: E/MainListActivity(1216): at android.os.AsyncTask$2.call(AsyncTask.java:288)

02-05 17:39:11.157: E/MainListActivity(1216): at java.util.concurrent.FutureTask.run(FutureTask.java:237)

02-05 17:39:11.157: E/MainListActivity(1216): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)

02-05 17:39:11.157: E/MainListActivity(1216): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)

02-05 17:39:11.157: E/MainListActivity(1216): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)

02-05 17:39:11.157: E/MainListActivity(1216): at java.lang.Thread.run(Thread.java:841)

sorry forgot to say that the "problems" panel shows no errors!

Ethan Lowry
PLUS
Ethan Lowry
Courses Plus Student 7,323 Points

Ok so the error we're working with is NegativeArraySizeException. Could you try printing out the value of 'contentLength' (in your GetBlogPostsTask class) to your log and see what it is? ( Log.d("YourLogTag", "CONTENT LENGTH IS: "+contentLength) ) You are using this to set the size of your charArray before reading from it, so if for some reason contentLength is, say, -1 instead of the expected value, then this may be the cause of the error we're seeing.

where would I place ( Log.d("YourLogTag", "CONTENT LENGTH IS: "+contentLength) ) in the area of code? Sorry I'm very new to android!

Ethan Lowry
PLUS
Ethan Lowry
Courses Plus Student 7,323 Points

No worries, just immediately after 'int contentLength = connection.getContentLength();' would be fine.

so this is what I got:

02-05 19:35:02.437: D/BlogReader(1275): CONTENT LENGTH IS: -1

Ethan Lowry
PLUS
Ethan Lowry
Courses Plus Student 7,323 Points

Alright so in doing that we've confirmed this is where the problem lies, notice how the contentLength value -1 matches up with the error in your stack trace:

02-05 17:39:11.157: E/MainListActivity(1216): Exception caught! 02-05 17:39:11.157: E/MainListActivity(1216): java.lang.NegativeArraySizeException: -1

Sadly right now I'm not sure why you're getting an empty response...the code you posted still has the treehouse URL in it, could you post the version of that bit of the code with your own URL inserted to make sure you haven't broken anything in that regard?

Barring that I'm not sure what to suggest as your site is certainly returning JSON content correctly as you demonstrated...hopefully someone else will come along who can suggest more.

@Override protected JSONObject doInBackground(Object... arg0) { int responseCode = -1; JSONObject jsonResponse = null; try{ URL blogFeedUrl = new URL("http://www.ilovelimerick.ie/?json=1" + NUMBER_OF_POSTS); HttpURLConnection connection = (HttpURLConnection) blogFeedUrl.openConnection(); connection.connect();

                responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = connection.getInputStream();
                    Reader reader = new InputStreamReader(inputStream);
                    int contentLength = connection.getContentLength();
                    Log.d("BlogReader", "CONTENT LENGTH IS: "+contentLength);
                    char [] charArray = new char[contentLength];
                    reader.read(charArray);
                    String responseData = new String(charArray);

                    jsonResponse = new JSONObject(responseData);
                }
                else {
                Log.i(TAG, "Unsuccessful HTTP Response Code: " + responseCode);
                }
            }
            catch (MalformedURLException e) {
                logException(e);
            }
            catch (IOException e) {
                logException(e);
            }
            catch (Exception e) {
                logException(e);
            }

           return jsonResponse;
    }

My guess was maybe I'm not targeting it in the correct way because in the tutorial for getting the heading and author etc. it's:

public void handleBlogResponse() { mProgressBar.setVisibility(View.INVISIBLE); if (mBlogData == null) { updateDisplayForError(); } else { try { JSONArray jsonPosts = mBlogData.getJSONArray("posts"); ArrayList<HashMap<String, String>> blogPosts = new ArrayList<HashMap<String, String>>(); for (int i = 0; i < jsonPosts.length(); i++) { JSONObject post = jsonPosts.getJSONObject(i); String title = post.getString(KEY_TITLE); title = Html.fromHtml(title).toString(); String author = post.getString(KEY_AUTHOR); author = Html.fromHtml(author).toString();

                HashMap<String, String> blogPost = new HashMap<String, String>();
                blogPost.put(KEY_TITLE, title);
                blogPost.put(KEY_AUTHOR, author);

                blogPosts.add(blogPost);
            }
            String[] keys = { KEY_TITLE, KEY_AUTHOR };
            int[] ids = { android.R.id.text1, android.R.id.text2 };
            SimpleAdapter adapter = new SimpleAdapter(this, blogPosts, android.R.layout.simple_list_item_2, keys, ids);
            setListAdapter(adapter);
        } catch (JSONException e) {
            logException(e);
        }
    }

}

Maybe because its trying to target an author but I don't have an author specified on the site!