I'm trying to implement the Tumblr API in an Android app. I'm really getting stuck with authorizing a user so that they can do things such as post and view their dashboard. I don't really understand oAuth, and the Tumblr API documentation sort of skips right over it. I have no idea if I'm supposed to prompt the user for their credentials, or what to do with those once I have them, or anything like that. I added the Signpost library to my project, but I've been scratching my head since then. Anybody familiar with oAuth on Android who would care to fill me in? Thanks!
Yes, the documentation is not that good. You should first read about OAuth. Twitter has a good overview.
First of all you need a consumer key and secret (you can get those by registering your app in tumblr). After that, you should use the auth URLs that Tumblr provides to get the authorization from the user. Usually you will generate a request URL, from which you can take the user to the browser where he/she will login and authorize your app. This will trigger a callback to your app, and you will be able to get the oAuth token. Save this in your app (SharedPreferences) so that you won't need to ask the user again to authenticate. With this token you will be able to interact with Tumblr's API that requires authentication.
Note that you could also implement a webview instead of making the user use the browser. Though, this requires a bit more of work.
I have found that the latest signpost library does not work well with Tumblr. You will need a bit older version. Head here and download these files:
Import both libraries to your project. To use them, basically you need to call the following code:
CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY,
CONSUMER_SECRET);
CommonsHttpOAuthProvider provider = new CommonsHttpOAuthProvider(
REQUEST_TOKEN_URL,
ACCESS_TOKEN_URL,
AUTH_URL);
String authUrl = provider.retrieveRequestToken(consumer, CALLBACK_URL);
CALLBACK_URL could be something like this: "tumblrapp://tumblrapp.com/ok". There is no need to set the callback URL on the Tumblr settings.
Also, you will need to set an intent filter so your app gets called after authorization. Make sure that your Manifest looks like this:
<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="tumblrapp"/>
</intent-filter>
Now after authentication you can get the token like this:
Uri uri = this.getIntent().getData();
if (uri != null) {
String token = uri.getQueryParameter("oauth_token");
}
I made a quick sample app. You can check it out here. You might want to move the request to a background thread as it will block the UI.
Just so new people coming in have an easier way to implement this, There's an Android Library on GitHub to login the user for you. It returns the Tokens so you may use them with Jumblr Library.
Edit 1:
On Recommendation of Bhargav Rao & tttony, below is an elaboration of the login process for Tumblr. Though I recommend using the library as it takes care of the messy part, for those who like getting their hands dirty...
The Tumblr Login is a 3 staged process. For info on what OAuth is, refer this simplified guide
1) Using httpOAuthprovider in the signpost library, generate a request token.
//Generate a new oAuthConsumer object
commonsHttpOAuthConsumer
= new CommonsHttpOAuthConsumer(
"Consumer Key",
"Consumer Secret Key");
//Generate a new oAuthProvider object
commonsHttpOAuthProvider
= new CommonsHttpOAuthProvider(
"https://www.tumblr.com/oauth/request_token",
"https://www.tumblr.com/oauth/access_token",
"https://www.tumblr.com/oauth/authorize");
//Retrieve the URL to which the user must be sent in order to authorize the consumer
return commonsHttpOAuthProvider.retrieveRequestToken(
commonsHttpOAuthConsumer,
"Callback URL as registered with Tumblr"
);
2) The response of the previous return statement is a URL which the user should be redirected to for him to login to Tumblr and authorize your app. I did this in a webview for better control of app flow. Refer this for info on how to load content to WebViews. Attach a WebView client and override the shouldOverrideUrlLoading
method. This will enable you to intercept URLs before they are loaded. Post Authorization, tumblr issues an OAuthVerifier
which will be used to exchange for Tokens.
public boolean shouldOverrideUrlLoading(WebView view, String strUrl) {
//Log Current loading URL
Log.i(TAG, strUrl);
//Check if the Currently loading URL is that of the call back URL mentioned on top
if (strUrl.toLowerCase().contains("Callback URL".toLowerCase())) {
//Parse string URL to conver to URI
Uri uri = Uri.parse(strUrl);
//instantiate String variables to store OAuth & Verifier tokens
String strOAuthToken = "";
String strOAuthVerifier = "";
//Iterate through Parameters retrieved on the URL
for (String strQuery : uri.getQueryParameterNames())
switch (strQuery) {
case "oauth_token":
//Save OAuth Token
//Note : This is not the login token we require to set on JumblrToken
strOAuthToken = uri.getQueryParameter(strQuery);
break;
case "oauth_verifier":
//Save OAuthVerifier
strOAuthVerifier = uri.getQueryParameter(strQuery);
break;
}
}
3) Exchange the OAuthVerifier
for access tokens.
try {
//Queries the service provider for access tokens. The method does not return anything.
//It stores the OAuthToken & OAuthToken secret in the commonsHttpOAuthConsumer object.
commonsHttpOAuthProvider.retrieveAccessToken(commonsHttpOAuthConsumer, strOAuthVerifier);
//Check if tokens were received. If Yes, save them to SharedPreferences for later use.
if(!TextUtils.isEmpty(commonsHttpOAuthConsumer.getToken())) {
Log.i(TAG, "OAuthToken : " + commonsHttpOAuthConsumer.getToken());
}
if(!TextUtils.isEmpty(commonsHttpOAuthConsumer.getTokenSecret())) {
Log.i(TAG, "OAuthSecretToken : " + commonsHttpOAuthConsumer.getTokenSecret());
}
} catch (OAuthCommunicationException e) {
e.printStackTrace();
return null;
} catch (OAuthExpectationFailedException e) {
e.printStackTrace();
return null;
} catch (OAuthNotAuthorizedException e) {
e.printStackTrace();
return null;
} catch (OAuthMessageSignerException e) {
e.printStackTrace();
return null;
}
4) Once Token and TokenSecret are retrieved, use them with Jumblr to continue using TumblrAPIs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With