Paul Brower bio photo

Paul Brower

Android development for fun and profit.

Email Twitter Github Stackoverflow Codementor

Find further code and implementation here: https://github.com/browep/Android-OAuth-Twitter-Example

This tutorial will show you how to authorize your Android app to update someone’s Twitter status through the Twitter OAuth API. Once setup, the app will pop-up a WebView that the user will log into, authorize your app, and then app will tweet using that twitter account.

This app uses the library created by sugree. Credit should be given to him for the OAuth authorization steps. I made a few modifications to that library to work with this example so you should probably use the java files from https://github.com/browep/Android-OAuth-Twitter-Example instead of https://github.com/sugree/twitter-android-sdk

First we register an app with twitter to get OAuth keys. Goto https://dev.twitter.com/apps . Click “Create a new application”

Fill in the textboxes for names and descriptions. It doesn’t matter what you put for Callback URL, it just needs to be a valid URL. I used “http://github.com”

Once the application is created, go to the Settings tab on the application’s page. Scroll down to the Application Type section and make sure that the option for Read and Write is selected.

Let’s start with the AndroidManifest.xml . We need to use the INTERNET service so let’s add the permission:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.github.browep.oauthtwitter"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET"/>

<application android:label="@string/app_name" >
<activity android:name="Main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>
</manifest>

We then need get the Twitter OAuth library from https://github.com/sugree/twitter-android-sdk. The https://github.com/browep/Android-OAuth-Twitter-Example example project has them copied to the source tree but it can also be included as a library project which is outside the scope of this project. If you copy the files into your own project don’t forget to include the the two signpost jars in the “libs” directory as they are needed for the twitter integration. The https://github.com/browep/Android-OAuth-Twitter-Example project already has everything imported, I suggest you start there.

Once we have all the files in our source tree we can start integrating into the app. I am going to use just one activity for this. It will open a WebView dialog in the onCreate method:

twitter screen

public class Main extends Activity
{
  public static final String TAG =  Main.class.getSimpleName();
  public static final String TWITTER_OAUTH_REQUEST_TOKEN_ENDPOINT = "http://twitter.com/oauth/request_token";
  public static final String TWITTER_OAUTH_ACCESS_TOKEN_ENDPOINT = "http://twitter.com/oauth/access_token";
  public static final String TWITTER_OAUTH_AUTHORIZE_ENDPOINT = "http://twitter.com/oauth/authorize";
  private CommonsHttpOAuthProvider commonsHttpOAuthProvider;
  private CommonsHttpOAuthConsumer commonsHttpOAuthConsumer;

  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    commonsHttpOAuthProvider = new CommonsHttpOAuthProvider(TWITTER_OAUTH_REQUEST_TOKEN_ENDPOINT,
      TWITTER_OAUTH_ACCESS_TOKEN_ENDPOINT, TWITTER_OAUTH_AUTHORIZE_ENDPOINT);
      commonsHttpOAuthConsumer = new CommonsHttpOAuthConsumer(getString(R.string.twitter_oauth_consumer_key),
      getString(R.string.twitter_oauth_consumer_secret));
      commonsHttpOAuthProvider.setOAuth10a(true);
      TwDialog dialog = new TwDialog(this, commonsHttpOAuthProvider, commonsHttpOAuthConsumer,
        dialogListener, R.drawable.android);
        dialog.show();

      }

After creating the consumer/producer, we pass them to the TwDialog constructor along with a Twitter.DialogListener object that will handle success and error conditions.

Behind the scenes

This section is not necessary to complete the tutorial as it only explains what the TwDialog is doing. The TwDialog is a android.app.Dialog object that will display over the activity. It’s going to fill that dialog with a WebView that loads the request URL provided by the OAuth request call. To get a more in depth look at how OAuth works see here. This URL will prompt the user to enter their credentials or cancel. The WebView will then be redirected to a callback success URL. This is where the WebView overrides the URL loading process, in the shouldOverrideUrLoading function. This parses the success URL which contains the requisite keys and dismisses the Dialog containing the WebView. It then passes those keys to the Twitter.DialogListener that we declared. End Behind the Scenes.

The Twitter.DialogListener class is simple and in this example I have only really implemented the onComplete method.

private Twitter.DialogListener dialogListener = new Twitter.DialogListener() {
  public void onComplete(Bundle values) {
    String secretToken = values.getString("secret_token");
    Log.i(TAG,"secret_token=" + secretToken);
    String accessToken = values.getString("access_token");
    Log.i(TAG,"access_token=" + accessToken);
    new Tweeter(accessToken,secretToken).tweet(
      "Tweet from sample Android OAuth app.  unique code: " + System.currentTimeMillis());
    }

    public void onTwitterError(TwitterError e) { Log.e(TAG,"onTwitterError called for TwitterDialog",
    new Exception(e)); }

    public void onError(DialogError e) { Log.e(TAG,"onError called for TwitterDialog", new Exception(e)); }

    public void onCancel() { Log.e(TAG,"onCancel"); }
  };

The onComplete method will be called when the app has been authorized by the user and will return us the secret token and the access token that we will use to make OAuth calls.

You can see in the onComplete method that we then create a Tweeter object which will handle the tweeting logic.

public class Tweeter {
  protected CommonsHttpOAuthConsumer oAuthConsumer;

  public Tweeter(String accessToken, String secretToken) {
    oAuthConsumer = new CommonsHttpOAuthConsumer(getString(R.string.twitter_oauth_consumer_key),
    getString(R.string.twitter_oauth_consumer_secret));
    oAuthConsumer.setTokenWithSecret(accessToken, secretToken);
  }

  public boolean tweet(String message) {
    if (message == null && message.length() > 140) {
      throw new IllegalArgumentException("message cannot be null and must be less than 140 chars");
    }
    // create a request that requires authentication

    try {
      HttpClient httpClient = new DefaultHttpClient();
      Uri.Builder builder = new Uri.Builder();
      builder.appendPath("statuses").appendPath("update.json")
      .appendQueryParameter("status", message);
      Uri man = builder.build();
      HttpPost post = new HttpPost("http://twitter.com" + man.toString());
      oAuthConsumer.sign(post);
      HttpResponse resp = httpClient.execute(post);
      String jsonResponseStr = convertStreamToString(resp.getEntity().getContent());
      Log.i(TAG,"response: " + jsonResponseStr);
      String id = getFirstMatch(ID_PATTERN,jsonResponseStr);
      Log.i(TAG,"id: " + id);
      String screenName = getFirstMatch(SCREEN_NAME_PATTERN,jsonResponseStr);
      Log.i(TAG,"screen name: " + screenName);

      final String url = MessageFormat.format("https://twitter.com/#!/{0}/status/{1}",screenName,id);
      Log.i(TAG,"url: " + url);

      Runnable runnable = new Runnable() {
        public void run() {
          ((TextView)Main.this.findViewById(R.id.textView)).setText("Tweeted: " + url);
        }
      };

      Main.this.runOnUiThread(runnable);

      return resp.getStatusLine().getStatusCode() == 200;

      } catch (Exception e) {
        Log.e(TAG,"trying to tweet: " + message, e);
        return false;
      }

    }
  }

This creates a POST request to http://twitter.com/statuses/update.json with the HttpPost class provided by Android. It then uses the signpost library to sign it and then executes the request and returns the link to the newly created status to a TextView on the screen.

image

To continue tweeting you need to persist those keys from the onComplete function, preferably using SharedPreferences.

Further documentation on what you can do with the Twitter API can be found here: https://dev.twitter.com/docs/api