Android:使用Twitter4J登录Twitter

6

我的尝试:

我已经在Twitter上注册了一个应用程序,并获得了Consumer Key和Secret。我甚至还得到了各种登录Twitter的代码,这些是我已经尝试过的:

http://thetechnib.blogspot.com/2011/01/android-sign-in-with-twitter.html

[此链接已失效,您可以在此处查看存档here]
http://www.android10.org/index.php/articleslibraries/291-twitter-integration-in-your-android-application

我的问题:

到目前为止,以上代码带我进入Twitter登录界面,让我登录并获得PIN以完成登录过程。但我不知道如何使用它来使我的应用程序工作。我检查了整个代码,但没有找到与PIN相关的内容。

其次,在我在Twitter上注册应用程序时,它要求回调URL,但由于写明它真的不需要,我跳过了指定。(我甚至不知道它应该是什么!)

因此,在我的应用程序中,我将回调URL设置为null。

有人能建议我如何使用这个PIN来完成登录过程并将用户带回我的应用程序的主要活动吗?是回调URL导致问题还是我做错了其他事情?

请回复。感谢任何帮助!

编辑:

正如Frankenstein建议的那样,我尝试了github.com/ddewaele/AndroidTwitterSample/downloads上的代码

我添加了我的Consumer Key和Consumer Secret以及回调URL:

public static final String OAUTH_CALLBACK_SCHEME= "x-oauthflow-twitter";
public static final String OAUTH_CALLBACK_HOST= "callback";
public static final String OAUTH_CALLBACK_URL= OAUTH_CALLBACK_SCHEME + "://" + OAUTH_CALLBACK_HOST;

但是它给我这个错误:

日志记录:

11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081): Error during OAUth retrieve request token
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081): oauth.signpost.exception.OAuthNotAuthorizedException: Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match.
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at oauth.signpost.AbstractOAuthProvider.handleUnexpectedResponse(AbstractOAuthProvider.java:239)
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at oauth.signpost.AbstractOAuthProvider.retrieveToken(AbstractOAuthProvider.java:189)
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at oauth.signpost.AbstractOAuthProvider.retrieveRequestToken(AbstractOAuthProvider.java:69)
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at com.ecs.android.sample.twitter.OAuthRequestTokenTask.doInBackground(OAuthRequestTokenTask.java:55)
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at com.ecs.android.sample.twitter.OAuthRequestTokenTask.doInBackground(OAuthRequestTokenTask.java:1)
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at android.os.AsyncTask$2.call(AsyncTask.java:185)
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at java.util.concurrent.FutureTask.run(FutureTask.java:137)
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
11-29 11:56:56.249: E/com.ecs.android.sample.twitter.OAuthRequestTokenTask(3081):   at java.lang.Thread.run(Thread.java:1096)

当我点击推特按钮时,它给我显示黑屏,而不是带我进入推特的登录界面。哎呀,我快要疯了...已经尝试了两天! :( 请帮帮我。

你已经处理授权过程的返回并存储访问令牌了吗? - jmcdale
嗯...我不知道代码是否保存了令牌,因为我对OAuth很陌生。但看代码,我不认为令牌被保存了。 - Hiral Vadodaria
3个回答

9

这是因为您的应用程序被注册为桌面客户端。 要覆盖回调URL,您的应用程序需要注册为浏览器客户端。

尝试在https://dev.twitter.com/apps/[appid]/settings > Callback URL中配置一个虚拟回调URL(例如http://example.com/或其他任何内容),您的应用程序将被识别为浏览器客户端。

然后尝试使用@Frankenstein或@jamn224的代码。


7

首先,您需要正确进行身份验证:

try{
        consumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
        provider = new DefaultOAuthProvider("http://twitter.com/oauth/request_token", "http://twitter.com/oauth/access_token", "http://twitter.com/oauth/authorize");
        String authUrl = provider.retrieveRequestToken(consumer, CALLBACK_URL);

        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl)));

    }catch(Exception e){
        Log.e(TAG,e+"");
    }

