Using OAuth with Scribe on Android
Asked Answered
D

1

6

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

Durno answered 2/8, 2011 at 22:6 Comment(4)
Hey @jeff think you can paste the logcat output here?Whiting
Thanks for sharing your code, this really helped me along here.Trish
I have a question ... I did almost the same - stored access_token and access_secret to shared preferences... But when I try to make a new call, the app crashes ... Any idea?Thighbone
Is this OOB authentication?Carpentry
D
1

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?

Durno answered 7/8, 2011 at 20:22 Comment(1)
My guess is that you need to change Verb.GET for Verb.POST or Verb.PUTWhiting

© 2022 - 2024 — McMap. All rights reserved.