android - 使用 Android 和 Twitter4J 的持久性 OAuth

标签 android twitter-oauth

因此,我正尝试使用 Twitter4J 库来掌握此 OAuth for twitter。

我会给出一些背景知识。

我在 AndroidManifest.xml 中使用浏览器方法和回调(我已将其设置为 intent-filter)设置我的 Twitter 开发者帐户。

我有一个 Activity 可以完全处理我的 Twitter 身份验证。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    //set up the datahelper
    dh = new DataHelper(this, null);
    tae = dh.GetAuthenticationObject();
    setContentView(R.layout.main);
}

@Override
protected void onResume() {
    super.onResume();
    selectOption(getIntent());
}

public void selectOption(Intent intent) {
    Uri uri = intent.getData();
    if (uri != null && uri.toString().startsWith(CALLBACKURL) && tae.hasBeenAuthenticatedTwitter()) {           
        completeAuth(intent);           
    } else {
        doOauth();
    }
}

private void doOauth() {
    try {
        consumer = new CommonsHttpOAuthConsumer(Enums.TWITTER_APPLICATION_KEY,
                Enums.TWITTER_APPLICATION_SECTRET);

        provider = new DefaultOAuthProvider(
                Enums.TWITTER_REQUEST_TOKEN_URL,
                Enums.TWITTER_ACCESS_TOKEN_URL,
                Enums.TWITTER_AUTHORIZE_URL);

        String authUrl = provider.retrieveRequestToken(
                consumer, CALLBACKURL);

        tae.TwitterToken =  consumer.getToken();
        tae.TwitterTokenSecret = consumer.getTokenSecret();
        dh.SaveAuthenticationObject(tae);

        this.startActivity(new Intent(Intent.ACTION_VIEW, Uri
                .parse(authUrl)));
    } catch (Exception e) {
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
    }
}

/**
 * After use authorizes this is the function where we get back callbac with
 * user specific token and secret token. You might want to store this token
 * for future use.
 */

public void completeAuth(Intent intent) {
    Uri uri = intent.getData();
    if (uri != null && uri.toString().startsWith(CALLBACKURL)) {

        tae = dh.GetAuthenticationObject();
        String verifier = uri
                .getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER);
        tae.TwitterVerifier = verifier;
        dh.SaveAuthenticationObject(tae);   
    }

    Intent settingsIntent = new Intent(this, com.undetowdevelopment.kontakt.Settings.class);
    settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
    settingsIntent.putExtra("REQUEST_CODE", Enums.REQUEST_CODE_TWITTER_LOGIN);
    settingsIntent.putExtra("RESULT_CODE", Activity.RESULT_OK);
    startActivity(settingsIntent);  
}

这门课完全符合我的预期。它打开 Twitter 身份验证页面,返回 Activity ,我将 Token & Secret 保存到我的共享首选项。

我的 AndroidManifest.xml 看起来像:

    <activity android:name=".TwitterSuccess" android:label="@string/app_name" android:launchMode="singleTop">
        <intent-filter>
            <action android:name="android.intent.action.VIEW"></action>
            <category android:name="android.intent.category.DEFAULT"></category>
            <category android:name="android.intent.category.BROWSABLE"></category>
            <data android:scheme="myapp" android:host="mainactivity"/>
        </intent-filter>
    </activity>

然而,当我的应用程序启动时,我想检查此人是否已通过身份验证,而不必一直要求用户再次进行身份验证。

在我所有的 Activity 中,我有一个返回 Twitter 对象的方法,我想用它来设置状态或获取用户的 friend 。

我使用以下方法来做到这一点:

public Twitter getTwitterObject()
{

    AuthenticationEntity ae = GetAuthenticationObject();

    CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(Enums.TWITTER_APPLICATION_KEY, Enums.TWITTER_APPLICATION_SECTRET); 
    //Set the requestToken and the tokenSecret that you got earlier by calling retrieveRequestToken.
    consumer.setTokenWithSecret(ae.TwitterToken, ae.TwitterTokenSecret);

    //The provider object is lost, too, so instantiate it again.
    DefaultOAuthProvider provider = new DefaultOAuthProvider(
            Enums.TWITTER_REQUEST_TOKEN_URL,
            Enums.TWITTER_ACCESS_TOKEN_URL,
            Enums.TWITTER_AUTHORIZE_URL);

    //Now that's really important. Because you don't perform the retrieveRequestToken method at this moment, the OAuth method is not detected automatically (there is no communication with Twitter). So, the default is 1.0 which is wrong because the initial request was performed with 1.0a.
    provider.setOAuth10a(true);


    try {
        provider.retrieveAccessToken(consumer, ae.TwitterVerifier);
    } catch (Exception e) {
        Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show();
        e.printStackTrace();
    }

    Twitter twitter = new TwitterFactory().getInstance();
    twitter.setOAuthConsumer(Enums.TWITTER_APPLICATION_KEY, Enums.TWITTER_APPLICATION_SECTRET);
    twitter.setOAuthAccessToken(new AccessToken(consumer.getToken(), consumer.getTokenSecret()));
    return twitter;

}

