3

何が起こっているのか把握するのに苦労しています。私は、Twitter トークンの取得を処理する 1 つの OAuthActivity を生成する典型的なアプリ構造を持っています。その後、私のメイン アプリケーション アクティビティは、さまざまな Twitter 関連の操作にそのトークンを使用します。

私の OAuthActivity は動作します。認証トークンを取得すると、Twitter の Web 画面にアプリケーション名などが正しく表示されます。また、その activity 内でツイートを送信すると、それが公開されます。. これは、OAuthActivity が機能していること、クロックが同期していること、トークンが有効であることなどを意味します。

しかし、この OAuthActivity が終了して呼び出し元のアクティビティに戻ると、そのトークンを使用しようとすると (永続化された key/secret から再作成する)、何があっても、操作は常に401 で失敗し、AuthChallenge が null を報告したと不平を言います.. . 空のトークンを提供したのと同じように、まだ提供していません!!!

OAuthActivity のソースと、メイン アクティビティで Twitter オブジェクトを初期化する方法のソースを添付してください。何か間違っているところがあれば教えてください。

PD -割り当てたトークン値が取得したものと同じであることを明らかに確認しました!! また、プロパティを介して、ビルダーを介して、セットを介して、Twitterをインスタンス化するさまざまな方法を試しました....そして何も変わりません:(

編集->トークンを再利用したい場合は、新しいtwitterオブジェクトで「 verifyCredentials() 」を呼び出さなければならないことがわかりましたが、....うまくいきません! (最後に投稿された例外を見つけてください)

EDIT-2>子アクティビティと親の両方で使用する場合

mTwitter=TwitterFactory.getSingleton()

その後、twitter オブジェクトは機能しますが、永続性を使用せず、毎回アプリケーションを承認する必要があるため、これは私には受け入れられません。また、Twitter オブジェクトのみが許可され、TwitterStream は例外をスローし続けます。

乾杯!

子アクティビティで取得したアクセス トークンを使用しようとする親アクティビティのソース コードを以下に示します。このトークンで何をしようとしても、常に 401 が返されます。

private void init_twitter(String tok, String sec) {

    ConfigurationBuilder cb = new ConfigurationBuilder();

    cb.setDebugEnabled(true)
      .setOAuthConsumerKey(Conf.OAUTH_CONSUMER_KEY)
      .setOAuthConsumerSecret(Conf.OAUTH_CONSUMER_SECRET)
      .setOAuthAccessToken(tok)
      .setOAuthAccessTokenSecret(sec);

    TwitterFactory tf = new TwitterFactory(cb.build());

    mTwitter=tf.getInstance();



    /** This always fails, even though I call this routine with the 
                correct token & secret !!! See at the enf of message for an alternate 
                routine like this one that makes use of verifyCredentials and
                also fails. */ 

    new Thread(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
                mTwitter.updateStatus("yello 2");
            } catch (TwitterException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }}).start();


}

子 OAuthActivity のソース コード。アクセス トークンを取得してツイートできるように動作するようです。

import a lot;

public class TwitterLogin extends Activity {

    private final String TAG = "TwitterLogin";
    public final static String PREF_KEY_OAUTH_TOKEN="twitter.oauth.token", PREF_KEY_OAUTH_SECRET="twitter.oauth.secret", PREF_KEY_TWITTER_LOGIN="twitter.oauth.login";

    private SharedPreferences mPreferences;

