2011-07-25 23 views
4

我在我的應用程序中實現了Twitter,我在回調中遇到問題。Android中的Twitter中的回調問題

Twitter API的最近更新,所以我無法發送回叫URL。

此外,設置頁面現在改變,沒有選擇基於Web的應用程序或桌面應用程序的選項。

如果我在這一行發送回叫:

authUrl = provider.retrieveRequestToken(consumer,CALLBACK_URL); 

它總是返回

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. 

,但如果我的重定向發送爲在這個給Twitter登錄頁面,但經過成功授權它不會返回到我的應用程序。

在顯示PIN號後,我想重定向回我的應用程序。

注意:Twitter已經更新了他們的API,因此Post中的舊代碼無法使用。

我嘗試了所有以下鏈接

Link 1Link 2Link 3Link4Link5Link 6

我的代碼如下:

public class Main extends Activity { 
OAuthConsumer consumer; 
OAuthProvider provider; 
Twitter twitter; 
private static String CALLBACK_URL = "twitterapptest://connect"; 


@Override 
public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    setContentView(R.layout.main); 

    consumer = new DefaultOAuthConsumer(
      "XXXXXXXXXXX", 
      "XXXXXXXXXXXXX"); 

    provider = new DefaultOAuthProvider(
      "https://api.twitter.com/oauth/request_token", 
      "https://api.twitter.com/oauth/access_token", 
      "https://api.twitter.com/oauth/authorize"); 

