【问题标题】:Twitter's live streaming API unauthorized(android)Twitter 的直播 API 未经授权(android)
【发布时间】:2015-05-19 06:05:09
【问题描述】:

我找到了这个旧的 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 提要。

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

【问题讨论】:

  • 为了使用 OAuth,您需要添加一个 HttpHeader,其中包含一个值为 "Bearer " + your_tokenAUTHORITATION 字段,如 twitter docs for application auth 中所述。抱歉,我无法测试它,对原始 org.apache.http.* 不太熟悉(如果我可以测试它,我会将其作为答案发布......)希望它有所帮助。
  • 谢谢 Irnzcig :) 但我不确定我理解你的意思(我对此完全陌生 :( )..在这个具体的例子中,我认为可以稍微修改一下以获得通过授权问题?或者如果我以某种方式将它插入我谈到的这个 twitter 客户端,以便它可以直接使用客户端已经获得的流,是否有可能?
  • 不客气。实际上,您必须修改您的方法doInBackground,而不是添加您的凭据,您必须将授权参数添加到HttpHeader。正如我所说,我对 org.apache.http.* 不太熟悉,我可以提供一个 Jersey 客户端的示例。昨天我花了一点时间浏览,但我没有发现任何有用的东西。现在是我的时区的晚上。也许明天我会花更多时间寻找一个简单的例子,但我不能保证。
  • 你真是太好了,再次感谢:)

标签: android twitter oauth twitter-streaming-api


【解决方案1】:

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

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


        } 

【讨论】:

  • CommonsHttpOAuthConsumer 来自哪里?
  • 我收到此错误 {"errors":[{"code":32,"message":"Could not authenticate you."}]} with this code
猜你喜欢
  • 2013-08-22
  • 2017-08-25
  • 2014-01-02
  • 2016-12-24
  • 2015-09-15
  • 1970-01-01
  • 2013-10-06
  • 2012-06-24
  • 2012-04-08
相关资源
最近更新 更多