Accessing Fitbit’s Web API

After learning how to send HTTP requests and receive JSON objects in an Android app,
I started working on getting OAuth authentication and access set up so I can access Withings and Fitbit’s web APIs.

So far I have only been COMPLETELY successful with Fitbit’s API, so I am going to outline how I did it below.

I chose to use a Java library called Scribe, which simplifies OAuth access,
since I was able to find a few tutorials on how to implement it in an Android app.
The library can be found here: https://github.com/fernandezpablo85/scribe-java

Scribe defines API objects that outline important URLs needed for an API’s OAuth authentication process.
The Fitbit API access class I made looks like this:

public class FitbitApi extends DefaultApi10a{
private static final String AUTHORIZE_URL = "https://www.fitbit.com/oauth/authorize?oauth_token=%s";

public String getAccessTokenEndpoint(){
return "https://api.fitbit.com/oauth/access_token";
}
public String getRequestTokenEndpoint(){
return "https://api.fitbit.com/oauth/request_token";
}
public String getAuthorizationUrl(Token requestToken){
return String.format(AUTHORIZE_URL, requestToken.getToken());
}
}

Scribe also uses a service object and serviceBuilder object that contains additional information regarding the API such as:

  • Api Key – A key obtained from the API provider after registering an application
  • API Secret – A value obtained from the API provider after registering an application
  • Callback – A URL that the API will send the user to after they have been authorized

The service for Fitbit looked like:


OAuthService service = new ServiceBuilder()
.provider(FitbitApi.class)
.apiKey("*") //replaced my app key with * for security
.apiSecret("*") //replace my app secret with * for security
.callback(getString(R.string.FitbitCallback)) //arbitary value. I used http://fitbit.com/oauth/callback which isn't a valid address
.debug() //for more verbose messages while testing
.build();

With that complete, all the setup for the Fitbit API is complete.
Now the OAuth requests begin.
The first thing that handles is a request for a Request Token.

final Token requestToken = service.getRequestToken();

With the request token successfully retrieved, the usr is sent to authorize the app by signing into their account with the API provider.


final String authURL = service.getAuthorizationUrl(requestToken);
webview.loadUrl(authURL);

This will load the sign-in page in the web-view i have defined for the Android app.
Once they sign in and choose to allow the app access to their account, they will be sent to the pre-defined callback URL.
I used http://fitbit.com/oauth/callback, but it doesn’t actually matter. This is only used for intercepting the user after the have been authorized.
The webview’s URL loading is modified to execute custom code when the callback URL is the target URL.


public boolean shouldOverrideUrlLoading(WebView view, String url)
{
//check for our custom callback protocol
if(url.startsWith(getString(R.string.FitbitCallback)))
{
//custom code
}
//otherwise use default behavior
return super.shouldOverrideUrlLoading(view, url);
}

The custom code finished the OAuth verification process.
First it gets a verifier value that will be passed from the API as a paramter in the callback URL.


Uri uri = Uri.parse(url);
String verifier = uri.getQueryParameter("oauth_verifier");
Verifier v = new Verifier(verifier);

This verifier can then be used to get an OAuth access token, the final step to getting the app authenticated for API access.


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

The app is now ready to make API calls. As a test, I was able to successfully request my own personal Fitbit profile information like so:


OAuthRequest request = new OAuthRequest(Verb.POST, PROTECTED_RESOURCE_URL);
service.signRequest(accessToken, request);
Response response = request.send();
System.out.println(response.getBody());

The request returned:


{"user":
{
"avatar":"http://www.fitbit.com/images/profile/defaultProfile_100_male.gif",
"avatar150":"http://www.fitbit.com/images/profile/defaultProfile_150_male.gif",
"country":"CA",
"dateOfBirth":"1992-08-29",
"displayName":"Dylan",
"distanceUnit":"en_US",
"encodedId":"27BYDD",
"foodsLocale":"en_US",
"fullName":"Dylan Segna",
"gender":"MALE",
"glucoseUnit":"METRIC",
"height":0,
"heightUnit":"en_US",
"locale":"en_US",
"memberSince":"2013-09-11",
"offsetFromUTCMillis":-14400000,
"strideLengthRunning":0,
"strideLengthWalking":0,
"timezone":"America/New_York",
"waterUnit":"en_US",
"weight":78.7,
"weightUnit":"en_US"
}
}

Advertisements

6 thoughts on “Accessing Fitbit’s Web API

  1. please Could you let me know the “custom code” ?
    if(url.startsWith(getString(R.string.FitbitCallback)))
    {
    //custom code
    }

    I’m having difficulty now on building android app using fitbit api through few weeks.

    • This is what mine looks like:

      if(url.startsWith(R.string.FitbitCallback)))
      {
      //user authorization is completed, and Fitbit has redirected the user to our callback URL
      Uri uri = Uri.parse(url);
      //Get the oauth verifier that Fitbit provides
      String verifier = uri.getQueryParameter(“oauth_verifier”);
      Verifier v = new Verifier(verifier);

      //we have everything we need to get the access token now
      accessToken = service.getAccessToken(requestToken, v);

      //now that we have the access token, lets hide the webview
      webview.setVisibility(View.GONE);
      webview.loadUrl(“about:blank”);
      return true;
      }

      You should now be able to make resource access calls using the access token you have obtained.

      If we need any additional help with this, don’t hesitate to email me at : dylan.segna@senecacollege.ca

  2. above code isn’t working for me.i am getting following exception :
    Exception in thread “main” org.scribe.exceptions.OAuthException: Response body is incorrect. Can’t extract token and secret from this: ‘{“errors”:[{“errorType”:”oauth”,”fieldName”:”oauth_timestamp”,”message”:”oauth_acceptable_timestamps=1437059609-1437060209″}],”success”:false}’
    at org.scribe.extractors.TokenExtractorImpl.extract(TokenExtractorImpl.java:41)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s