无法使用Android上的Twitter4j通过Twitter进行身份验证

时间:2013-11-21 21:03:17

标签: android twitter twitter4j

因此,在尝试通过Twitter进行身份验证时,我收到了“未发现身份验证质询”错误。在你问之前,是的,我用Google搜索了这个问题;只有三页的结果,似乎没有一个帮助。使用Twitter4j的所有GitHub项目都已过时也无济于事,我设法找到的所有教程和指南也是如此......

无论如何,这是我得到的相关代码:

class TwitterGetAccessTokenTask extends AsyncTask<String, String, String> {

    @Override
    protected void onPostExecute(String userName) {
        Intent intent = new Intent(CurrentActivity.this, ActivityToLaunch.class);
        startActivity(intent);
        finish();
    }

    @Override
    protected String doInBackground(String... params) {

        Twitter twitter = TwitterUtil.getInstance().getTwitter();
        RequestToken requestToken = TwitterUtil.getInstance().getRequestToken();

        try {
            AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, ConstantValues.URL_PARAMETER_TWITTER_OAUTH_VERIFIER);

            long userId = accessToken.getUserId();

            return twitter.showUser(userId).getName();
        } catch (TwitterException e) {
            e.printStackTrace();
        }

        return null;
    }
}

该代码是从onClick事件运行的,应该很容易理解:点击按钮,执行新的后台任务。在那个任务中,我们得到一个请求令牌(我知道它是有效的,因为我正在将它们记录下来)。然后我们尝试将该请求令牌交换为访问令牌,这就是抛出错误的原因。这是堆栈跟踪:

11-21 16:41:37.152: W/System.err(3534): No authentication challenges found
11-21 16:41:37.152: W/System.err(3534): Relevant discussions can be found on the Internet at:
11-21 16:41:37.152: W/System.err(3534):     http://www.google.co.jp/search?q=bb0a5eb5 or
11-21 16:41:37.152: W/System.err(3534):     http://www.google.co.jp/search?q=324c40aa
11-21 16:41:37.152: W/System.err(3534): TwitterException{exceptionCode=[bb0a5eb5-324c40aa 5147af80-173bd05c], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=3.0.5}
11-21 16:41:37.152: W/System.err(3534):     at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:177)
11-21 16:41:37.152: W/System.err(3534):     at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:61)
11-21 16:41:37.152: W/System.err(3534):     at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:89)
11-21 16:41:37.152: W/System.err(3534):     at twitter4j.TwitterImpl.get(TwitterImpl.java:1911)
11-21 16:41:37.152: W/System.err(3534):     at twitter4j.TwitterImpl.showUser(TwitterImpl.java:852)
11-21 16:41:37.152: W/System.err(3534):     at com.myapp.CurrentActivity.TwitterActivity$TwitterGetAccessTokenTask.doInBackground(TwitterActivity.java:90)
11-21 16:41:37.152: W/System.err(3534):     at com.myapp.CurrentActivity.TwitterActivity$TwitterGetAccessTokenTask.doInBackground(TwitterActivity.java:1)
11-21 16:41:37.152: W/System.err(3534):     at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-21 16:41:37.152: W/System.err(3534):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-21 16:41:37.152: W/System.err(3534):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-21 16:41:37.152: W/System.err(3534):     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-21 16:41:37.152: W/System.err(3534):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
11-21 16:41:37.152: W/System.err(3534):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
11-21 16:41:37.152: W/System.err(3534):     at java.lang.Thread.run(Thread.java:856)
11-21 16:41:37.152: W/System.err(3534): Caused by: java.io.IOException: No authentication challenges found
11-21 16:41:37.160: W/System.err(3534):     at libcore.net.http.HttpURLConnectionImpl.getAuthorizationCredentials(HttpURLConnectionImpl.java:427)
11-21 16:41:37.160: W/System.err(3534):     at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java:407)
11-21 16:41:37.160: W/System.err(3534):     at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java:356)
11-21 16:41:37.160: W/System.err(3534):     at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:292)
11-21 16:41:37.160: W/System.err(3534):     at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:486)
11-21 16:41:37.160: W/System.err(3534):     at libcore.net.http.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:134)
11-21 16:41:37.160: W/System.err(3534):     at twitter4j.internal.http.HttpResponseImpl.<init>(HttpResponseImpl.java:34)
11-21 16:41:37.160: W/System.err(3534):     at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:141)
11-21 16:41:37.160: W/System.err(3534):     ... 13 more

