2010-07-15 11 views
8

Sto configurando OAuth per la mia app per Android. Per testarlo ho fatto quanto segue: Aggiunto signpost-core-1.2.1.1.jar e signpost-commonshttp4-1.2.1.1.jar al mio progetto, aggiunto le variabili "CommonsHttpOAuthConsumer consumer" e "CommonsHttpOAuthProvider provider" e ho fatto quanto segue quando il pulsante viene premuto:Android OAuth: Eccezione su 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() effettua le seguenti operazioni:

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

Così, il consumatore e il fornitore vengono salvati prima di aprire il browser, come descritto here.

Nel metodo onResume() ho caricare i dati del provider e dei consumatori e procedere come segue:

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

Allora, che cosa funziona: 1) io capisco un requestToken e requestSecret. 2) Ottengo l'oauthUrl. 3) Sono indirizzato alla pagina del browser per autorizzare la mia app 4) Mi viene reindirizzato alla mia app. 5) Ottengo il verificatore. Ma chiamare retrieveAccessToken (consumer, verificatore) non riesce con una OAuthCommunicationException che dice "Comunicazione con il provider di servizi fallita: null".

Qualcuno sa quale potrebbe essere la ragione? Alcune persone sembrano avere problemi nel ricevere la richiesta, ma funziona perfettamente. Mi chiedo se potrebbe essere un problema che la mia app abbia incluso anche apache-mime4j-0.6.jar e httpmime-4.0.1.jar di cui ho bisogno per il caricamento multipart.

risposta

13

Ok, l'ho capito. Forse questo è utile per gli altri:

Prima di tutto, non è necessario salvare l'intero oggetto consumatore e fornitore. Tutto ciò che devi fare è memorizzare la richiestaToken e la richiestaSecret. Fortunatamente, quelle sono stringhe, quindi non è necessario scriverle su disco o altro. Basta archiviarli nelle SharedPreferences o qualcosa del genere.

Ora, quando si arriva reindirizzati dal browser e la vostra onResume() metodo viene chiamato, basta fare il seguente:

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

Questo è tutto, è possibile ricevere il token e il segreto con ControllaToken() e getTokenSecret(), ora.

+0

Grazie mille ... questo risolto il mio problema ... grande opera Manuel – Panache

+0

Quindi nel tuo caso, il 'requestToken' che hai impostato in' consumer.setOkenWithSecret' è 'oauthUrl'? e posso chiedere qual è il 'tokenSecret'? Grazie :) – dumbfingers

+0

Scusa, penso di aver capito, è il 'requestToken' recuperato usando' consumer.getToken() '? – dumbfingers

0

Ciao Manuel, vedo che stai evitando anche l'OAuthocalypse! heres è un buon esempio per implementare OAuth per Twitter utilizzando sharedPreferences per salvare requestToken e requestSecret, come la tua soluzione. http://github.com/brione/Brion-Learns-OAuth da Brion Emde

heres il video

speranza che questo aiuta altri sviluppatori =)

Problemi correlati