2010-07-15 7 views
8

Ich richte OAuth für meine Android-App ein. Um es zu testen, habe ich Folgendes getan: Added signpost-core-1.2.1.1.jar und signpost-commonshttp4-1.2.1.1.jar zu meinem Projekt hinzugefügt die Variablen "CommonsHttpOAuthConsumer Verbraucher" und "CommonsHttpOAuthProvider Anbieter" und tat folgendes wenn die Schaltfläche geklickt wird:Android OAuth: Ausnahme bei 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() führt folgendes aus:

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

der Verbraucher und der Anbieter So werden gespeichert, bevor der Browser geöffnet wird, wie here beschrieben.

Im onResume() -Methode laden ich die Provider- und Consumer-Daten und wie folgt vorgehen:

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

Also, was funktioniert: 1) bekomme ich tun, um eine requestToken und requestSecret. 2) Ich bekomme die OAUTHURl. 3) Ich bin auf die Browser-Seite gerichtet, um meine App zu autorisieren 4) Ich werde auf meine App umgeleitet. 5) Ich bekomme den Verifizierer. Der Aufruf von retrieveAccessToken (consumer, verifier) ​​schlägt jedoch mit einer OAuthCommunicationException fehl, die besagt "Kommunikation mit dem Service Provider ist fehlgeschlagen: null".

Weiß jemand, was der Grund sein könnte? Einige Leute haben Probleme, den requestToken zu bekommen, aber das funktioniert einfach. Ich frage mich, ob es ein Problem sein könnte, dass meine App auch die Apache-Mime4j-0.6.jar und httpmime-4.0.1.jar enthalten, die ich für Multipart-Upload benötige.

Antwort

13

Okay, ich habe es herausgefunden. Vielleicht ist dies hilfreich für andere:

Zunächst müssen Sie nicht das gesamte Verbraucher- und Provider-Objekt speichern. Alles, was Sie tun müssen, ist das requestToken und das requestSecret zu speichern. Zum Glück sind das Strings, also müssen Sie sie nicht auf die Festplatte schreiben oder so. Speichern Sie sie einfach in den sharedPreferences oder so ähnlich.

Nun, wenn Sie durch den Browser weitergeleitet und Ihre onResume() -Methode aufgerufen wird, nur Folgendes tun:

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

Das ist es, können Sie das Token und das Geheimnis mit getToken() erhalten und getTokenSecret(), jetzt.

+0

vielen Dank ... das ist mein Problem gelöst ... großartige Arbeit Manuel – Panache

+0

Also in Ihrem Fall des 'requestToken', das Sie in' consumer.setOkenWithSecret' gesetzt haben, ist 'oauthUrl'? und darf ich fragen, was ist das TokenSecret? Danke :) – dumbfingers

+0

Entschuldigung, ich denke, ich kann es herausfinden, ist das 'requestToken' abgerufen mit' consumer.getToken() '? – dumbfingers

0

Hallo Manuel ich sehe, du bist auch in der OAuthocalypse meiden! Heres ist ein gutes Beispiel, um OAuth für Twitter mit sharedPreferences zu implementieren, um requestToken und requestSecret wie Ihre Lösung zu speichern. http://github.com/brione/Brion-Learns-OAuth von Brion Emde

heren der video

hoffen, dass diese anderen Entwicklern hilft =)