0

I've done the following code to show a simple twitter feed, yet it comes up with an error. It may be because I'm doing fragments, but I'm not sure. I followed a tutorial on how to create a twitter feed so it should've worked, but I don't know. Can you guys find the problem?

package info.android.icecreamparties;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Fragment;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class HomeFragment extends Fragment {

TextView tweetTextView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 

{


    View rootView = inflater.inflate(R.layout.fragment_home, container, false);

    TextView about = (TextView)rootView.findViewById(R.id.homepageintro);
    Typeface bb = Typeface.createFromAsset(getActivity().getAssets(), "BebasNeue.otf");
    about.setTypeface(bb);

    String twitterTimeline = getTwitterTimeline();
    try {
     String tweets = "";
     JSONArray jsonArray = new JSONArray(twitterTimeline);
     for (int i = 0; i < jsonArray.length(); i++) {
      JSONObject jsonObject = jsonArray.getJSONObject(i);
      int j = i + 1;
      tweets += "Tweet #" + j + " \n";
      tweets += "Date:" + jsonObject.getString("created_at") + "\n";
      tweets += "Post:" + jsonObject.getString("text") + "\n\n";
     }
     tweetTextView = (TextView)rootView.findViewById(R.id.twitterfeed);
     tweetTextView.setText(tweets);
    } catch (JSONException e) {
     e.printStackTrace();
    }
    return rootView;
   }

   public String getTwitterTimeline() {
    StringBuilder builder = new StringBuilder();
    HttpClient client = new DefaultHttpClient();
    HttpGet httpGet = new HttpGet(
      "http://api.twitter.com/1/statuses/user_timeline/BBCNews.json?count=10&include_rts=1&callback=?");
    try {
     HttpResponse response = client.execute(httpGet);
     StatusLine statusLine = response.getStatusLine();
     int statusCode = statusLine.getStatusCode();
     if (statusCode == 200) {
      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);
      }
     } else {
      // Display couldn't obtain the data from twitter
     }
    } catch (ClientProtocolException e) {
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
    return builder.toString();
   }

}
  • [See this example of AsyncTask](http://stackoverflow.com/questions/18898039/using-asynctask/18898105#18898105) put your network code in `doInBackground()` and update `UI` in other methods. – codeMagic Feb 04 '14 at 21:48
  • 1
    Grrrrrrr. Search first! Do you think you are the first person to see this? – Simon Feb 04 '14 at 21:58

4 Answers4

1

You need to call getTwitterTimeline on a non-UI thread. Call it from an AsyncTask or a Loader. Something like (blind code in Notepad++):

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.fragment_home, container, false);
    TextView about = (TextView)rootView.findViewById(R.id.homepageintro);
    Typeface bb = Typeface.createFromAsset(getActivity().getAssets(), "BebasNeue.otf");
    about.setTypeface(bb);
    new AsyncTask<Void, Void, String>() {
        public String doInBackground(Void ... params) {
            return getTwitterTimeline();
        }
        protected void onPostExecute(String twitterTimeline) {
            try {
                String tweets = "";
                JSONArray jsonArray = new JSONArray(twitterTimeline);
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    int j = i + 1;
                    tweets += "Tweet #" + j + " \n";
                    tweets += "Date:" + jsonObject.getString("created_at") + "\n";
                    tweets += "Post:" + jsonObject.getString("text") + "\n\n";
                }
                TextView tweetTextView = (TextView)rootView.findViewById(R.id.twitterfeed);
                tweetTextView.setText(tweets);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }.execute();
    return rootView;
}
gunar
  • 14,660
  • 7
  • 56
  • 87
  • Yes, a Loader is also a good choice, but you need to use the support loader to reach back before API 11. See: https://developer.android.com/reference/android/content/Loader.html and https://developer.android.com/reference/android/support/v4/content/Loader.html – Nick Palmer Feb 04 '14 at 21:48
  • I tried this, but there seems to be errors on the protected void onPostExecute(String) and public String doInBackground(Void ...) . Variable declarators error – user3198241 Feb 05 '14 at 00:07
  • As said, blind coding with Notepat++ ... fixed the errors, you can give it a shot. – gunar Feb 05 '14 at 06:38
0

You need to run the getTwitterTimeline in another thread. I suggest creating an AsyncTask in the onCreateView(). The exception you are getting is because the UI cannot be drawn while you are waiting for twitter to come back with an answer. Thus the "Network on Main Thread" issue.

See here:

http://developer.android.com/reference/android/os/AsyncTask.html

Nick Palmer
  • 2,589
  • 1
  • 25
  • 34
0

Use AsyncTask class to get your twitter data, you can't use UI thread for getting data from network.

Orhan Obut
  • 8,756
  • 5
  • 32
  • 42
0

You are placing network communication on the main thread. You are not allowed to do so. You can use AsyncTask

http://developer.android.com/reference/android/os/AsyncTask.html 

Just for testing you can add the following in your Main Activity but it is consider bad practice.

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy); 
android_dev_
  • 412
  • 2
  • 6