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

Blog Reader - JSON Exception

I'm trying to figure out why my script is throwing a JSON exception

package com.duelingsquids.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.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Html;
import android.util.Log;
import android.view.Menu;
import android.view.View;
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(isNetworkAvailable()){
        mProgressBar.setVisibility(View.VISIBLE);
        GetBlogPostsTask getBlogPostsTask = new GetBlogPostsTask();
        getBlogPostsTask.execute();
    }else{
            Toast.makeText(this, "Network is unavailable!",          Toast.LENGTH_LONG).show();
        }

}

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

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

    return isAvailable;
    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main_list, menu);
    return true;    }



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_1, keys, ids);
            setListAdapter(adapter);

        } catch (JSONException e) {
            Log.e(TAG,"Exception Caught! Boom");
        }

    }

}

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);
                Log.v(TAG, responseData);

                jsonResponse = new JSONObject(responseData);

            }else{
                Log.i(TAG, "Uncessful HTTP Response Code: " + responseCode);
            }
            Log.i(TAG, "Code: " + responseCode);
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            Log.e(TAG, "Exception Caught", e);
        } catch (IOException e){
            Log.e(TAG, "Exception Caught", e);
        } catch (Exception e){
            Log.e(TAG, "Exception Caught", e);
        }

        return jsonResponse;
    }

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

}

}

Specifically it's the error "Exception Caught! Boom"

1 Answer

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

Well, I found your error. I ran it with the debugger and found that it was throwing the exception at this line:

JSONArray jsonPosts = mBlogData.getJSONArray("Posts");

I then looked at the data for one single post by using this URL: http://blog.teamtreehouse.com/api/get_recent_summary/?count=1

Data:

{
  status: "ok",
  count: 1,
  count_total: 1507,
  pages: 1507,
  posts: [
    {
      id: 22263,
      url: "http://blog.teamtreehouse.com/getting-started-with-the-history-api",
      title: "Getting Started With The History API",
      date: "2013-09-10 14:30:36",
      author: "Matt West",
      thumbnail: "http://blog.teamtreehouse.com/wp-content/uploads/2013/09/history-api-150x150.jpg"
    }
  ]
}

The problem? JSON is case-sensitive (just like Java and many other programming languages). That should be enough information to point out your error. :smile:

That was it! Thank you very much. One other thing I can't seem to find now, however, is where in LogCat you found the line number. I'm trying to google that now.

I think I just figured it out. The reason I cannot find the "error" in LogCat is because the error is being logged in the try catch. So Eclipse doesn't throw the actual error causing element because it's not actually putting it through because it failed. Thanks again Ben! You pointed me in the right direction without giving the answer a way and let me figure it out for myself so I can learn to do it. Much more appreciated than just giving the answer away.

Ben Jakuben
Ben Jakuben
Treehouse Teacher

Awesome - so glad you got it! We definitely try to avoid just giving the answers here. :)