2013-11-22 84 views
1

我一直在研究从用户时间线拉取JSON的Twitter阅读器(只读)(oauth 2.0)的开放源代码。它成功从Twitter API 1.1中提取JSON。我面临的挑战是将JSON转换为用户友好的东西。我已经实现了另一个解析JSON的源代码部分,但我对解析JSON并不熟悉。它拼凑而成,所以我知道我可能会忽略一些东西。可能是冗余或缺少的部分。解析Twitter API 1.1 JSON

已更新: 当我运行该应用程序时,它不会崩溃,它只是停留在“Got Token!”。我希望显示的是一些有点格式化的推文,看起来像一个。我相信这是MainActivity,但我可能是错的。你将需要一个消费者密钥和秘密来测试。我会提出我现在拥有的东西,但如果有人知道我能如何摆脱这种循环,我会很感激你的意见。

谢谢!

MainActivity.java

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/[email protected]@@&include_rts=1&[email protected] 
static String tweeterURL = twitterAPIurl + screenName 
     + "&include_rts=1&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<Void, Void, Integer> { 

    @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<Void, Void, Integer> { 

    @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<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() > 0) { 
      twitterText.setText(jsonFeed); 
     } else { 
      //I'd assume wrong Consumer Key/Secret if this happens. 
      twitterText.setText("Nothing Returned"); 
     }  
    } 
} 

activity_main.xml中

<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"> 

<TextView 
    android:id="@+id/tweetFeed" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Loading..." /> 


</ScrollView> 
+0

我想你忘了关闭'onPostExecute'中的'progressDialog' ..你把它关在别的地方吗? –

+0

如果你想得到很多反馈,我建议你在问题中修改MainActivity.java代码。只需将代码修剪到反序列化和渲染相关方法(因为根据你拉动JSON不是问题)。阅读越愉快,反馈越多;) –

回答

0

你忘了关ProgressDialog在onPostExecute方法。 这样做pd.dismiss();onPostExecute这样。

@Override 
protected void onPostExecute(Integer result) { 

    pd.dismiss(); 

    // 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(); 
} 
+0

感谢那@Priyanka。我已经在代码中取得了进展。我发现我需要将XML TextView更改为ListView并删除ScrollView。我现在唯一的问题是获得R.java文件来创建一个android.R.id.list,但我的ListView ID似乎很好:“android:id =”@ android:id/list“其他任何东西都可以导致它不生成? – reekdev

+1

@reekdev当R.java文件未创建时,可能错误在res文件夹中。如果有任何错误,请检查所有的.xml文件,同时检查您的导入包是否有任何包名'android。 R'删除它,如果你使用'android:id =“@ android:id/list'意味着隐式的android列表,你应该用ListActivity扩展你的类。 – Priyanka

+0

感谢您的解释@Priyanka!我已经对代码进行了一些更新。同样,它仍然不会崩溃或显示错误,但是我可以获得状态,告诉我“Got Token!”所以它已经正确授权,但在那里停止。你能否告诉我是否正确设置了解析来输出更新的java中的推文列表?它应该是文件中的最后一个块。到目前为止,我感谢你的帮助。我可以告诉我很近。 – reekdev