Consuming Twitter API 1.1 with Application-Only Auth in Android

Preamble

Recently twitter turned off API 1.0 requiring applications to move to 1.1 and begin using OAuth for all API calls. For those of us who simply wanted to display a user’s timeline in our app, that means things just got a little more complicated.

There are essentially three ways to authenticate with Twitter

  1. Standard OAuth is what you’ll need to use if you want your users to be able to sign in with their own twitter credentials.
  2. Single user mode is great if you are the only person using your application. For instance if your washing machine tweets updates. It’s much simpler to setup than Standard OAuth, but all actions will be performed in the context of the single user you specify in the code. (more info here)
  3. Application Only is a little different in that instead of authenticating a user, you authenticate the application. Again, this type of authentication is a little easier to setup, but it comes with the limitation that you cannot perform any actions in the context of a user.

For my application I only needed to display the timelines from a handful of users. Since searching/reading tweets is public information I can use Application Only authentication. This process is documented already here, but this post will supplement some Android-specific code.

Prerequisites

The first thing you will need to do is sign into https://dev.twitter.com. Go to the “My Applications” section and create a new application for yourself.  Twitter will assign you a Consumer Key and a Consumer Secret.

Getting Down to Business

We need to obtain a “bearer token” which will serve as the login credentials for our application. To obtain the bearer token we submit a specially formatted request to twitter. The request should look like this (without the line break on the Authorization line):

POST /oaut/token HTTP/1.1
Host: api.twitter.com
User-Agent: My Twitter App v1.0.23
Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEJvZzpMOHFxOVBaeVJnNmllS0dFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==

Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 29
Accept-Encoding: gzip

grant_type=client_credentials

We construct this request in Android as follows:

DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httppost = new HttpPost("https://api.twitter.com/oaut/token");

final String APIKEY = "<Your Consumer Key>";
final String APISECRET = "<Your Consumer Secret>";

String apiString = APIKEY + ":" + APISECRET;
String authorization = "Basic " + Base64.encodeToString(apiString.getBytes(), Base64.NO_WRAP);

httppost.setHeader("Authorization", authorization);
httppost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
httppost.setEntity(new StringEntity("grant_type=client_credentials"));

InputStream inputStream = null;
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();

inputStream = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();

String line = null;
while ((line = reader.readLine()) != null)
{
    sb.append(line + "n");
}

The StringBuilder sb will now contain a JSON formatted response containing your bearer token. It will look something like this

{“token_type”:”bearer”,”access_token”:”AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA”}

We will include the bearer token in every call we make to the API. It acts as our authentication. Before we jump into using the bearer token there are some things you should know about it.

  • It uniquely identifies your application to twitter. Do not post it publicly.
  • It can be revoked by twitter. If this happens, you will need to generate a new token using the process above.
  • It can be revoked by you. You would want to do this if someone else obtained the token and was using it without your permission

So while theoretically you could hard code the bearer token into your app, it’s better to save it to your application’s database or as a preference. If the token is revoked, your application should run the code above to get a new token.

Making the Call

Calling the API with the bearer token is very similar to what we did before. We simply add the bearer token as a header in the HTTP request like this

GET /1.1/statuses/user_timeline.json?count=100&screen_name=twitterapi
HTTP/1.1 Host: api.twitter.com User-Agent: My Twitter App v1.0.23
Authorization: Bearer AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Accept-Encoding: gzip

Which is created by the following Android code. The variable url specifies the API you are attempting to access. For instance https://api.twitter.com/1.1/statuses/user_timeline.json?count=100&screen_name=twitterapi

DefaultHttpClient httpclient = new DefaultHttpClient(new BasicHttpParams());
HttpGet httpget = new HttpGet(url);
httpget.setHeader("Authorization", "Bearer AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAAAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
httpget.setHeader("Content-type", "application/json");

InputStream inputStream = null;
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();

inputStream = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();

String line = null;
while ((line = reader.readLine()) != null)
{
 sb.append(line + "n");
}

Once again, the StringBuilder sb will contain the JSON encoded response from the API.

 

Here is an example eclipse project. Simply provide your API Key and API Secret in MainActivity.java.

TwitterApiExample

17 thoughts on “Consuming Twitter API 1.1 with Application-Only Auth in Android

  1. Defuera

    Would you please post a sourse code for this app it woud be much easier than to ask all the parts I didn’t get. Thank you!

    • heathbar

      I have attached an example project at the bottom of the post.

  2. defuera

    Not working for me. sb returns : {“errors”:[{“message”:”Bad Authentication data”,”code”:215}]}. Any ideas what Am I doing wrong?

    • heathbar

      That means twitter could not authenticate you because you did not supply the correct information.
      1. Are you trying to use the tokens I provided in this post? They will not work, you need to provide your own.

  3. Manthan Shah

    You have sorted my life dude!!
    I had been searching for this thing since 24 hrs..Thanks a ton!!!!!

  4. Manthan Shah

    InputStream inputStream = null;
    HttpResponse response = httpclient.execute(httpget);
    HttpEntity entity = response.getEntity();

    from where did httpget come from..is that a typing error and shouldn’t it be httppost..
    P.S. in the method that retrieves the bearer token.

    • heathbar

      Yes, fixed.

  5. Defuera

    Thx a lot! Everything working now. Appreciate your post-)

  6. Hello I put the API key and API secret of my application, run the application, and clicking on “get Bearer Token” gave me a string like “AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2FAAAAA….” but clicking on “Get Feed” returns nothing. Please help!

    • After reseting consumer key and consumer token, it’s finally working!

  7. wiralim

    Thankkkkkkk yyyyyoooouuuuuuuuu!!!!!!!!!!
    It really help me.

  8. Rafael Vieira

    Thank you so much man!!!!

  9. bijin

    Thank you for the post. working perfetly

    Any one know how to impliment this in ios

  10. I realize that it has been months since someone has replied to this, but it was so helpful that I wanted to make so that I let you know. Thanks for spelling things out so well and supplying code. I’ve seen a number of posts that give details, but all of them leave out important information. Yours covered everything perfectly!

  11. anbarasu

    Thanks a lot,Thanks thanks

  12. Yellen Seram

    Hi,

    This is a superb post. Made my life easier. 😀

    However, it failed to fetch the statuses if I change the screen_name from twitterapi to some other screen name. Anything that I’m missing?

    Thanks,
    Yellen

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>