2010-07-15 6 views
8

Je configure OAuth pour mon application Android. Pour le tester, j'ai fait ce qui suit: Ajout de signpost-core-1.2.1.1.jar et de signpost-commonshttp4-1.2.1.1.jar à mon projet, ajout des variables "CommonsHttpOAuthConsumer consumer" et "CommonsHttpOAuthProvider provider" et fait ce qui suit quand clique sur le bouton:Android OAuth: Exception sur 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() effectue les opérations suivantes:

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

Ainsi, le consommateur et le fournisseur sont enregistrés avant d'ouvrir le navigateur, comme décrit here.

Dans la méthode onResume() je charge le fournisseur et consommateur de données et procédez comme suit:

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

Alors, ce qui fonctionne: 1) Je reçois un requestToken et un requestSecret. 2) Je reçois le fichier oauthUrl. 3) Je suis dirigé vers la page du navigateur pour autoriser mon application 4) Je suis redirigé vers mon application. 5) Je reçois le vérificateur. Toutefois, l'appel à retrieveAccessToken (consommateur, vérificateur) échoue avec une exception OAuthCommunicationException indiquant que la communication avec le fournisseur de services a échoué: null.

Est-ce que quelqu'un sait quelle pourrait être la raison? Certaines personnes semblent avoir des problèmes pour obtenir le requestToken, mais cela fonctionne bien. Je me demande si cela pourrait être un problème que mon application a également inclus le apache-mime4j-0.6.jar et httpmime-4.0.1.jar dont j'ai besoin pour le téléchargement en plusieurs parties.

Répondre

13

D'accord, je l'ai compris. Peut-être que cela est utile à d'autres:

Tout d'abord, vous n'avez pas besoin d'enregistrer l'ensemble de l'objet consommateur et fournisseur. Tout ce que vous devez faire est de stocker le requestToken et le requestSecret. Heureusement, ce sont des chaînes, donc vous n'avez pas besoin de les écrire sur le disque ou quoi que ce soit. Il suffit de les stocker dans les sharedPreferences ou quelque chose comme ça.

Maintenant, quand vous êtes redirigé par le navigateur et votre méthode onResume() est appelée, juste effectuer les opérations suivantes:

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

C'est, vous pouvez recevoir le jeton et le secret avec getToken() et getTokenSecret(), maintenant.

+0

merci beaucoup ... ce a résolu mon problème ... excellent travail Manuel – Panache

+0

Donc, dans votre cas, la 'requestToken' vous définissez dans' consumer.setOkenWithSecret' est 'oauthUrl'? et puis-je demander quel est le 'tokenSecret'? Merci :) – dumbfingers

+0

Désolé, je pense que je peux comprendre, est le 'requestToken' récupéré en utilisant' consumer.getToken() '? – dumbfingers

0

Salut Manuel je vois que vous évitez aussi l'OAuthocalypse! heres est un bon exemple pour mettre en œuvre OAuth pour Twitter en utilisant sharedPreferences pour sauvegarder requestToken et le requestSecret, comme votre solution. http://github.com/brione/Brion-Learns-OAuth par Brion Emde

Heres le video

espérons que cette aide d'autres développeurs =)