Android OAuth:retrieveAccessToken()上的异常

Man*_*uel 8 twitter android oauth signpost

我正在为我的Android应用设置OAuth.为了测试它我执行了以下操作:在我的项目中添加了signpost-core-1.2.1.1.jar和signpost-commonshttp4-1.2.1.1.jar,添加了变量"CommonsHttpOAuthConsumer consumer"和"CommonsHttpOAuthProvider provider"并在执行时执行以下操作单击按钮:

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)));
Run Code Online (Sandbox Code Playgroud)

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) { }
}
Run Code Online (Sandbox Code Playgroud)

所以,消费者和供应商正在打开浏览器,如之前描述保存在这里.

在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();
            }            
        }
    }
Run Code Online (Sandbox Code Playgroud)

这样,有效:1)我得到一个requestToken和一个requestSecret.2)我确实得到了oauthUrl.3)我被引导到浏览器页面来授权我的应用程序4)我被重定向到我的应用程序.5)我确实得到了验证者.但调用retrieveAccessToken(使用者,验证者)失败,并显示"与服务提供者的通信失败:null"的OAuthCommunicationException.

有谁知道可能是什么原因?有些人似乎在获取requestToken时遇到了问题,但这样做效果很好.我想知道我的应用程序是否也包含apache-mime4j-0.6.jar和httpmime-4.0.1.jar可能是一个问题,我需要进行分段上传.

Man*_*uel 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);
Run Code Online (Sandbox Code Playgroud)

就是这样,你现在可以通过getToken()和getTokenSecret()接收令牌和秘密.