    String authUrl = null; 
    try { 
     authUrl = provider.retrieveRequestToken(consumer,null); 
     this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl))); 
    } catch (OAuthMessageSignerException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (OAuthNotAuthorizedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (OAuthExpectationFailedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (OAuthCommunicationException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
    String pin = null; 
    try { 
     pin = br.readLine(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    try { 
     provider.retrieveAccessToken(consumer, "4947222"); 
    } catch (OAuthMessageSignerException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (OAuthNotAuthorizedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (OAuthExpectationFailedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (OAuthCommunicationException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    URL url = null; 
    try { 
     url = new URL("http://twitter.com/statuses/mentions.xml"); 
    } catch (MalformedURLException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    HttpURLConnection request = null; 
    try { 
     request = (HttpURLConnection) url.openConnection(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    try { 
     consumer.sign(request); 
    } catch (OAuthMessageSignerException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } catch (OAuthExpectationFailedException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } catch (OAuthCommunicationException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
    try { 
     request.connect(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    try { 
     System.out.println("Response: " + request.getResponseCode() + " " 
       + request.getResponseMessage()); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 


/** 
* As soon as the user successfully authorized the app, we are notified 
* here. Now we need to get the verifier from the callback URL, retrieve 
* token and token_secret and feed them to twitter4j (as well as 
* consumer key and secret). 
*/ 

    @Override 
    protected void onNewIntent(Intent intent) { 

     super.onNewIntent(intent); 

     Uri uri = intent.getData(); 
     if (uri != null && uri.toString().startsWith(CALLBACK_URL)) { 

      String verifier = uri 
        .getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER); 

      try { 
       // this will populate token and token_secret in consumer 

       provider.retrieveAccessToken(consumer, 
         verifier); 

       // TODO: you might want to store token and token_secret in you 
       // app settings!!!!!!!! 

       AccessToken a = new AccessToken(consumer.getToken(), 
         consumer.getTokenSecret()); 

       // initialize Twitter4J 

       twitter = new TwitterFactory().getInstance(); 
       twitter.setOAuthConsumer("XXXXXXX", "XXXXXXXXXX"); 
       twitter.setOAuthAccessToken(a); 

       // create a tweet 

       Date d = new Date(System.currentTimeMillis()); 
       String tweet = "#OAuth working! " + d.toLocaleString(); 

       // send the tweet 

       twitter.updateStatus(tweet); 

      } catch (Exception e) { 

       Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show(); 
      } 
     } 
    } 
} 

我的清單:

<?xml version="1.0" encoding="utf-8"?> 

<activity android:name=".OAuthForTwitter" android:label="@string/app_name" 
      android:configChanges="orientation|keyboardHidden" android:launchMode="singleInstance"> 
    <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="twitterapptest" android:host="connect" /> 
    </intent-filter> 

</activity> 

</application> 
<uses-sdk android:minSdkVersion="4" /> 
<uses-permission android:name="android.permission.INTERNET" /> 

+0

401錯誤可能是由幾件事引起的。特別是,檢查您的API密鑰是否正確(沒有多餘的空格或缺少字符),並檢查設備上的日期/時間和時區是否正確。 – Dave

+0

@Dave您是否在您的應用程序中使用過Twitter? – Venky

回答

8

的問題是,回調URL。 我們應該在應用程序的設置頁面中的CallBack URL的字段名稱中提供一個虛擬回調URL。

如果我們做到這樣的,在我們的代碼將呼叫發送回URL,成功登錄後,會出現一個選項叫重定向到您的應用程序

備查檢查這個Link for Twitter

+1

+1 - 非常好,這對我有很大的幫助。 –

+0

鏈接不能再工作。我有重定向問題。使用本地主機作爲重定向網址顯示本地主機的網頁。它不會返回到我的應用程序的任何建議? –

3

有你發現問題來自哪裏?我有同樣的一種懷疑,最後我發現這是從哪裏來的。正確的是,Twitter的設置頁面發生了變化,您不能再選擇基於Web的應用程序或桌面應用程序。但是這裏有一些提示:在Twitter應用程序的設置中,只需填充回調URL,並填入一個虛擬文件,如http://www.dummy.com。這會隱式設置你的應用程序有一個網頁瀏覽器,然後當你發送你自己的回調時,它會重新放置一個虛擬的。 我花了很多時間來找到這個,所以我希望這個答案能幫助別人。

0

將下面的Callback URL添加到應用程序將解決該問題。這將用戶重定向到其開始它在Manifest驗證用戶的Twitter account_

更新Application _

<activity android:name="<YOUR ACTIVITY NAME>" 
     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> 

在你TwitterManager,你有你的TwitterFactory和所需things_

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

最後,你可以得到你的一切need_ 例如,getHostgetSchemegetEncodedQuerygetQuerygetEncodedSchemeSpecificPart多按使用需要intent由調用返回back_

@Override 
protected void onNewIntent(final Intent intent) { 
    super.onNewIntent(intent); 

    new AsyncTask<Void,Void,Void>(){ 
     @Override 
     protected Void doInBackground(Void... arg0) { 
      Uri uri = intent.getData(); 
      if (uri != null && uri.toString().startsWith(TwitterManager.TWITTER_CALLBACK_URL)) { 
       String verifier = uri.getQueryParameter(TwitterManager.TWITTER_IEXTRA_OAUTH_VERIFIER); 
       Log.e("---ActivityMain-onNewIntent---", "verifier:"+verifier+", uri- getQuery:"+uri.getQuery()); 
       Log.i(ApplicationPockets.TAG, "verifier : "+verifier); 
       if(verifier != null){ 
        try { 
        /* 
         *---Get the AccessToken and do what you like ... :) 
         */ 
         AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, verifier); 
         SharedPreferences.Editor e = context.getSharedPreferences(SF_TWITTER, Context.MODE_PRIVATE).edit(); 
         e.putString(TWITTER_PREF_KEY_TOKEN, accessToken.getToken()); 
         e.putString(TWITTER_PREF_KEY_SECRET, accessToken.getTokenSecret()); 
         e.commit(); 
        //Extra you would like to do... 
        } catch (TwitterException e) { 
         e.printStackTrace(); 
        } 
       }else{ 
        //Logout Twitter. 
       } 
      } 
      return null; 
     } 
    }.execute(); 
} 

你RequestToken_

try { 
     RequestToken requestToken = twitter.getOAuthRequestToken(TWITTER_CALLBACK_URL); 
     //Toast.makeText(activity, "Please authorize this app!", Toast.LENGTH_LONG).show(); 
     activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(requestToken.getAuthenticationURL()))); 
     } catch (TwitterException e) { 

      e.printStackTrace(); 
    } 

我希望這將幫助everyone_