2011-10-20 10 views
5

Okej, więc robię klienta Tumblr dla Androida, próbowałem i nie udało mi się uruchomić OAuth przez około tydzień. Oto, jak to działa:Android Tumblr Oauth-drogowskaz 401

Użytkownik uruchamia aplikację. Aktywność w głównym działaniu onCreate:

settings = getSharedPreferences(PREFS_NAME, 0); 
authToken=settings.getString("OauthToken", "none"); 
authTokenSecret=settings.getString("OauthSecret", "none"); 
if(authToken=="none" || authTokenSecret=="none"){ 
    Intent i = new Intent(getApplicationContext(),Authentication.class); 
    startActivity(i); 
} 

uruchamia to działanie uwierzytelniające, które zawiera WebView. Ta aktywność pomyślnie pobiera token żądania i wysyła go do ekranu logowania Tumblr. Użytkownik jest proszony, aby umożliwić dostęp do swoich danych przez aplikację, to naciśnij Zezwalaj, a mój WebViewClient łapie Callback URL, a czyni to z niego:

String[] token = helper.getVerifier(url); 
      if (token != null) { 
       try { 
        String accessToken[] = helper.getAccessToken(token[1]); 
        editor.putString("OauthToken", accessToken[0]); 
        editor.putString("OauthSecret", accessToken[1]); 
        editor.commit(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
      finish(); 

getAccessToken klasy pomocnika i getVerifier wyglądać następująco:

public String[] getVerifier(String myUrl) { 
    // extract the token if it exists 
    Uri uri = Uri.parse(myUrl); 
    if (uri == null) { 
     return null; 
    } 

    String token = uri.getQueryParameter("oauth_token"); 
    String verifier = uri.getQueryParameter("oauth_verifier"); 
    return new String[] { token, verifier }; 
} 

public String[] getAccessToken(final String verifier) 
     throws OAuthMessageSignerException, OAuthNotAuthorizedException, 
     OAuthExpectationFailedException, OAuthCommunicationException { 
    new Thread(new Runnable() { 
     public void run() { 
       try { 
        mProvider.retrieveAccessToken(mConsumer, verifier); 
       } catch (OAuthMessageSignerException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (OAuthNotAuthorizedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (OAuthExpectationFailedException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (OAuthCommunicationException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
     } 
    }).start(); 
    return new String[] { 
      mConsumer.getToken(), mConsumer.getTokenSecret() 
    }; 
} 

Wtedy w końcu wrócić do głównego ekranu aplikacji i starają się uczynić moje pierwsze wywołanie API, aby uzyskać najnowsze dziesięć posty na desce rozdzielczej użytkownika:

OAuthConsumer myConsumer = new CommonsHttpOAuthConsumer(MainView.authToken, MainView.authTokenSecret); 
      HttpGet request = new HttpGet("http://api.tumblr.com/v2/user/dashboard?limit=10"); 
      myConsumer.sign(request); 
      HttpClient httpClient = new DefaultHttpClient(); 
      HttpResponse response = httpClient.execute(request); 
      HttpEntity entity = response.getEntity(); 
      BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent())); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       builder.append(line); 
      } 

Jednak zamiast się piękny odpowiedź JSON, jak powinienem być, ja dostaję to:

10-20 16:36:18.110: D/Result(22817): {"meta":{"status":401,"msg":"Not Authorized"},"response":[]} 

Więc gdzie ja się nie udać? Dzięki

+1

Dostaję dokładnie ten sam problem, próbuję użyć metod API, które wymagają żądań POST, jednak żądania GET wydają się działać dobrze. Zaczynam się zastanawiać, czy ich API jest trochę niestabilne. –

+0

Na jakiej wersji Androida się rozwijasz? – NotACleverMan

+0

Tylko o strukturze plastra miodu. – Nick

Odpowiedz

2

Udało mi się wykorzystać bibliotekę drogowskazów z Appache HttpCommons GET/POST/PUTs.

Po pierwsze, mam rozpoczęła WebView dla celów logowania, używając następującego kodu (ActivityLogin.java):

private static CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(AppConfig.CONSUMER_KEY, AppConfig.CONSUMER_SECRET); 
private static OAuthProvider provider = new DefaultOAuthProvider (AppConfig.requestURL, AppConfig.accessURL, AppConfig.authURL); 

private void logMeIn() throws ...{ 
    String authUrl = provider.retrieveRequestToken(consumer,AppConfig.CALLBACK_URL); 
    startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl))); 
} 

Następnie użyłem onNewIntent(Intent) do odbierania wywołań zwrotnych OAuth z wcześniej uruchomił Activity:

AppConfig.java kod snipet:

/** OAuth Authorization URL */ 
public static final String authURL = mainOAuthUrl+"/authorize/?theme=android"; 

/** OAuth Request URL */ 
public static final String requestURL = mainOAuthUrl+"/request/token/"; 

/** OAuth Access URL  */ 
public static final String accessURL = mainOAuthUrl+"/access/token/"; 

/** OAuth CALLback URL*/ 
public static final String CALLBACK_URL = "yourapp://twitt"; 

ActivityLogin.java kod snipet:

protected void onNewIntent(Intent intent) { 
    Uri uri = intent.getData(); 
    if (uri != null && uri.toString().startsWith(AppConfig.CALLBACK_URL)) { 
     String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER); 

     provider.retrieveAccessToken(consumer, verifier); 
     Data.OAuthAccessKey = consumer.getToken(); 
     Data.OAuthAccessSecret = consumer.getTokenSecret(); 
    } 

} 

