java - 解析 Twitter API 1.1 JSON

标签 java android json parsing twitter

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

更新: 当我运行该应用程序时,它不会崩溃,只是卡在“获得 token !”。我希望显示的是一个推文列表,其格式有点像推文。我相信这是 MainActivity,但我可能是错的。您将需要消费者 key 和 secret 来进行测试。我将提供目前所拥有的内容,但如果有人知道我如何摆脱这个循环,我将不胜感激您的意见。

谢谢!

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/user_timeline.json?screen_name=@@@&include_rts=1&count=@
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>

最佳答案

您忘记在 onPostExecute 方法中关闭 ProgressDialog。 只需在 onPostExecute 中执行此 pd.dismiss(); 即可。

@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();
}

关于java - 解析 Twitter API 1.1 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20143048/

相关文章:

php - 从javascript读取JSON到PHP

java - 如果 Java 中使用了泛型,如何获取 `int` 并将其转换为 `Integer`?

java - 使用 JXL 将图像插入到 excel 文件而不拉伸(stretch)它

java - 是否有任何标准方法可以使用 gradle 从 intellij 运行 java 项目?

android - 单击共享按钮时如何从这些数组列表项中获取文本值

Android:如何使用名称从资源中获取字符串?

android - RTL - 是否是 android :autoMirrored work with png images?

json - Spark Streaming 滑动窗口的最大值和最小值

Java ~ 通过套接字连接发送枚举

ios - 如何从 Swift 4 中的解码器容器获取非解码属性?