Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using OAuth with Scribe on Android

Hi I'm using the scribe library for OAuth communication with LInkedIn.

I have a login class and a query class.

The login class creates a service to get my request token and secret and creates my access token. The access token is then saved to the preferences file. This seems to work fine and I can make a successful api call after all the tokens have been created.

In my OAuth query class i retrieve the access token, create another service and try to make an API call, but when ever I load an activity which makes calls this class it causes my app to crash. I have tested to make sure that the access token is saved and they are.

Here is my login class

public class Login_LinkedIn extends Activity 
{
SharedPreferences settings;
OAuthService service;
Token requestToken;

Button home;

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.webauth);

    initControls();

    service = new ServiceBuilder()
    .provider(LinkedInApi.class)
    .apiKey( getString(R.string.apiKey) )
    .apiSecret( getString(R.string.secKey) )
    .callback( getString(R.string.callBack) )
    .build();

    requestToken = service.getRequestToken();
    final String authURL = service.getAuthorizationUrl(requestToken);

    final WebView webview = (WebView) findViewById(R.id.webView);

    //attach WebViewClient to intercept the callback url
    webview.setWebViewClient(new WebViewClient()
    {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {

            //check for our custom callback protocol
            //otherwise use default behavior
            if(url.startsWith( getString(R.string.callBack) ))
            {
                //authorization complete hide webview for now.
                webview.setVisibility(View.GONE);
                Uri uri = Uri.parse(url);
                String verifier = uri.getQueryParameter("oauth_verifier");
                Verifier v = new Verifier(verifier);

                //save this token for practical use.
                Token accessToken = service.getAccessToken(requestToken, v);

                OAuthRequest request = new OAuthRequest(Verb.GET, "http://api.linkedin.com/v1/people/~:(first-name,last-name)");
                service.signRequest(accessToken, request);
                Response response = request.send();

                xmlHandler xh = new xmlHandler(response.getBody());

                settings = getSharedPreferences("preferences", 0);
                SharedPreferences.Editor editor = settings.edit();

                editor.putString("accessToken", accessToken.getToken());

                // The requestToken is saved for use later on to verify the OAuth request.
                // See onResume() below
                editor.putString("requestToken", requestToken.getToken());
                editor.putString("requestSecret", requestToken.getSecret());

                editor.putString("first-name", xh.getValue("first-name"));
                editor.putString("last-name", xh.getValue("last-name"));

                editor.commit();

                return true;
            }
            return super.shouldOverrideUrlLoading(view, url);
        }
   });

   //send user to authorization page
   webview.loadUrl(authURL); 
}

@Override
protected void onResume()
{
    super.onResume();

    Intent i = getIntent();

    if(i != null) 
    {
        Uri uri = i.getData();
        if(uri != null)
        {
            String oauthVerifier = uri.getQueryParameter("oauth_verifier");

            Verifier verifier = new Verifier(oauthVerifier);

            requestToken = new Token(settings.getString("requestToken", null), settings.getString("requestSecret", null));

            Token accessToken = service.getAccessToken(requestToken, verifier);

            // Save the access token.
            SharedPreferences.Editor editor = settings.edit();
            editor.remove("requestToken");
            editor.remove("requestSecret");
            editor.putString("accessToken", accessToken.getToken());
            editor.putString("accessSecret", accessToken.getSecret());
            editor.commit();

            // Start the film list activity.
            final Intent intent = new Intent(this,ProConnect.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(intent);
        }
    }
} 

private void initControls()
{
    home = (Button)findViewById(R.id.home);

    final Intent intent = new Intent(this,ProConnect.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    home.setOnClickListener(new Button.OnClickListener() 
    {
        public void onClick (View v) 
        {
            startActivity(intent);
        }
    });


}

}

and my query class

public class oAuthQuery extends Activity
{
OAuthService service;
Token accessToken;
SharedPreferences settings;

public oAuthQuery()
{
    service= new ServiceBuilder()
    .provider(LinkedInApi.class)
    .apiKey( getString(R.string.apiKey) )
    .apiSecret( getString(R.string.secKey) )
    .callback( getString(R.string.callBack) )
    .build();

    settings = getSharedPreferences("preferences", 0);

    accessToken = new Token(settings.getString("accessToken", null), settings.getString("accessSecret", null));

}

public String query(String s)
{
    OAuthRequest request = new OAuthRequest(Verb.GET, s);
    service.signRequest(accessToken, request);
    Response response = request.send();

    return response.getBody();
}

public OAuthService getService()
{
    return service;
}

}

Thanks for any help Jeff

like image 615
Jeff Finn Avatar asked Aug 02 '11 22:08

Jeff Finn


1 Answers

I solved the problem it was something stupid in the end. I had edited my code to save the access secret and the the access token but had forgotten to re-login when testing my app on my phone. This resulted in the code which saved the parts of the token was not being reached.

I still have a problem using the invite call in the LinkedIn API

invite.setOnClickListener(new Button.OnClickListener() 
        {
            public void onClick (View v) 
            {
                inviteXml = inviteCreator.inviteString(to, subj, body, authName, authValue);
                nameField.setText(inviteXml);
                titleField.setText("");


                call = "http://api.linkedin.com/v1/people/~/mailbox";
                request = new OAuthRequest(Verb.GET, call);
                request.addPayload(inviteXml);
                service.signRequest(accessToken, request);
                response = request.send();

                invite.setVisibility(View.GONE);
            }
        });

I'm not sure if this is the correct way to add the XML string to the call. The LinkedIn API doesn't specify how it is to be added. Has anyone any experience with this?

like image 134
Jeff Finn Avatar answered Sep 21 '22 15:09

Jeff Finn