    private Twitter twitter = new TwitterFactory().getInstance();


    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i(TAG, "Starting task to retrieve request token.");
        this.mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
        super.onCreate(savedInstanceState);
        getActionBar().setTitle("TWITTER AUTHENTICATION");


    }

    private void returnParent(boolean result)  {
        setResult(result?Activity.RESULT_OK:Activity.RESULT_CANCELED, null);
        if (Conf.LOG_ON) Log.d(TAG, "TWITTER AUTH: END PROCESS , GLOBAL RESULT "+result);

        /** THE FOLLOWING THING WORKS !!!!! IT SUCCESSFULLY TWEETS */

        new Thread(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                try {
                    twitter.updateStatus("yello");
                } catch (TwitterException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }}).start();



        finish();
    }

    /**
     * Uses TWITTER4J to get the Request URL. It gets something like 
     * AUTH URL TWITTER4J IS http://api.twitter.com/oauth/authorize?oauth_token=xxxxxxxxxxxxxxxxxxxxx
     *
     * @return The Request URL to open in webview and get the Verifier
     */

    private String oauth_twitter4j_getRequestUrl() throws TwitterException {
        twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
        RequestToken tempToken = twitter.getOAuthRequestToken(Constants.OAUTH_CALLBACK_URL);
        return tempToken.getAuthorizationURL();
    }


    @Override
    protected void onResume() {
        super.onResume();
        WebView webview = new WebView(this);
        webview.getSettings().setJavaScriptEnabled(true);  
        webview.setVisibility(View.VISIBLE);
        setContentView(webview);

        Log.i(TAG, "Retrieving request token from Google servers");

        try {

            StrictMode.ThreadPolicy policy = new StrictMode. ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy);

            String authorizationUrl=oauth_twitter4j_getRequestUrl();
            Log.d(TAG, "AUTH URL TWITTER4J IS "+authorizationUrl_t);

            webview.setWebViewClient(new WebViewClient() {  

                @Override
                public boolean shouldOverrideUrlLoading(WebView webView, String url) { 
                    if (Conf.LOG_ON) Log.d(TAG,"WebView: "+url);
                    if (url != null && url.startsWith(Constants.OAUTH_CALLBACK_URL)) try {
                        System.out.println("TWEET TWEET TWEET");
                        retrieveAccessToken(url); //added this
                        webView.setVisibility(View.GONE); //added this
                        return true;            
                    } catch (Exception e) {
                        e.printStackTrace();
                        returnParent(false);
                        return true;
                    } else return false;
                }

                private void saveAccessToken(AccessToken accessToken) {

                    // Shared Preferences
                    Editor e = mPreferences.edit();

                    // After getting access token, access token secret
                    // store them in application preferences

                    e.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
                    e.putString(PREF_KEY_OAUTH_SECRET,accessToken.getTokenSecret());
                    e.putBoolean(PREF_KEY_TWITTER_LOGIN, true);
                    e.commit(); 

                    Log.e("Twitter OAuth Token", "> " + accessToken.getToken()+"-"+accessToken.getScreenName());

                }

                private void retrieveAccessToken(String url) throws Exception {
                    String requestToken  = extractParamFromUrl(url,"oauth_token");
                    String verifier= extractParamFromUrl(url,"oauth_verifier");
                    if (Conf.LOG_ON) Log.d(TAG, "Tenemos ACCESS TOKEN y VERIFIER :"+requestToken+","+verifier+","+(new Date().toString()));

                    if (ONLY_TWITTER4J)
                        retrieveAccessToken_with4j(verifier);
                    else
                        retrieveAccessToken_signpost(verifier);
                }

                private void retrieveAccessToken_with4j(String verifier) throws TwitterException {
                    AccessToken a=twitter.getOAuthAccessToken(verifier);
                    saveAccessToken(a);
                    returnParent(true);
                }

                private String extractParamFromUrl(String url,String paramName) {
                    String queryString = url.substring(url.indexOf("?", 0)+1,url.length());
                    QueryStringParser queryStringParser = new QueryStringParser(queryString);
                    return queryStringParser.getQueryParamValue(paramName);
                }  

            });  

            webview.loadUrl(authorizationUrl);  
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

}

正しいと確信しているトークンを使用して VerifyCredentials を呼び出すときに発生する例外:

    Received authentication challenge is null
    W/System.err(24915): Relevant discussions can be found on the Internet at:
    W/System.err(24915):    http://www.google.co.jp/search?q=6f0f59ca or
    W/System.err(24915):    http://www.google.co.jp/search?q=20d0f74e
    W/System.err(24915): TwitterException{exceptionCode=[6f0f59ca-20d0f74e 1de2170b-f94dee38], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=3.0.3}
    W/System.err(24915):    at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:192)
    W/System.err(24915):    at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:61)
    W/System.err(24915):    at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:89)
    W/System.err(24915):    at twitter4j.TwitterBaseImpl.fillInIDAndScreenName(TwitterBaseImpl.java:126)
    W/System.err(24915):    at twitter4j.TwitterImpl.verifyCredentials(TwitterImpl.java:592)
    W/System.err(24915):    at com.regaliz.helpers.TwitterManager$2.run(TwitterManager.java:140)
    W/System.err(24915):    at java.lang.Thread.run(Thread.java:856)
    W/System.err(24915): Caused by: java.io.IOException: Received authentication challenge is null
    W/System.err(24915):    at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java:397)
    W/System.err(24915):    at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java:345)
    W/System.err(24915):    at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:276)
    W/System.err(24915):    at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:479)
    W/System.err(24915):    at twitter4j.internal.http.HttpResponseImpl.<init>(HttpResponseImpl.java:34)
    W/System.err(24915):    at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:156)
    W/System.err(24915):    ... 6 more

これは、verifyCredentials を利用するために変更された関数です。

    private void init_twitter_2(final String tok, final String sec) throws TwitterException {

            ConfigurationBuilder cb = new ConfigurationBuilder();

            cb.setDebugEnabled(true)
              .setOAuthConsumerKey(Conf.OAUTH_CONSUMER_KEY)
              .setOAuthConsumerSecret(Conf.OAUTH_CONSUMER_SECRET);
    //        .setOAuthAccessToken(tok)
    //        .setOAuthAccessTokenSecret(sec);

            TwitterFactory tf = new TwitterFactory(cb.build());

            mTwitter=tf.getInstance();
            Log.d(TAG, "init_twitter_2 "+tok+","+sec);
            new Thread(new Runnable(){

                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    User u;
                    try {
                        /** also tried setting token&secret like this, instead of in the builder-->no success */
                        mTwitter.setOAuthAccessToken(new AccessToken(tok,sec));
                        u = mTwitter.verifyCredentials();
                        Log.d(TAG, "User: "+u.getName());

                    } catch (TwitterException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }}).start();


        }
4

1 に答える 1

5

愚かな人、愚かな人、愚かな人がいて、それが私です。1週間、コードに苦労し、Twitter4jをトレースし、oauthをcurlで複製し、ガベージコレクションされたアクティビティを疑い、DDMSをトレースし、トークンのハッシュを計算しました.... Conf.OAUTH_CONSUMER_xxxxxのインスタンスが2つあることがわかりました異なる値。

ものは定数から来ていて、名前が似ていたので、私はそれに気づきませんでした。

ため息 -- 50 の評判ポイントがトイレに落ちました!

于 2013-05-28T01:52:54.140 に答える