Android OAuth: Exception on retrieveAccessToken()

I'm setting up OAuth for my Android app. To test it I did the following: Added signpost-core-1.2.1.1.jar and signpost-commonshttp4-1.2.1.1.jar to my project, added the variables "CommonsHttpOAuthConsumer consumer" and "CommonsHttpOAuthProvider provider" and did the following when the button is clicked:

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() does the following:

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) { }
}

So, the consumer and the provider are saved before opening the browser, like described here.

In the onResume() method I load the provider and consumer data and do the following:

    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();
            }            
        }
    }

So, what works: 1) I do get a requestToken and a requestSecret. 2) I do get the oauthUrl. 3) I am directed to the browser page to authorize my app 4) I am getting redirected to my app. 5) I do get the verifier. But calling retrieveAccessToken(consumer, verifier) fails with an OAuthCommunicationException saying "Communication with the service provider failed: null".

Does anyone know what might be the reason? Some people seem to have problems getting the requestToken, but that just works fine. I wonder if it might be a problem that my app has also included the apache-mime4j-0.6.jar and httpmime-4.0.1.jar which I need for multipart upload.

This question and answers originated from www.stackoverflow.com
Question by (7/15/2010 11:37:20 AM)

Answer

Okay, I figured it out. Maybe this is helpful to others:

First of all, you do not need to save the whole consumer and provider object. All you need to do is store the requestToken and the requestSecret. Luckily, those are Strings, so you don't need to write them to disk or anything. Just store them in the sharedPreferences or something like that.

Now, when you get redirected by the browser and your onResume() method is called, just do the following:

//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);

That's it, you can receive the token and the secret with getToken() and getTokenSecret(), now.

Answer by

Find More Answers
Related Topics  android  twitter  oauth  signpost
Related Questions
  • Problem with OAuth, Twitter and Android: fails in http-communication with the server

    Does anyone have a working example of OAuth authentication for twitter with Android? I have tried to use both Twitter4J and SignPost, but I get very strange errors, saying twitter.com is an unknown …
  • Getting 401 when requesting access token with signpost within android

    Here is my code, i keep getting an exception "Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match." on this line 'pr…
  • Twitter4j retrieveAccessToken issue since Twitter oauth change

    Using twitter4j on Android my app was able to consistently update twitter, now since the oauth change it will work after the user authenticates the app once and fail every time after that until the …
  • Yahoo OAuth on Android - 401 error

    I'm trying to implement OAuth for Google, Twitter, Yahoo etc. on Android using the signpost libraries. All of the above work fine, except Yahoo, which gives me a 401 error when trying to retrieve…
  • Oauth on android using signpost library

    I try since a few days to connect one of my android app to an oauth service. I have found a few really good articles like http://blog.doityourselfandroid.com/2011/04/12/oauth-android-google-apis-cli…
  • Android Tumblr oAuth Confusion

    I'm trying to implement the Tumblr API in an Android app. I'm really getting stuck with authorizing a user so that they can do things such as post and view their dashboard. I don't really understand…
  • Android Tumblr Oauth-signpost 401

    Okay, so, I am making a Tumblr client for Android, I've been trying and failing to get OAuth working for about a week now. Here's how its going: User fires up the app. Main activity's onCreate do…
  • Signpost OAuth on Android: how to re-create the Consumer between two succesive runs?

    I'm succesfully using Signpost to authorize calls to protected resources in a Google account via OAuth. However it seems a bit weird that the user has to go each and every time through Google and…
  • OAuth 1.0 Libraries for Android (java)

    I'm trying to access user data from a site that supports OAuth 1.0 without callbacks. I'm using the signpost library and I'm not able to retrieve the access token because the site I'm trying to conn…
  • oauth_callback on Android

    I created a Twitter app I need user of my Android application to authorize its use. I'm at the point where I can call Twitter app page in the browser and successfully authorize. However, the callbac…