CALLBACK_URL的必要条件需要在清单文件中设置(请参考Frankenstein的答案)。上述代码启动了一个意图,在Twitter服务器上执行授权。回调信息是必要的,因此意图知道在授权过程后返回哪个应用程序。

然后,我们需要处理在Twitter进行身份验证后返回应用程序的情况:

    @Override
public void onResume(){
    super.onResume();

    if (this.getIntent()!=null && this.getIntent().getData()!=null){
        Uri uri = this.getIntent().getData();

        //handle returning from authenticating the user
        if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {
            String verifier = uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
            String token = uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_TOKEN);
            try {  
                Twitter t = new TwitterFactory().getInstance();
                t.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);

                // Get Access Token and store it  
                rToken = new RequestToken(token, CONSUMER_SECRET);
                AccessToken aToken = t.getOAuthAccessToken(rToken);
                storeAccessToken(aToken);  

                //send to checkLoginState again since we have authorization now!
                checkLoginState(); 

           } catch (Exception e) {  
               Log.e(TAG, e+"");  
           }  
          }  
         }
}//end onResume

这段代码从返回的意图中获取数据,其中包括获取授权令牌的信息。"storeAccessToken(aToken)"是我编写的一种简短的方法,用于将令牌存储在应用程序的首选项中,以便我们不必每次打开应用程序时重新授权。
现在我们有了授权令牌,我们可以使用它来授权 Twitter 实例:
twitter = new TwitterFactory().getInstance();
        twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
        twitter.setOAuthAccessToken(aToken);

上述变量“twitter”现在已被授权并可以运行它自己的操作。

请问您如何存储令牌?也就是说,您能否给我提供storeAccessToken(aToken)和checkLoginState()方法的代码? - Hiral Vadodaria
还有一个问题,使用这个代码登录Twitter后,它不会给我PIN码来完成登录过程吗?我的问题只是如何在我们的应用程序中使用该PIN码。即使我们让用户在我们的应用程序中输入PIN码,我们如何使用它并防止他每次打开应用程序时都要重新输入? - Hiral Vadodaria
我在授权过程中从未需要使用 PIN 码...所以对此我无能为力,抱歉。public void storeAccessToken(AccessToken aToken){ SharedPreferences.Editor editor = settings.edit(); editor.putString(PREFS_TWITTER_USER_TOKEN, aToken.getToken()); editor.putString(PREFS_TWITTER_USER_SECRET, aToken.getTokenSecret()); editor.commit(); }至于 checkLoginState() 函数,它只是一个 if 语句。它检查是否已经存储了 aToken。如果已经存储,则创建 Twitter 实例并进行操作。否则,运行身份验证程序。 - jmcdale
我尝试了别人的Key-Secret配对,它完美地工作了。那么,只有我的这个配对会有问题吗?如果是这样,可能是什么问题呢? - Hiral Vadodaria
即使我尝试删除该应用并在 dev.twitter 帐户上创建一个新的,但是新的配对似乎仍然无法工作! :( - Hiral Vadodaria
显示剩余5条评论

5

在您的活动清单中,应将回调编写为以下格式

<activity android:name="com.apps.twitter.PrepareRequestTokenActivity"
            android:launchMode="singleTask" android:theme="@android:style/Theme.Translucent.NoTitleBar"
            android:screenOrientation="portrait">
            <intent-filter>
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="x-oauthflow-twitter" android:host="callback" />
            </intent-filter>
</activity>

在常量文件中

final public static String  CALLBACK_SCHEME = "x-oauthflow-twitter";    
final public static String  CALLBACK_URL = CALLBACK_SCHEME + "://callback";

我已经尝试了我问题中第二个参考链接中指定的代码。但不幸的是,它对我没有用。:( 无论如何,谢谢。 - Hiral Vadodaria
同样将 CallbackURL 设置为 "" 可以使用 Twitter 登录,但是我卡在这里了,不知道该如何处理收到的 PIN 完成登录过程。 - Hiral Vadodaria
谢谢您的回复。我一定会尝试并告诉您结果。 - Hiral Vadodaria

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接