我的问题是,简短而甜蜜:如何使用Twitter4j 3.0.5版通过Twitter进行正确的身份验证?我做错了什么导致了这个错误?非常感谢任何和所有的帮助!

编辑:包含我正在使用的TwitterUtil类的代码可能对我有所帮助:

import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;

public final class TwitterUtil {

    private RequestToken requestToken = null;
    private TwitterFactory twitterFactory = null;
    private Twitter twitter;

    public TwitterUtil() {
        ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
        configurationBuilder.setOAuthConsumerKey(ConstantValues.TWITTER_CONSUMER_KEY);
        configurationBuilder.setOAuthConsumerSecret(ConstantValues.TWITTER_CONSUMER_SECRET);
        Configuration configuration = configurationBuilder.build();
        twitterFactory = new TwitterFactory(configuration);
        twitter = twitterFactory.getInstance();
    }

    public TwitterFactory getTwitterFactory()
    {
        return twitterFactory;
    }

    public void setTwitterFactory(AccessToken accessToken)
    {
        twitter = twitterFactory.getInstance(accessToken);
    }

    public Twitter getTwitter()
    {
        return twitter;
    }
    public RequestToken getRequestToken() {
        if (requestToken == null) {
            try {
                requestToken = twitterFactory.getInstance().getOAuthRequestToken(ConstantValues.TWITTER_CALLBACK_URL);
            } catch (TwitterException e) {
                e.printStackTrace();
            }
        }
        return requestToken;
    }

    static TwitterUtil instance = new TwitterUtil();

    public static TwitterUtil getInstance() {
        return instance;
    }

    public void reset() {
        instance = new TwitterUtil();
    }
}

编辑2:请注意,调用getOAUthAccessToken时会抛出堆栈跟踪中的错误,即AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, ConstantValues.URL_PARAMETER_TWITTER_OAUTH_VERIFIER);

1 个答案:

答案 0 :(得分:1)

最终我自己设法解决了这个问题。关键是将请求令牌分解为它自己的AsyncTask,如下所示:

class TwitterGetRequestTokenTask extends AsyncTask<String, String, RequestToken> {

    @Override
    protected void onPostExecute(RequestToken requestToken) {
        Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(requestToken.getAuthenticationURL()));
        startActivity(intent);
    }

    @Override
    protected RequestToken doInBackground(String... params) {
        return TwitterUtil.getInstance().getRequestToken();
    }
}

onPostExecute()方法中的代码会显示用户允许您的应用访问其帐户的Twitter身份验证页面。在此之后,将以下行放在清单文件中,以便在验证后将Twitter网页重定向回的任何活动(请注意,它不必是启动意图的同一活动!):

<category android:name="android.intent.category.BROWSABLE" />
<!-- The following line should match your callback url; mine is oauth://com.example.myapp -->
<data android:scheme="oauth" android:host="com.example.myapp" />

最后,将以下代码放在将处理实际生成访问令牌以及随后存储/使用该数据的活动中:

class TwitterGetAccessTokenTask extends AsyncTask<String, String, String> {

    @Override
    protected void onPostExecute(String s) {
        // The user's name is now in 's', so you can do stuff with it
    }

    @Override
    protected String doInBackground(String... params) {

        String verifier = params[0];

        Twitter twitter = TwitterUtil.getInstance().getTwitter();
        RequestToken requestToken = TwitterUtil.getInstance().getRequestToken();

        try {
            AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, verifier);
            // You can store the access token data now however you'd like
            // You can also use it to get data from the user's Twitter account
            long userId = accessToken.getUserId();
            return twitter.showUser(userId).getName();
        } catch (TwitterException e) {
            e.printStackTrace();
        }

        return null;
    }

}

我认为这涵盖了使twitter4j身份验证正常工作所需的一切......希望这可以帮助某人!

相关问题