2010-07-15 68 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

希望这可以帮助其他开发者=)