OAuth in Android

Here's a simple example that uses OAuth to authorize your app with Twitter. I use Jamba-modified JTwitter library here. The source code is included, but you must get your own OAuth key from Twitter by going to https://dev.twitter.com/apps/new.

You should enter something like this when registering your app:




MainActivity.java

Note that I use SignPost and JTwitter libraries with this code (provided in source). Also, the key to this code is the callback from the browser back to the app. You need to see the Manifest file down below to get the whole picture.

Code:

package com.marakana.oauth;

import oauth.signpost.OAuth;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.OAuthProvider;
import oauth.signpost.basic.DefaultOAuthProvider;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
import oauth.signpost.exception.OAuthNotAuthorizedException;
import winterwell.jtwitter.OAuthSignpostClient;
import winterwell.jtwitter.Twitter;
import winterwell.jtwitter.TwitterException;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
private static final String TAG = "OAuthDemo";
private static final String OAUTH_KEY = "YOUR_KEY_GOES_HERE";
private static final String OAUTH_SECRET = "YOUR_SECRET_GOES_HERE";
private static final String OAUTH_CALLBACK_SCHEME = "x-marakana-oauth-twitter";
private static final String OAUTH_CALLBACK_URL = OAUTH_CALLBACK_SCHEME
+ "://callback";
private static final String TWITTER_USER = "YOUR_EMAIL_GOES_HERE";

private OAuthSignpostClient oauthClient;
private OAuthConsumer mConsumer;
private OAuthProvider mProvider;
private Twitter twitter;
SharedPreferences prefs;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// mConsumer = new DefaultOAuthConsumer(OAUTH_KEY, OAUTH_SECRET);
mConsumer = new CommonsHttpOAuthConsumer(OAUTH_KEY, OAUTH_SECRET);
mProvider = new DefaultOAuthProvider(
"https://api.twitter.com/oauth/request_token",
"https://api.twitter.com/oauth/access_token",
"https://api.twitter.com/oauth/authorize");

// Read the prefs to see if we have token
prefs = PreferenceManager.getDefaultSharedPreferences(this);
String token = prefs.getString("token", null);
String tokenSecret = prefs.getString("tokenSecret", null);
if (token != null && tokenSecret != null) {
// We have token, use it
mConsumer.setTokenWithSecret(token, tokenSecret);
// Make a Twitter object
oauthClient = new OAuthSignpostClient(OAUTH_KEY, OAUTH_SECRET, token,
tokenSecret);
twitter = new Twitter(TWITTER_USER, oauthClient);
}
}

/* Callback once we are done with the authorization of this app with Twitter. */
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
Log.d(TAG, "intent: " + intent);

// Check if this is a callback from OAuth
Uri uri = intent.getData();
if (uri != null && uri.getScheme().equals(OAUTH_CALLBACK_SCHEME)) {
Log.d(TAG, "callback: " + uri.getPath());

String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
Log.d(TAG, "verifier: " + verifier);

new RetrieveAccessTokenTask().execute(verifier);
}

}

public void onClickAuthorize(View view) {
new OAuthAuthorizeTask().execute();
}

public void onClickTweet(View view) {
if (twitter == null) {
Toast.makeText(this, "Authenticate first", Toast.LENGTH_LONG).show();
return;
}

EditText status = (EditText) findViewById(R.id.status);
new PostStatusTask().execute(status.getText().toString());
}

public void onClickGetStatus(View view) {
if (twitter == null) {
Toast.makeText(this, "Authenticate first", Toast.LENGTH_LONG).show();
return;
}
new GetStatusTask().execute();
}

/* Responsible for starting the Twitter authorization */
class OAuthAuthorizeTask extends AsyncTask<Void, Void, String> {

@Override
protected String doInBackground(Void... params) {
String authUrl;
String message = null;
try {
authUrl = mProvider.retrieveRequestToken(mConsumer, OAUTH_CALLBACK_URL);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl));
startActivity(intent);
} catch (OAuthMessageSignerException e) {
message = "OAuthMessageSignerException";
e.printStackTrace();
} catch (OAuthNotAuthorizedException e) {
message = "OAuthNotAuthorizedException";
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
message = "OAuthExpectationFailedException";
e.printStackTrace();
} catch (OAuthCommunicationException e) {
message = "OAuthCommunicationException";
e.printStackTrace();
}
return message;
}

@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result != null) {
Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
}
}
}

/* Responsible for retrieving access tokens from twitter */
class RetrieveAccessTokenTask extends AsyncTask<String, Void, String> {

@Override
protected String doInBackground(String... params) {
String message = null;
String verifier = params[0];
try {
// Get the token
Log.d(TAG, "mConsumer: " + mConsumer);
Log.d(TAG, "mProvider: " + mProvider);
mProvider.retrieveAccessToken(mConsumer, verifier);
String token = mConsumer.getToken();
String tokenSecret = mConsumer.getTokenSecret();
mConsumer.setTokenWithSecret(token, tokenSecret);

Log.d(TAG, String.format("verifier: %s, token: %s, tokenSecret: %s",
verifier, token, tokenSecret));

// Store token in prefs
prefs.edit().putString("token", token).putString("tokenSecret",
tokenSecret).commit();

// Make a Twitter object
oauthClient = new OAuthSignpostClient(OAUTH_KEY, OAUTH_SECRET, token,
tokenSecret);
twitter = new Twitter("MarkoGargenta", oauthClient);

Log.d(TAG, "token: " + token);
} catch (OAuthMessageSignerException e) {
message = "OAuthMessageSignerException";
e.printStackTrace();
} catch (OAuthNotAuthorizedException e) {
message = "OAuthNotAuthorizedException";
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
message = "OAuthExpectationFailedException";
e.printStackTrace();
} catch (OAuthCommunicationException e) {
message = "OAuthCommunicationException";
e.printStackTrace();
}
return message;
}

@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result != null) {
Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
}
}
}

/* Responsible for getting Twitter status */
class GetStatusTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
return twitter.getStatus().text;
}

@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
}
}

/* Responsible for posting new status to Twitter */
class PostStatusTask extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
try {
twitter.setStatus(params[0]);
return "Successfully posted: " + params[0];
} catch (TwitterException e) {
return "Error connecting to server.";
}
}

@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
}

}
}

AndroidManifest.xml

The key here is the intent filter that serves as a callback to our main activity to complete the authentication process.

Code:

<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.marakana.oauth"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="11" />
<uses-permission
android:name="android.permission.INTERNET" />


<application
android:icon="@drawable/icon"
android:label="@string/app_name">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleInstance">
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>

<!-- Used for OAuth callback -->
<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="x-marakana-oauth-twitter"
android:host="callback" />
</intent-filter>

</activity>

</application>
</manifest>

main.xml Layout

Nothing special here, just basic UI stuff.

Code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="50sp"
android:gravity="center" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Authenticate"
android:onClick="onClickAuthorize"
android:textSize="40sp"></Button>
<EditText
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="@+id/status"
android:textSize="40sp"
android:hint="What's up?"></EditText>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tweet"
android:onClick="onClickTweet"
android:textSize="40sp"></Button>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Status"
android:textSize="40sp"
android:onClick="onClickGetStatus"></Button>

</LinearLayout>

Source code is here:
https://github.com/marakana/OAuthDemo

Copyright © 2018 ProTech. All Rights Reserved.

Sign In Create Account

Navigation

Social Media