A potem, mój kod gra wygląda tak:

public HttpResponse sampleOauthConnect(String url) throws ...{ 

    /** setup some connection params */ 
    HttpContext context = new BasicHttpContext(); 

    HttpRequestBase request = new HttpGet(url); 

    if (Data.OAuthConsumer == null) 
     Data.OAuthConsumer = new CommonsHttpOAuthConsumer(AppConfig.CONSUMER_KEY, AppConfig.CONSUMER_SECRET); 

    if (Data.OAuthAccessKey == null || Data.OAuthAccessSecret == null) 
     throw new LoginErrorException(LoginErrorException.NOT_LOGGED_IN); 

    Data.OAuthConsumer.setTokenWithSecret(Data.OAuthAccessKey, Data.OAuthAccessSecret); 

    try { 
     Data.OAuthConsumer.sign(request); 
    } catch (OAuthMessageSignerException e) { 
     throw new LoginErrorException(LoginErrorException.OAUTH_EXCEPTION, e); 
    } catch (OAuthExpectationFailedException e) { 
     throw new LoginErrorException(LoginErrorException.OAUTH_EXCEPTION, e); 
    } catch (OAuthCommunicationException e) { 
     throw new LoginErrorException(LoginErrorException.OAUTH_EXCEPTION, e); 
    } 

    HttpClient client = new DefaultHttpClient(); 

    /** finally execute this request */ 
    return client.execute(request, context); 
} 

mogę coś przeoczyć podczas kopiowania i wklejania, po prostu powiedz mi, czy to rozwiązanie będzie pracować dla Ciebie. Używam singpost 1.2.1.1

+0

Nie mam czasu, aby przetestować kod teraz, a nawet w ciągu kilku następnych dni, ale odkąd skończyła się nagroda i wygląda na super pomocny dokładny wpis, wygrywasz! Dziękuję, dowiem się, czy to faktycznie zadziała później – Nick

+0

Pamiętaj, że używam dwóch par kluczy tam: 'AppConfig.CONSUMER_KEY, AppConfig.CONSUMER_SECRET' (które są przechowywane w aplikacji) i' Data.OAuthAccessKey, Data.OAuthAccessSecret', które są generowane przez serwer. – Kocus

+0

uzyskanie tej samej odpowiedzi nieautoryzowanej: {"meta": { "status": 401, "msg": "Nie autoryzowany"}, "odpowiedź": []} – DcodeChef

1

Obecnie Tumblr nie obsługuje MultipartEntity, więc musisz dodać NameValuePairs, aby dodać parametry.

Jeśli chcesz opublikować zdjęcie, MUSISZ przekonwertować to zdjęcie na ARRAY i zakodować je!

+0

Wystąpił problem z publikowaniem zdjęć. Co masz na myśli mówiąc "... przekonwertuj to zdjęcie na ARRAY i zakodować je URL"? Czy możesz podać fragment kodu? –

+0

Biblioteka własna Tumblera (Jumblr) używa formularzy wieloczęściowych: https://github.com/tumblr/jumblr/blob/master/src/main/java/com/tumblr/jumblr/request/MultipartConverter.java – Jabari

Powiązane problemy