To access RunKeeper API, you need to do few things first.
- Create an application in their Application Portal
- Creating application will get you Client ID, Client Secret and URLs to authenticate. If you are unlucky like me and don’t see client secret, go and post a message in their support Google group. They are good at resolving immediately.
Let’s write a simple application that finds out total distance user has walked so far using RunKeeper’s API.
Accessing RunKeeper’s API involves couple of steps,
- Redirect user to RunKeeper’s authorization URL on a WebView.
- Get permission from user to access their data.
- Once they allow it, Run Keeper will redirect with an “Authorization Code”.
- With the Authorization Code make a Post request to get the access token.
- Securely save the access token for reuse. This is long lived key. It works even after users change their password. So keep it safe.
Let’s create a simple Android project with a simple activity that has a Button and WebView.
On button click, hide the Button and bring the WebView to foreground.
Embed client_id, response_type=code, redirect_uri in Authorization URL and load this URL on the WebView control. After user grants/denies permission, it will be redirected to the redirect_uri you have provided. Override shouldOverrideUrlLoading on WebViewClient to you can detect when it is redirected.
After extracting Authorization Code from the redirected URL, get access token by making a POST request. Note few interesting things, You can’t make network requests on UI thread so create a separate thread. This will return a JSON response. Extract access token from the response.
Now we have the access token, let’s go ahead and query RunKeeper’s API.To keep it simple for this example, I just hard coded the URL. But you should query “user”[https://api.runkeeper.com/user/] endpoint to get list of URLs available for you. If we query http://api.runkeeper.com/records endpoint it returns list of statistics for each activity type available in RunKeeper.
Note that we didn’t create a separate thread for this call since this method gets called in a non UI thread we created earlier. If you are calling this method from UI thread, create a separate thread.
After getting response from “records” endpoint, we have to traverse it to the walking activity type and extract overall walking distance. Parsing JSON with out dedicated parser like Gson is a real mess. To keep the example simple and friction less, I just used built in JSONObject.
RunKeeper returns total distance in meters and convert it to miles and display it on a Toast message. Note we are not on UI thread, we have to call runOnUiThread to display the Toast message. Some less interesting helper methods,
One last important thing, add android.permission.INTERNET to AndroidManifest.xml file so that our app can access internet.