推特直播API未经授权(android)

Twitter's live streaming API unauthorized(android)

我找到了这个旧的android示例代码,它可以根据用户的输入从 Twitter 的直播中过滤推文API,但问题是它使用了基本授权。

显然它不起作用,我得到了“401 未授权”错误。

原代码如下:

package com.teleknesis.android.twitter.livestream;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class TwitterLiveStreamingActivity extends Activity {

    private List<HashMap<String,String>> mTweets = new ArrayList<HashMap<String,String>>();
    private SimpleAdapter mAdapter;
    private boolean mKeepRunning = false;
    private String mSearchTerm = "";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mAdapter = new SimpleAdapter(this, mTweets, android.R.layout.simple_list_item_2, new String[] {"Tweet", "From"}, new int[] {android.R.id.text1, android.R.id.text2});
        ((ListView)findViewById(R.id.Tweets)).setAdapter(mAdapter);
        }


public void startStop( View v ) {
    if( ((Button)v).getText().equals("Start") ) {
        mSearchTerm = ((EditText)findViewById(R.id.SearchText)).getText().toString();
        if( mSearchTerm.length() > 0 ) {
            new StreamTask().execute();
            mKeepRunning = true;
            ((Button)v).setText("Stop");
            }
        else {
            Toast.makeText(this, "You must fill in a search term", Toast.LENGTH_SHORT).show();
            }
        }
    else {
        mKeepRunning = false;
        ((Button)v).setText("Start");
        }
    }


    private class StreamTask extends AsyncTask<Integer, Integer, Integer> {

        private String mUrl = "https://stream.twitter.com/1/statuses/filter.json?track=";

@Override
protected Integer doInBackground(Integer... params) {
    try {
        DefaultHttpClient client = new DefaultHttpClient();
        Credentials creds = new UsernamePasswordCredentials("username", "password");
        client.getCredentialsProvider().setCredentials( new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), creds);
        HttpGet request = new HttpGet();
        request.setURI(new URI("https://stream.twitter.com/1/statuses/filter.json?track=" + mSearchTerm));
        HttpResponse response = client.execute(request);
        InputStream in = response.getEntity().getContent();
        BufferedReader reader = new BufferedReader( new InputStreamReader(in) );

        parseTweets(reader);

        in.close();  

        } 
    catch (Exception e) {
        Log.e("Twitter", "doInBackground_" + e.toString());
        }
    return new Integer(1);
    }


private void parseTweets( BufferedReader reader ) {
    try {
        String line = "";
        do {
            line = reader.readLine();
            Log.d("Twitter", "Keep Running: " + mKeepRunning
                    + " Line: " + line);
            JSONObject tweet = new JSONObject(line);
            HashMap<String, String> tweetMap = new HashMap<String, String>();
            if (tweet.has("text")) {
                tweetMap.put("Tweet", tweet.getString("text"));
                tweetMap.put("From", tweet.getJSONObject("user")
                        .getString("screen_name"));
                mTweets.add(0, tweetMap);
                if (mTweets.size() > 10) {
                    mTweets.remove(mTweets.size() - 1);
                    }
                //mAdapter.notifyDataSetChanged();
                publishProgress(1);
                }
            } while (mKeepRunning && line.length() > 0);
        } 
    catch (Exception e) {
        // TODO: handle exception
        }
    }



        protected void onProgressUpdate(Integer... progress) {
            mAdapter.notifyDataSetChanged();
            }

        @Override
        protected void onPostExecute(Integer i) {

            }

        }
}

我尝试用 OAuth 替换凭据:

ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true);
cb.setOAuthConsumerKey("*************");
cb.setOAuthConsumerSecret("*************");
cb.setOAuthAccessToken("*************");
cb.setOAuthAccessTokenSecret("*************");

没用..(我有所有正确的密钥和秘密)

我还尝试将这整个部分插入到一个当前运行的 Twitter 客户端(我可以在时间线上获取所有推文),我不知道我是否做对了,但它也没有用。同样在这种情况下,如果在此代码中再次完成 Oauth 并且它有效,这是否意味着当我 运行 应用程序时,如果我想使用此过滤器功能,我必须被重定向到授权页面两次?我想要一个修复程序,即时间线和此过滤模式都可以使用 Twitter 提要。

有人能告诉我如何做到这一点吗?

问题已解决。 这是修改后的代码:

protected Integer doInBackground(Integer... params) {
    try {
        DefaultHttpClient client = new DefaultHttpClient();
        OAuthConsumer consumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY,
                CONSUMER_SECRET);
        consumer.setTokenWithSecret(ACCESS_TOKEN, ACCESS_TOKEN_SECRET);

        HttpGet request = new HttpGet();
        request.setURI(new URI("https://stream.twitter.com/1/statuses/filter.json?track=" + mSearchTerm));
        consumer.sign(request);
        HttpResponse response = client.execute(request);
        InputStream in = response.getEntity().getContent();
        BufferedReader reader = new BufferedReader( new InputStreamReader(in) );

        parseTweets(reader);

        in.close();  


        }