Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Android

Trying to retrieve data from my own blog! Help

This is my second time going through the blogReader app videos but this time I'm trying to use my own blog. It's a wordpress based blog and I've already installed the JSON API plugin but when i try to retrieve the JSON data from http://www.grepscience.com/api/get_recent_posts/ in tthe Log Cat i get the errors java.lang.NegativeArraySizeException:-1 at com.grepscience.grepreader.MainListActivity&GetBlogPostsTask.doInBackground(MainListActivity.java:82)

I think it has to do with the size of the JSON file but not sure. Can someone help me with this please!

Thanks

17 Answers

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

Thanks also to @Fabian and @Vivek! This seems to be a strong solution based on the code @Fabian provided in the other post. Try replacing your doInBackground() method with this code (you'll have to reorganize your imports):

@Override
protected JSONObject doInBackground(Object... params) {
    int responseCode = -1;
    JSONObject jsonResponse = null;
    StringBuilder builder = new StringBuilder();
    HttpClient client = new DefaultHttpClient();
    HttpGet httpget = new HttpGet("http://www.grepscience.com/api/get_recent_summary/");

    try {
        HttpResponse response = client.execute(httpget);
        StatusLine statusLine = response.getStatusLine();
        responseCode = statusLine.getStatusCode();

        if (responseCode == HttpURLConnection.HTTP_OK) {
            HttpEntity entity = response.getEntity();
            InputStream content = entity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(content));
            String line;
            while((line = reader.readLine()) != null){
                builder.append(line);
            }

            jsonResponse = new JSONObject(builder.toString());
        }
        else {
            Log.i(TAG, String.format("Unsuccessful HTTP response code: %d", responseCode));
        }
    }
    catch (JSONException e) {
        logException(e);
    }
    catch (Exception e) {
        logException(e);
    }           

    return jsonResponse;
}   

I ran into that problem too, the char array was malformed. I wasn't satisfied with the fixes in this thread, because they change how the entire method works and don't explain what they do with terms known to someone following this track. Here's a fix with comments that only changes a few lines.

Delete those lines:

    int contentLength = connection.getContentLength();
    char[] charArray = new char[contentLength];
    reader.read(charArray);
    String responseData = new String(charArray);

Replace them with those:

    int nextCharacter; // read() returns an int, we cast it to char later
    String responseData = "";
    while(true){ // Infinite loop, can only be stopped by a "break" statement
        nextCharacter = reader.read(); // read() without parameters returns one character
        if(nextCharacter == -1) // A return value of -1 means that we reached the end
            break;
        responseData += (char) nextCharacter; // The += operator appends the character to the end of the string
    }
Ben Jakuben
Ben Jakuben
Treehouse Teacher

Great fix, Hubert! Thanks so much for sharing in this post.

Hi @Hubert,

Thank you as much for the fix , as much for the explanations that Ive learned a lot from and are clearly identifing the problem.

Cheers m8 :)

can you please upload the whole mainactivity after you have done the next 3-4 videos. because after the video where we start getting problem when I try to to do the next one I get more problems!

11-10 02:15:58.238 1179-1201/qax.khabaralyoum E/MainListActivity﹕ Exception caught: org.json.JSONException: End of input at character 1 of { at org.json.JSONTokener.syntaxError(JSONTokener.java:450) at org.json.JSONTokener.nextValue(JSONTokener.java:97) at org.json.JSONTokener.readObject(JSONTokener.java:362) at org.json.JSONTokener.nextValue(JSONTokener.java:100) at org.json.JSONObject.<init>(JSONObject.java:155) at org.json.JSONObject.<init>(JSONObject.java:172) at qax.khabaralyoum.MainListActivity$GetBlogPostsTask.doInBackground(MainListActivity.java:101) at qax.khabaralyoum.MainListActivity$GetBlogPostsTask.doInBackground(MainListActivity.java:78) at android.os.AsyncTask$2.call(AsyncTask.java:288) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) at java.lang.Thread.run(Thread.java:841)

Do I add this to the fix or the code form the track? Im confused!

Ben Jakuben
Ben Jakuben
Treehouse Teacher

Qasim Albaqali, I'll be replacing this course with three new courses that will teach the same concepts in hopefully a more understandable manner. The first of the new courses is due in about a week and I'll be working to get the others out as soon as possible. Sorry for the confusion around this specific part!

Roman Kozak
Roman Kozak
3,119 Points

Worked for me. Thanks Hubert!

Nitesh Chand
Nitesh Chand
1,592 Points

Any solutions for blogger blog?? Thanks

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

Hi @Peter,

Awesome to see you and others adapting this for other blogs! I have a quick semi-solution and a longer term fix that I need to figure out when I'm fresh in the morning.

First, you'll want to switch to the same web service call as we use in the video to reuse the same code. You are using get_recent_posts, but our code is formatted to parse data from get_recent_summary. Take a look at both in your browser to see the differences:

Second, for now, you'll want to limit the get_recent_summary to 14 or fewer articles, like this:

Why? There is some sort of error in the code right now with special characters in JSON. In this case it is the dollar sign in your (current) 15th article: "Dark Matter Possibly Found by $2 Billion Space Station Experiment"