现在,如果用户刚刚登录,这就可以正常工作了,但是如果我再次启动应用程序(这应该无关紧要,因为我只使用静态变量和共享首选项中的数据),我无法进行身份验证,并且出现以下异常:

01-24 11:41:54.075: WARN/System.err(14612): oauth.signpost.exception.OAuthCommunicationException: Communication with the service provider failed: http://twitter.com/oauth/access_token
01-24 11:41:54.075: WARN/System.err(14612):     at oauth.signpost.AbstractOAuthProvider.retrieveToken(AbstractOAuthProvider.java:214)
01-24 11:41:54.075: WARN/System.err(14612):     at oauth.signpost.AbstractOAuthProvider.retrieveAccessToken(AbstractOAuthProvider.java:97)
01-24 11:41:54.075: WARN/System.err(14612):     at com.undetowdevelopment.kontakt.helpers.DataHelper.getTwitterObject(DataHelper.java:129)
01-24 11:41:54.075: WARN/System.err(14612):     at com.undetowdevelopment.kontakt.Settings.checkTwitterStatus(Settings.java:118)
01-24 11:41:54.075: WARN/System.err(14612):     at com.undetowdevelopment.kontakt.Settings.setUIComponents(Settings.java:60)
01-24 11:41:54.075: WARN/System.err(14612):     at com.undetowdevelopment.kontakt.Settings.onCreate(Settings.java:39)
01-24 11:41:54.075: WARN/System.err(14612):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1069)
01-24 11:41:54.085: WARN/System.err(14612):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2751)
01-24 11:41:54.085: WARN/System.err(14612):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803)
01-24 11:41:54.085: WARN/System.err(14612):     at android.app.ActivityThread.access$2300(ActivityThread.java:135)
01-24 11:41:54.085: WARN/System.err(14612):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136)
01-24 11:41:54.085: WARN/System.err(14612):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-24 11:41:54.085: WARN/System.err(14612):     at android.os.Looper.loop(Looper.java:144)
01-24 11:41:54.085: WARN/System.err(14612):     at android.app.ActivityThread.main(ActivityThread.java:4937)
01-24 11:41:54.085: WARN/System.err(14612):     at java.lang.reflect.Method.invokeNative(Native Method)
01-24 11:41:54.085: WARN/System.err(14612):     at java.lang.reflect.Method.invoke(Method.java:521)
01-24 11:41:54.085: WARN/System.err(14612):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-24 11:41:54.085: WARN/System.err(14612):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-24 11:41:54.085: WARN/System.err(14612):     at dalvik.system.NativeStart.main(Native Method)
01-24 11:41:54.085: WARN/System.err(14612): Caused by: java.io.FileNotFoundException: http://twitter.com/oauth/access_token
01-24 11:41:54.085: WARN/System.err(14612):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1162)
01-24 11:41:54.085: WARN/System.err(14612):     at oauth.signpost.basic.HttpURLConnectionResponseAdapter.getContent(HttpURLConnectionResponseAdapter.java:18)
01-24 11:41:54.085: WARN/System.err(14612):     at oauth.signpost.AbstractOAuthProvider.handleUnexpectedResponse(AbstractOAuthProvider.java:228)
01-24 11:41:54.085: WARN/System.err(14612):     at oauth.signpost.AbstractOAuthProvider.retrieveToken(AbstractOAuthProvider.java:189)
01-24 11:41:54.085: WARN/System.err(14612):     ... 18 more
01-24 11:41:54.885: WARN/System.err(14612): http://api.twitter.com/1/account/verify_credentials.json?include_entities=falseRelevant discussions can be on the Internet at:
01-24 11:41:54.885: WARN/System.err(14612):     http://www.google.co.jp/search?q=2486d84d or
01-24 11:41:54.885: WARN/System.err(14612):     http://www.google.co.jp/search?q=0d00203c
01-24 11:41:54.885: WARN/System.err(14612): TwitterException{exceptionCode=[2486d84d-0d00203c 175a68e8-9303e317], statusCode=-1, retryAfter=0, rateLimitStatus=null, version=2.1.12-SNAPSHOT(build: e7bec3eec13cedc774926ee24f4c5368d218c9d4)}
01-24 11:41:54.885: WARN/System.err(14612):     at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:214)
01-24 11:41:54.885: WARN/System.err(14612):     at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:75)
01-24 11:41:54.885: WARN/System.err(14612):     at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:103)
01-24 11:41:54.885: WARN/System.err(14612):     at twitter4j.Twitter.verifyCredentials(Twitter.java:1397)
01-24 11:41:54.885: WARN/System.err(14612):     at twitter4j.Twitter.getScreenName(Twitter.java:191)
01-24 11:41:54.885: WARN/System.err(14612):     at com.undetowdevelopment.kontakt.Settings.checkTwitterStatus(Settings.java:120)
01-24 11:41:54.885: WARN/System.err(14612):     at com.undetowdevelopment.kontakt.Settings.setUIComponents(Settings.java:60)
01-24 11:41:54.885: WARN/System.err(14612):     at com.undetowdevelopment.kontakt.Settings.onCreate(Settings.java:39)
01-24 11:41:54.885: WARN/System.err(14612):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1069)
01-24 11:41:54.885: WARN/System.err(14612):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2751)
01-24 11:41:54.885: WARN/System.err(14612):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2803)
01-24 11:41:54.885: WARN/System.err(14612):     at android.app.ActivityThread.access$2300(ActivityThread.java:135)
01-24 11:41:54.885: WARN/System.err(14612):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2136)
01-24 11:41:54.885: WARN/System.err(14612):     at android.os.Handler.dispatchMessage(Handler.java:99)
01-24 11:41:54.885: WARN/System.err(14612):     at android.os.Looper.loop(Looper.java:144)
01-24 11:41:54.885: WARN/System.err(14612):     at android.app.ActivityThread.main(ActivityThread.java:4937)
01-24 11:41:54.885: WARN/System.err(14612):     at java.lang.reflect.Method.invokeNative(Native Method)
01-24 11:41:54.885: WARN/System.err(14612):     at java.lang.reflect.Method.invoke(Method.java:521)
01-24 11:41:54.885: WARN/System.err(14612):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
01-24 11:41:54.885: WARN/System.err(14612):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
01-24 11:41:54.885: WARN/System.err(14612):     at dalvik.system.NativeStart.main(Native Method)
01-24 11:41:54.885: WARN/System.err(14612): Caused by: java.io.FileNotFoundException: http://api.twitter.com/1/account/verify_credentials.json?include_entities=false
01-24 11:41:54.885: WARN/System.err(14612):     at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1162)
01-24 11:41:54.885: WARN/System.err(14612):     at twitter4j.internal.http.HttpResponseImpl.<init>(HttpResponseImpl.java:47)
01-24 11:41:54.895: WARN/System.err(14612):     at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:178)
01-24 11:41:54.895: WARN/System.err(14612):     ... 20 more
01-24 11:41:54.995: WARN/InputManagerService(99): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy@46113ee8 (uid=10060 pid=14093)

正如我提到的,当我刚刚完成身份验证时,一切正常,但如果我再次启动我的应用程序,我会收到此消息。

我使用的是 HTC Incredible,运行 Android 2.2。该应用程序正在为 Android 1.6+ 开发。

任何意见或帮助将不胜感激!

最好的,

伊格纳斯

最佳答案

我不太确定你在做什么,但你可以看看 Zwitscher https://github.com/pilhuhn/ZwitscherA尤其是在 https://github.com/pilhuhn/ZwitscherA/blob/v065/src/de/bsd/zwitscher/LoginActivity.java然后调用 TwitterHelper 的方法。

当用户首次登录但从未登录时, Activity 会对此进行检查并显示带有“getPinFromTwitter”按钮的屏幕 - 这会将用户重定向到 Twitter,他可以在其中登录并获取 PIN。 用户再次启动应用程序,输入密码并单击“setPin”。 在此版本的 Zwitscher 中,帐户存储在数据库中;在早期版本中(例如,只需查看 v065 标签:https://github.com/pilhuhn/ZwitscherA/tree/v065),这是通过共享首选项完成的。 来源目前有点变化。

关于android - 使用 Android 和 Twitter4J 的持久性 OAuth,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4785196/

相关文章:

ios - 在登录成功时运行函数 MGTwitterEngine ala FBConnect

api - 推特 API 问题

android - 如何在Android中将屏幕尺寸作为像素获取

java - android 完成当前 Activity 导致应用关闭

java - Android 中的欢迎 Activity

c# - 获取 Twitter 请求 token 失败

android - OAuthNotAuthorizedException,当 twitter 在 android 应用程序中运行时

google-app-engine - 如何将 Facebook/Twitter/LinkedIn 登录添加到 Google App Engine 项目?

android - 禁用 ActionBarDrawerToggle 抽屉指示器,但保留汉堡包图标

android - 在 Android 应用程序中打开文件的 Intent 过滤器出现问题