Search code examples
androidandroid-emulatorandroid-networkingandroid-embedded-api

OAuth: Exception on retrieveAccessToken() while connecting with yahoo on emulator?


Above error comes when integrated to yahoo

provider define below

code

provider = new CommonsHttpOAuthProvider(
                "https://api.login.yahoo.com/oauth/v2/get_request_token",
                "https://api.login.yahoo.com/oauth/v2/get_token",
                "https://api.login.yahoo.com/oauth/v2/request_auth");

Consumer and Oauth_Verifier

            consumer = new CommonsHttpOAuthConsumer(
                "ppp",
                "lll");

        consumer.setMessageSigner(new HmacSha1MessageSigner());

String oauth_verifier = uri
            .getQueryParameter(OAuth.OAUTH_VERIFIER);

Error shown when try to access token from yahoo api :-

oauth.signpost.exception.OAuthCommunicationException: Communication with the service provider failed: null

when run below code then exception come into above :-

 provider.retrieveAccessToken(consumer, oauth_verifier);

Solution

  • BIG EDIT

    I highly recommend not using Signpost unless you have a plan on how to handle the token refresh. Signpost doesn't have methods to make this happen. I switched to Scribe which is much easier to use. Unfortunately It too doesn't have methods to help with Token Refresh, but I was able to write a helper method fairly easily.

    I now have the Yahoo API working 100% on Android. If you're not able to figure it out with Signpost and will switch to Scribe I'll post my code.


    This is working for me from start to finish. I'm also able to reuse a key. Tricky stuff if you do 1 thing out of sequence it breaks. This is a rough version by the way which I intend to clean up. Still have to figure out renewing the token after 60 minutes.

    Android Manifest

    <activity
        android:name=".UpdaterActivity"
        android:label="@string/app_name"
        android:launchMode="singleInstance" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter> 
            <action android:name="android.intent.action.VIEW" /> 
            <category android:name="android.intent.category.DEFAULT" /> 
            <category android:name="android.intent.category.BROWSABLE" /> 
            <data android:scheme="yfbwa" android:host="oauth"></data> 
        </intent-filter> 
    </activity>
    

    UpdaterActivity.java

    private static final String CONSUMER_KEY = "";
    private static final String CONSUMER_SECRET = "";
    private static final String REQUEST_TOKEN_URL = "https://api.login.yahoo.com/oauth/v2/get_request_token";
    private static final String ACCESS_TOKEN_URL = "https://api.login.yahoo.com/oauth/v2/get_token";
    private static final String AUTHORIZE_WEBSITE_URL = "https://api.login.yahoo.com/oauth/v2/request_auth";
    private static final String CALLBACK_URL = "yfbwa://oauth";
    private OAuthConsumer consumer;
    private OAuthProvider provider;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        consumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET); 
        provider = new CommonsHttpOAuthProvider(REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZE_WEBSITE_URL);
        if(getIsAuthorized() == 0) {
            callOAuth();
        } else {
            makeRequest("http://fantasysports.yahooapis.com/fantasy/v2/users;use_login=1/games;game_keys=308/teams?format=json");
        }
    }
    
    private void callOAuth() { 
        String url = provider.retrieveRequestToken(consumer, CALLBACK_URL);
        this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); 
    }
    
    @Override 
    protected void onNewIntent(Intent intent) { 
        Uri data = intent.getData();
        String verifier = data.getQueryParameter(OAuth.OAUTH_VERIFIER);
        provider.retrieveAccessToken(consumer, URLDecoder.decode(verifier,"UTF-8"));
        writePrefs(consumer.getToken(), consumer.getTokenSecret());
        makeRequest("http://fantasysports.yahooapis.com/fantasy/v2/users;use_login=1/games;game_keys=308/teams?format=json");
    }
    
    private void makeRequest(String url) throws OAuthMessageSignerException, OAuthNotAuthorizedException, OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException, IOException {
        String[] prefs = getPrefs();
        consumer.setTokenWithSecret(prefs[0], prefs[1]);
        HttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(url);
        consumer.sign(request);
        HttpResponse response = httpClient.execute(request);
        String result = EntityUtils.toString(response.getEntity());
    }
    
    private void writePrefs(String token, String tokenSecret) {
        Editor prefsEditor = getSharedPreferences("ybfwa", MODE_PRIVATE).edit();
        prefsEditor.putString("token",token);
        prefsEditor.putString("tokenSecret",tokenSecret);
        prefsEditor.putInt("isAuthorized",1);
        prefsEditor.commit();
    }
    
    private String[] getPrefs() {
        String[] prefs = new String[2];
        SharedPreferences myPrefs = getSharedPreferences("ybfwa", MODE_PRIVATE);
        prefs[0] = myPrefs.getString("token", null);
        prefs[1] = myPrefs.getString("tokenSecret", null);
        return prefs;
    }
    
    private int getIsAuthorized() {
        SharedPreferences myPrefs = getSharedPreferences("ybfwa", MODE_PRIVATE);
        return myPrefs.getInt("isAuthorized", 0);
    }