So I've been debugging this for a while, trying to escape or replace the special character in different ways. The weird thing is, I can get it to work correctly simply by running it in debug mode. I don't need to change anything or break anywhere, but with the debugger attached it lets it finish and display properly. I will look into this more and update this post when I get a solution.

Hope this helps!

Kevin Moslehpour
Kevin Moslehpour
4,119 Points

Hi Ben Jakuben,

No matter what I put for the count= (http://blog.teamtreehouse.com/api/get_recent_summary/?count=" + NUMBER_OF_POSTS) it only displays 10 items. In the tutorial you mentioned to use count = 20 however, this only displays 10 for some reason.

Could you please advise. Also I noticed the links you used in the above thread are different then this one http://blog.teamtreehouse.com/api/get_recent_summary/?count=" + NUMBER_OF_POSTS. Why is that?

Martin Turjak
Martin Turjak
3,062 Points

I experienced the same (or very similar) problem ... and I think the code provided in the above accepted answer helped me get around it. See my question/answer here: https://teamtreehouse.com/forum/query-string-removed-from-the-url-in-httpurlconnection-connection-after-any-get-method-called

Vivek Marakana
Vivek Marakana
16,412 Points

@Ben This is not because of get_recent_posts , It just reply with more size.

This error is because of HTTP headers. Sometimes WordPress doesn't send Content-Legnth header so the error appears in following line :

int contentLength = connection.getContentLength();

you get contentLength = -1;

So i have edited the plugin for wordpress and i am going to put it online.

@Peter Log the contentLength in Log cat, if you get contentLength value = -1 then this will be your problem. If so reply me so that i will describe it in length..

I have developed this app for my WordPress blog and its working plus i have implemented some extra features like offline reading.

Happy to help further..

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

@Vivek,

Wow, thanks for all your research on this issue! (All, see his other answer, too.)

You can use get_recent_posts to get JSON from the server, but the data returned is in a different format than get_recent_summary. That's why you would need to change to that call for it to just work the same with the code from the videos.

Now, as for the Content-Length property, I have not been able to reproduce that with the Treehouse blog or the blog from this post. I have, however, recreated it using the URL from the other post about this issue where you provide an awesome solution. Shame on me for coding it in a way that assumes the Content-Length property will be returned. I have to figure out how best to fix this within the project.

Finally, back to the "special character" issue I was discussing in my previous answer...now I can't recreate it consistently. Sometimes it works, sometimes it doesn't, and the Content-Length appears to be set either way whether it fails or succeeds. I'm going to put this specific issue to rest for now and instead fix the code so that Content-Length is not required at all in the client (kind of like @Fabian's solution in the other post). We don't have an exact system for fixing errors in videos like this, but I'll figure something out!

Thanks for your reply so soon @Ben. I can't believe I didn't catch that. The get_recent_summary looks more like what you were showing in the video. Unfortunately that didn't fix the issue but that is something that needed to be changed anyways. I appreciate you taking the time to look a little deeper for me also.

@ Vivek not sure how i'm suppose to Log the contentLength. Do I add another catch() with the Log.e(TAG,"Exception caught: ",e) code and if so where do I place it? Nice to see somebody has ran into the same issue using a WordPress blog and hopefully this can be a quick fix.

Thank you both for your responses. I Love Treehouse!

@Ben Your awesome! Once again thanks for taking the time in helping me out. Ok so after I replacing my doInBackground method with this new block of code i'm getting an error for the logException. It says "The method logException(JSONException) is undefined for the type MainListActivity.GetBlogPostsTask" Do I create method logException(JsonException)? Sorry if I can't figure this one out but before 2 months ago I had zero experience in coding. I do appreciate the help though and hopefully with the help from Treehouse and all the people in this community like @Vivek I'll become a pro. lol

Vivek Marakana
Vivek Marakana
16,412 Points

@Peter to see the output in LogCat for contentLength after int contentLength = connection.getContentLength(); write Log.i(TAG, "Length - " + contentLength);

@Peter and @Ben I have changed the default plugin i have written another or rather edited that one..

Download it from :

http://demo.htmlcsstutor.com/blogreaderapp/wp-json-api.rar

Then instead of int contentLength = connection.getContentLength(); Write

int contentLength = connection.getContentLength();
if(contentLength == -1)
        contentLength = connection.getHeaderFieldInt("Length", -1);

Note : please use get_recent_summary instead of get_recent_posts.. That call is removed in this version..

Hope this will help..It works fine with my app : http://demo.htmlcsstutor.com/blogreaderapp/HTMLCSSTutor.apk

Vivek you are a lifesaver

Vivek Marakana
Vivek Marakana
16,412 Points

@Ben No offence but displaying webpage based on URL doesn't look good when website in not running on responsive template (like mine). So i went ahead for the fetching post content in JSON format and display it in WebView as HTML. Images will be downloaded over the internet.. I also stored the html data once to show later offline.

