Note that there are some explanatory texts on larger screens.

plurals
  1. POParsing Twitter API 1.1 JSON
    primarykey
    data
    text
    <p>I've been working on an open source code of a Twitter reader (read only) (oauth 2.0) that pulls JSON from a user timeline. It successfully pulls the JSON from Twitter API 1.1. The challenge I'm facing is converting that JSON into something user friendly. I've implemented sections of another source code that focused on parsing the JSON, but I'm not very familiar with parsing JSON. It's patchwork so I know I might be overlooking something. Possibly a redundancy or missing part.</p> <p>UPDATED: When I run the app, it doesn't crash, it's just stuck at "Got Token!". What I'm hoping to display is a list of tweets somewhat formatted to look like one. I believe it's the MainActivity, but I could be wrong. You will need a Consumer Key and Secret to test. I'll put up what I have at the moment, but if anyone knows how I can get out of that loop, I'd appreciate your input.</p> <p>Thanks! </p> <p>MainActivity.java</p> <pre><code>package com.example.readtwitterfeed; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.json.JSONObject; import org.json.simple.JSONArray; import org.json.simple.JSONValue; import android.os.AsyncTask; import android.os.Bundle; import android.app.Activity; import android.util.Base64; import android.util.Log; import android.widget.TextView; import com.example.readtwitterfeed.R; public class MainActivity extends Activity { // CONSUMER API KEY - 21 characters (go here to get one: https://dev.twitter.com/apps/) // **** CHANGE THIS **** static final String twitterAPIKEY = "@@@@@@@@@@@@@@@@"; // CONSUMER SECRET - 41 characters (go here to get one: https://dev.twitter.com/apps/) // **** CHANGE THIS **** static final String twitterAPISECRET = "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"; static final String twitterAPIurl = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name="; // Twitter 'Screen Name' // **** CHANGE THIS **** static final String screenName = "Insert_Username_Here"; // Tweets to return // **** CHANGE THIS, if needed **** static final int tweets2Return = 1; // Final URL will look like this (@ is your sreen name/return tweets): // https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=@@@&amp;include_rts=1&amp;count=@ static String tweeterURL = twitterAPIurl + screenName + "&amp;include_rts=1&amp;count=" + tweets2Return; static String twitterToken = null; static String jsonTokenStream = null; static String jsonFeed = null; static String tweetJSON = null; TextView twitterText; // //////////////////////////////////// // onCreate - Let's get the GUI going // //////////////////////////////////// @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); twitterText = (TextView) findViewById(R.id.tweetFeed); // Call first AsyncTask new loadTwitterToken().execute(); } // //////////////////////////////////////////////////////////////////// // AsyncTask - First, let's get our Token for oAuth (from Twitter) // If you need oAuth help: https://dev.twitter.com/docs/auth/oauth/faq/ // //////////////////////////////////////////////////////////////////// protected class loadTwitterToken extends AsyncTask&lt;Void, Void, Integer&gt; { @Override protected Integer doInBackground(Void... params) { //As of this writing, Twitter says, "We do not currently expire access tokens." try { DefaultHttpClient httpclient = new DefaultHttpClient( new BasicHttpParams()); HttpPost httppost = new HttpPost( "https://api.twitter.com/oauth2/token"); String apiString = twitterAPIKEY + ":" + twitterAPISECRET; String authorization = "Basic " + Base64.encodeToString(apiString.getBytes(), Base64.NO_WRAP); httppost.setHeader("Authorization", authorization); httppost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); httppost.setEntity(new StringEntity( "grant_type=client_credentials")); InputStream inputStream = null; // Let's send to web HttpResponse response = httpclient.execute(httppost); HttpEntity entity = response.getEntity(); // Our response inputStream = entity.getContent(); BufferedReader reader = new BufferedReader( new InputStreamReader(inputStream, "UTF-8"), 8); StringBuilder sb = new StringBuilder(); String line = null; // Will look like this: // {"token_type":"bearer","access_token":"AAAAAAAAAAAAAAAAAAAAABiQTgAAAAAACGie2o%2Bm7jNnxw8txVG99c1wAU8%3DmZq7qrX8JZpDFrgYyh5gLtOkJhQ7BvPD6bZ0ssitjg"} while ((line = reader.readLine()) != null) { sb.append(line + "\n"); } jsonTokenStream = sb.toString(); // onPostExecute likes to get a parameter passed to work right. // Just passing something. return 1; } catch (Exception e) { Log.e("loadTwitterToken", "doInBackground Error:" + e.getMessage()); return null; } } @Override protected void onPostExecute(Integer result) { // Extract Token from JSON stream try { JSONObject root = new JSONObject(jsonTokenStream); twitterToken = root.getString("access_token"); } catch (Exception e) { Log.e("loadTwitterToken", "onPost Error:" + e.getMessage()); } twitterText.setText("Got Token!"); // Now that we have a oAuth Token, lets get our JSON feed from twitter. // We call it from here to make sure the Token has been received already. new loadTwitterFeed().execute(); } } // /////////////////////////////////////////////////////////// // AsyncTask - Download Twitter Feed w/Token as authorization // ////////////////////////////////////////////////////////// protected class loadTwitterFeed extends AsyncTask&lt;Void, Void, Integer&gt; { @Override protected Integer doInBackground(Void... params) { BufferedReader reader =null; try{ DefaultHttpClient httpclient = new DefaultHttpClient( new BasicHttpParams()); HttpGet httpget = new HttpGet(tweeterURL); httpget.setHeader("Authorization", "Bearer " + twitterToken); httpget.setHeader("Content-type", "application/json"); InputStream inputStream = null; HttpResponse response = httpclient.execute(httpget); HttpEntity entity = response.getEntity(); inputStream = entity.getContent(); reader = new BufferedReader( new InputStreamReader(inputStream, "UTF-8"), 8); return null; } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally{ if (reader != null) try { reader.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; } protected void onPostExecute(String result) { StringBuilder sb = new StringBuilder(); try{ JSONObject resultObject = new JSONObject(result); org.json.JSONArray tweetArray = resultObject.getJSONArray("results"); for (int t=0; t&lt;tweetArray.length(); t++) { JSONObject tweetObject = tweetArray.getJSONObject(t); sb.append(tweetObject.getString("from_user")+": "); sb.append(tweetObject.get("text")+"\n\n"); } } catch (Exception e) { Log.e("Tweet", "Error retrieving JSON stream" + e.getMessage()); jsonFeed = sb.toString(); e.printStackTrace(); } } } /*String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); }*/ protected void onPostExecute(Integer result) { // Update GUI if (jsonFeed.length() &gt; 0) { twitterText.setText(jsonFeed); } else { //I'd assume wrong Consumer Key/Secret if this happens. twitterText.setText("Nothing Returned"); } } } </code></pre> <p>Activity_Main.xml</p> <pre><code>&lt;ScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"&gt; &lt;TextView android:id="@+id/tweetFeed" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Loading..." /&gt; &lt;/ScrollView&gt; </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload