使用Android和Twitter4J的持久性OAuth

时间:2011-01-24 17:45:30

标签: android twitter-oauth

因此,我正试图使用​​OAuth库抓住这个Twitter4J的Twitter。

我将给出一些背景知识。

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

我有一项完全处理我的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身份验证页面,返回活动,然后将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>

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

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

我使用以下方法执行此操作:

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)

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

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

任何评论或帮助将不胜感激!

最佳,

Ignus

1 个答案:

答案 0 :(得分:1)

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

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