2010-07-15 77 views
8

我正在爲我的Android應用程序設置OAuth。爲了測試它,我做了以下操作: 將signpost-core-1.2.1.1.jar和signpost-commonshttp4-1.2.1.1.jar添加到我的項目中,添加了變量「CommonsHttpOAuthConsumer consumer」和「CommonsHttpOAuthProvider provider」,並在執行以下操作時執行以下操作該按鈕被點擊:Android OAuth:retrieveAccessToken()的例外

consumer = new CommonsHttpOAuthConsumer("xxx", "yyy"); 
provider = new CommonsHttpOAuthProvider("https://api.twitter.com/oauth/request_token", 
        "https://api.twitter.com/oauth/access_token", 
        "https://api.twitter.com/oauth/authorize"); 

oauthUrl = provider.retrieveRequestToken(consumer, "myapp://twitterOauth"); 
persistOAuthData(); 
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(oauthUrl))); 

persistOAuthData()進行以下操作:

protected void persistOAuthData() 
{ 
    try 
    { 
     FileOutputStream providerFOS = this.openFileOutput("provider.dat", MODE_PRIVATE); 
     ObjectOutputStream providerOOS = new ObjectOutputStream(providerFOS); 
     providerOOS.writeObject(this.provider); 
     providerOOS.close(); 

     FileOutputStream consumerFOS = this.openFileOutput("consumer.dat", MODE_PRIVATE); 
     ObjectOutputStream consumerOOS = new ObjectOutputStream(consumerFOS); 
     consumerOOS.writeObject(this.consumer); 
     consumerOOS.close(); 
    } 
    catch (Exception e) { } 
} 

所以,消費者和供應商正在打開瀏覽器之前保存的,就像描述here

在的onResume()方法我加載提供者和消費者數據,並執行以下操作:

Uri uri = this.getIntent().getData(); 
    if (uri != null && uri.getScheme().equals("myapp") && uri.getHost().equals("twitterOauth")) 
    { 
     verifier = uri.getQueryParameter(oauth.signpost.OAuth.OAUTH_VERIFIER); 
     if (!verifier.equals("")) 
     { 
      loadOauthData(); 
      try 
      { 
       provider.retrieveAccessToken(consumer, verifier); 
      } 
      catch (OAuthMessageSignerException e) { 
       e.printStackTrace(); 
      } catch (OAuthNotAuthorizedException e) { 
       e.printStackTrace(); 
      } catch (OAuthExpectationFailedException e) { 
       e.printStackTrace(); 
      } catch (OAuthCommunicationException e) { 
       e.printStackTrace(); 
      }    
     } 
    } 

那麼,是什麼在起作用: 1)我得到一個requestToken和requestSecret。 2)我確實得到了oauthUrl。 3)我被引導到瀏覽器頁面授權我的應用程序 4)我被重定向到我的應用程序。 5)我確實得到了驗證者。 但調用retrieveAccessToken(使用者,驗證者)失敗,併發生OAuthCommunicationException異常,說「與服務提供者的通信失敗:null」。

有誰知道可能是什麼原因?有些人似乎在獲取requestToken時遇到了問題,但這樣做很好。我想知道是否這可能是一個問題,我的應用程序還包括我需要分段上傳的apache-mime4j-0.6.jar和httpmime-4.0.1.jar。

回答

13

好的,我想通了。也許這有助於他人:

首先,你不需要保存整個消費者和提供者對象。所有你需要做的就是存儲requestToken和requestSecret。幸運的是,這些是字符串,所以你不需要將它們寫入磁盤或任何東西。只需將它們存儲在sharedPreferences或類似的東西中即可。

現在,當你被瀏覽器您的onResume()方法被調用,只要做到以下重定向和:

//The consumer object was lost because the browser got into foreground, need to instantiate it again with your apps token and secret. 
consumer = new CommonsHttpOAuthConsumer("xxx", "yyy"); 

//Set the requestToken and the tokenSecret that you got earlier by calling retrieveRequestToken. 
consumer.setTokenWithSecret(requestToken, tokenSecret); 

//The provider object is lost, too, so instantiate it again. 
provider = new CommonsHttpOAuthProvider("https://api.twitter.com/oauth/request_token", 
           "https://api.twitter.com/oauth/access_token", 
           "https://api.twitter.com/oauth/authorize");  
//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); 

provider.retrieveAccessToken(consumer, verifier); 

就是這樣,你可以得到令牌,併爲gettoken的祕密()和getTokenSecret(),現在。

+0

非常感謝...這解決了我的問題......偉大的工作曼努埃爾 – Panache 2011-08-25 15:29:02

+0

因此,在你的情況下, 'consumer.setOkenWithSecret'中設置的'requestToken'是'oauthUrl'?我可以問什麼是'tokenSecret'?謝謝:) – dumbfingers 2013-07-16 21:13:08

+0

對不起,我想我可能會想出來,是使用'consumer.getToken()'檢索到的'requestToken'? – dumbfingers 2013-07-16 21:22:39

0

嗨曼努埃爾我看到你也在OAuthocalypse中避免! 繼承人是一個使用sharedPreferences來保存requestToken和requestSecret的Twitter實現OAuth的好例子,就像您的解決方案一樣。 http://github.com/brione/Brion-Learns-OAuth 由Brion的昂德

繼承人的video

希望這可以幫助其他開發者=)