And about that "special character" issue and "timeout exception". It is because of inconsistency of the bandwidth. Sometimes the response break in-between so we get "unidentified character error".. So i went for another approach i.e. Displaying post by one by one.. You can see that in my app. I have only three posts on my blog right now, so i set the MAX_POST=2. So when you first start the app then two posts will be loaded and then when you tap on the refresh, another (i.e. third) post will show up..And article list is also stored offline so that you have something to read even when you are in flight mode :)

and further I think it is good idea to display post one by one when you have large number of posts.. I have implemented that feature in my edited JSON plugin..

And one more question i have got for you @Ben - Is there any problem in starting more than one AsyncTasks in background rather than only one? I have done this in my app and working fine but just wanted to know that is there any harm in that?

Vivek Marakana thanks for the wordpress plugin, it works great for my site and I am no longer the issues that I was getting before. Now, my problem is parsing the URL like you say does not look so nice, since it pulls everything from my responsive design including the header, footer and other stuff that is not that important at the moment.

Could you please share the code you use to just display a section of the html that includes just the post and the author, saving it for offline reading, and refreshing.

I would highly appreciate. I am downloading your app now for testing. Great work....

Ben Jakuben
Ben Jakuben
Treehouse Teacher

Hi Victor,

This is a pretty old thread. Would you mind posting your question with more details as a whole new thread? Thanks!

Wow @Vivek that worked perfect. I'm now getting the JSON data successfully in Log Cat. This was a excellent lesson for me. I just downloaded your app too. Nice! I like the "Tap to refresh" feature you added. What I would like to see from Treehouse is how to make the slide out menu like Evernote, Google+, Facebook and a lot of other big name apps have. Since I have different categories on by blog i'd like to have a slide out menu with all the different categories in it.

Thanks again Vivek!

Vivek Marakana
Vivek Marakana
16,412 Points

@Peter If you want menu like that then i suggest you to read following articles and the successive articles..

Hope it will help..

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

Hi @Vivek,

For your question about AsyncTasks - absolutely no problem at all! You can launch as many as you want, but if you want to truly run them in parallel you need to use a different method to execute them called executeOnExecutor. I had to check about that - here's a StackOverflow question that talks about the limit of concurrent AsyncTasks: http://stackoverflow.com/a/13800208/475217 (Read the whole thread if interested for more details)

Also, thanks again for all your help in the forum and tips and suggestions. Some of the design decisions for this app were simply based on time and ease of teaching the main concepts. Offline mode and a few other things have been tabled for a project that would enhance this app.

Ben Jakuben
STAFF
Ben Jakuben
Treehouse Teacher

Oh, and @Peter, check out SlidingMenu for an open-source implementation of that kind of side navigation. Good stuff. :smile: Here's a downloadable demo from Google Play: https://play.google.com/store/apps/details?id=com.slidingmenu.example

Hey guys, does anyone have a solution if your wordpress theme isn't responsive, how to make it respond well....instead of having to scroll around the web page?

Adedara Olanrewaju
Adedara Olanrewaju
398 Points

Here is my own error::

06-07 14:55:25.341 345-345/? I/SELinux: Function: selinux_android_load_priority [0], There is no sepolicy file.

06-07 14:55:25.341 345-345/? I/SELinux: Function: selinux_android_load_priority [1], There is no sepolicy version file.

06-07 14:55:25.341 345-345/? I/SELinux: Function: selinux_android_load_priority , priority version is VE=SEPF_GT-N7100_4.4.2_0035

06-07 14:55:25.341 345-345/? I/SELinux: selinux_android_seapp_context_reload: seapp_contexts file is loaded from /seapp_contexts 06-07 14:55:25.346 345-345/? D/dalvikvm: Late-enabling CheckJNI 06-07 14:55:25.386 345-351/? E/jdwp: Failed writing handshake bytes: Broken pipe (-1 of 14) 06-07 14:55:25.386 345-351/? D/dalvikvm: Debugger has detached; object registry had 0 entries 06-07 14:55:25.556 345-345/? D/AbsListView: Get MotionRecognitionManager 06-07 14:55:25.676 345-345/? D/libEGL: loaded /system/lib/egl/libEGL_mali.so 06-07 14:55:25.681 345-345/? D/libEGL: loaded /system/lib/egl/libGLESv1_CM_mali.so 06-07 14:55:25.686 345-345/? D/libEGL: loaded /system/lib/egl/libGLESv2_mali.so 06-07 14:55:25.776 345-345/? D/OpenGLRenderer: Enabling debug mode 0 06-07 14:55:25.781 345-345/? D/ProgressBar: updateDrawableBounds: left = 0 06-07 14:55:25.781 345-345/? D/ProgressBar: updateDrawableBounds: top = 0 06-07 14:55:25.781 345-345/? D/ProgressBar: updateDrawableBounds: right = 152 06-07 14:55:25.781 345-345/? D/ProgressBar: updateDrawableBounds: bottom = 152 06-07 14:55:30.266 345-360/com.example.user.blogreader D/dalvikvm: GC_FOR_ALLOC freed 435K, 16% free 9376K/11144K, paused 35ms, total 35ms 06-07 14:55:33.721 345-360/com.example.user.blogreader I/MainListActivity: Unsuccessful HTTP Response Code 404